首页 文章

如何调试Google Apps脚本(又名Logger.log登录到哪里?)

提问于
浏览
88

在Google表格中,您可以添加一些脚本功能 . 我正在为 onEdit 事件添加一些东西,但我可以't tell if it'正在工作 . 据我所知,你无法从Google表格中调试直播事件,因此你必须从调试器中进行调试,这是没有意义的,因为传递给我的 onEdit() 函数的事件参数将始终是未定义的,如果我从 Script Editor .

因此,每当调用 onEdit 函数时,我都试图使用 Logger.log 方法记录一些数据,但这似乎只有在从 Script Editor 运行时才有效 . 当我从 Script Editor 运行它时,我可以通过转到 View->Logs... 查看日志

我希望能够从事件实际执行时看到日志,但我无法弄明白 .

我该如何调试这些东西?

10 回答

  • 29

    开发控制台将记录应用程序脚本引发的错误,因此您只需抛出错误即可将其记录为正常的console.log . 它将停止执行,但它可能仍然有用于逐步调试 .

    throw Error('hello world!');
    

    将显示在控制台中与 console.log('hello world') 类似

  • 1

    2017 Update: Stackdriver Logging现在可用于Google Apps脚本 . 从脚本编辑器的菜单栏中,转到: View > Stackdriver Logging 以查看或流式传输日志 .

    console.log()将写入 DEBUG 级别的消息

    示例 onEdit() 日志记录:

    function onEdit (e) {
      var debug_e = {
        authMode:  e.authMode,  
        range:  e.range.getA1Notation(),    
        source:  e.source.getId(),
        user:  e.user,   
        value:  e.value,
        oldValue: e. oldValue
      }
    
      console.log({message: 'onEdit() Event Object', eventObject: debug_e});
    }
    

    然后检查标记为 onEdit() Event ObjectStackdriver UI中的日志以查看输出

  • 3

    我遇到了同样的问题,我在网上找到了以下内容....

    Docs中的事件处理程序虽然有点棘手 . 由于文档可以处理多个用户的多个同时编辑,因此事件处理程序在服务器端处理 . 此结构的主要问题是,当事件触发器脚本失败时,它在服务器上失败 . 如果您想查看调试信息,您需要在触发器菜单下设置显式触发器,当事件失败时通过电子邮件向您发送调试信息,否则它将无声地失败 .

  • 4

    就像一个通知 . 我为我的电子表格做了一个测试功能 . 我在onEdit(e)函数中使用变量google throws(我称之为e) . 然后我做了一个这样的测试函数:

    function test(){
    var testRange = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(GetItemInfoSheetName).getRange(2,7)
    var testObject = {
        range:testRange,
        value:"someValue"
    }
    onEdit(testObject)
    SpreadsheetApp.getActiveSpreadsheet().getSheetByName(GetItemInfoSheetName).getRange(2,6).setValue(Logger.getLog())
    }
    

    调用此测试函数会使所有代码按照电子表格中的事件运行 . 我只是把我编辑过的单元格放在了whitch给了我一个意想不到的结果,将值设置为我放入单元格的值 . OBS!更多变量googles赋予函数go here:https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events

  • 0

    目前,您仅限于在文档中使用脚本的容器绑定性质 . 如果您在docs之外创建一个新脚本,那么您将能够将信息导出到Google电子表格并将其用作日志记录工具 .

    例如,在您的第一个代码块中

    function setCheckboxes() {
    
        // Add your spreadsheet data
        var errorSheet = SpreadsheetApp.openById('EnterSpreadSheetIDHere').getSheetByName('EnterSheetNameHere');
        var cell = errorSheet.getRange('A1').offset(errorSheet.getLastRow(),0);
    
        // existing code
        var checklist = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("checklist");
        var checklist_data_range = checklist.getDataRange();
        var checklist_num_rows = checklist_data_range.getNumRows();
    
        // existing logger
        Logger.log("checklist num rows: " + checklist_num_rows);
    
       //We can pass the information to the sheet using cell.setValue()
        cell.setValue(new Date() + "Checklist num rows: " + checklist_num_rows);
    

    当我使用GAS时,我有两台显示器(你可以使用两个窗口)设置一个包含GAS环境,另一个包含SS,所以我可以写信息并记录 .

  • 5

    如果您打开了脚本编辑器,您将在View-> Logs下看到日志 . 如果您的脚本具有onedit触发器,请更改电子表格,该电子表格应在第二个选项卡中打开脚本编辑器时触发该功能 . 然后转到脚本编辑器选项卡并打开日志 . 您将看到您的函数传递给 Logger 的任何内容 .

    基本上只要脚本编辑器打开,事件就会写入日志并为您显示 . 它不会显示其他人是否在其他人的文件中 .

  • 0

    有点hacky,但我创建了一个名为"console"的数组,任何时候我想输出到控制台我推送到数组 . 然后,每当我想看到实际的输出时,我只是返回 console 而不是之前返回的任何内容 .

    //return 'console' //uncomment to output console
        return "actual output";
    }
    
  • 0

    据我所知,你不能从谷歌文档调试实时事件,所以你必须从调试器做,这是没有意义的,因为传递给我的onEdit()函数的事件参数将始终是未定义的,如果我从脚本编辑器运行它 .

    是 - 所以自己定义事件参数以进行调试 . 见How can I test a trigger function in GAS?

    我试图使用Logger.log方法在调用onEdit函数时记录一些数据,但这似乎只有在从脚本编辑器运行时才有效 . 当我从脚本编辑器运行它时,我可以通过转到View-> Logs查看日志...

    再说实话,但有帮助 . Peter Hermann的BetterLog library将所有日志重定向到电子表格,甚至可以从未附加到编辑器/调试器实例的代码启用日志记录 .

    例如,如果您在包含电子表格的脚本中进行编码,则只需将这一行添加到脚本文件的顶部,所有日志都将转到电子表格中的"Logs"表 . 没有其他必要的代码,只需像通常那样使用 Logger.log()

    Logger = BetterLog.useSpreadsheet();
    
  • 7

    UPDATE:

    正如在_519061中回答的那样,


    Logger.log 将向您发送(最终)您的脚本中发生的错误的电子邮件,或者,如果您正在运行 Script Editor 中的内容,您可以通过转到 View->Logs (仍在脚本编辑器中)查看上次运行函数的日志 . 同样,这只会显示从您运行的最后一个函数 from inside Script Editor 中记录的任何内容 .

    我试图开始工作的脚本与电子表格有关 - 我制作了一个电子表格todo-checklist类型的东西,按优先级等排序项目 .

    我为该脚本安装的唯一触发器是onOpen和onEdit触发器 . 调试onEdit触发器是最难解决的问题,因为我一直在想,如果我在onEdit函数中设置断点,打开电子表格,编辑一个单元格,我的断点就会被触发 . 不是这种情况 .

    为了模拟编辑一个单元格,我最终不得不在实际的电子表格中做一些事情 . 我所做的就是确保选择了我希望它作为"edited"处理的单元格,然后在 Script Editor 中,我会去 Run->onEdit . 然后我的断点就会被击中 .

    但是,我确实必须停止使用传递给onEdit函数的事件参数 - 你无法通过执行 Run->onEdit 来模拟它 . 我需要从电子表格中获得的任何信息,例如选择了哪个单元格等,我必须手动弄清楚 .

    无论如何,答案很长,但我最终想通了 .


    EDIT

    如果你想看到我做的待办事项清单,你可以check it out here

    (是的,我知道任何人都可以编辑它 - 这是分享它的重点!)

    我希望它能让你看到剧本 . 既然你在那里看不到它,这里是:

    function onOpen() {
      setCheckboxes();
    };
    
    function setCheckboxes() {
      var checklist = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("checklist");
      var checklist_data_range = checklist.getDataRange();
      var checklist_num_rows = checklist_data_range.getNumRows();
      Logger.log("checklist num rows: " + checklist_num_rows);
    
      var coredata = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("core_data");
      var coredata_data_range = coredata.getDataRange();
    
      for(var i = 0 ; i < checklist_num_rows-1; i++) {
        var split = checklist_data_range.getCell(i+2, 3).getValue().split(" || ");
        var item_id = split[split.length - 1];
        if(item_id != "") {
          item_id = parseInt(item_id);
          Logger.log("setting value at ("+(i+2)+",2) to " + coredata_data_range.getCell(item_id+1, 3).getValue());
          checklist_data_range.getCell(i+2,2).setValue(coredata_data_range.getCell(item_id+1, 3).getValue());
        }
      }
    }
    
    function onEdit() {
      Logger.log("TESTING TESTING ON EDIT");
      var active_sheet = SpreadsheetApp.getActiveSheet();
      if(active_sheet.getName() == "checklist") {
        var active_range = SpreadsheetApp.getActiveSheet().getActiveRange();
        Logger.log("active_range: " + active_range);
        Logger.log("active range col: " + active_range.getColumn() + "active range row: " + active_range.getRow());
        Logger.log("active_range.value: " + active_range.getCell(1, 1).getValue());
        Logger.log("active_range. colidx: " + active_range.getColumnIndex());
        if(active_range.getCell(1,1).getValue() == "?" || active_range.getCell(1,1).getValue() == "?") {
          Logger.log("made it!");
          var next_cell = active_sheet.getRange(active_range.getRow(), active_range.getColumn()+1, 1, 1).getCell(1,1);
          var val = next_cell.getValue();
          Logger.log("val: " + val);
          var splits = val.split(" || ");
          var item_id = splits[splits.length-1];
          Logger.log("item_id: " + item_id);
    
          var core_data = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("core_data");
          var sheet_data_range = core_data.getDataRange();
          var num_rows = sheet_data_range.getNumRows();
          var sheet_values = sheet_data_range.getValues();
          Logger.log("num_rows: " + num_rows);
    
          for(var i = 0; i < num_rows; i++) {
            Logger.log("sheet_values[" + (i) + "][" + (8) + "] = " + sheet_values[i][8]);
            if(sheet_values[i][8] == item_id) {
              Logger.log("found it! tyring to set it...");
              sheet_data_range.getCell(i+1, 2+1).setValue(active_range.getCell(1,1).getValue());
            }
          }
    
        }
      }
    
      setCheckboxes();
    };
    
  • 59

    它远非优雅,但在调试时,我经常登录到Logger,然后使用getLog()来获取其内容 . 然后,我要么:

    • 将结果保存到变量(可以在Google Scripts调试器中检查 - 这适用于我无法在某些代码中设置断点的情况,但我可以在稍后执行的代码中设置一个)

    • 将其写入一些临时DOM元素

    • 将其显示在alert

    从本质上讲,它只是一个JavaScript output问题 .

    它完全缺乏现代 console.log() 实现的功能,但Logger仍然有助于调试Google Scripts .

相关问题