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

时间:2012-07-18 10:35:42

标签: google-apps-script google-sheets

在Google表格中,您可以添加一些脚本功能。我为onEdit事件添加了一些内容,但我无法判断它是否有效。据我所知,你不能从Google表格中调试一个直播事件,所以你必须从调试器中做到这一点,这是没有意义的,因为传递给我的onEdit()函数的事件参数将永远是如果我从Script Editor运行它,则为undefined。

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

来查看日志

我希望我能够在事件实际执行时看到日志,但我无法弄清楚。

如何调试这些内容?

11 个答案:

答案 0 :(得分:69)

更新:

正如this回答中所述,


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

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

我为该脚本安装的唯一触发器是onOpen和onEdit触发器。调试onEdit触发器是最难理解的,因为我一直在想,如果我在onEdit函数中设置断点,打开电子表格,编辑一个单元格,我的断点就会被触发。事实并非如此。

为了模拟已编辑过的单元格,我 最终不得不在实际的电子表格中执行某些操作。我所做的就是确保选中我想要它作为“已编辑”的单元格,然后在Script Editor中,我会转到Run->onEdit。然后我的断点就会被击中。

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

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


修改

如果您想查看我制作的待办清单,您可以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();
};

答案 1 :(得分:30)

  

据我所知,你不能从谷歌文档调试一个直播事件,所以你必须从调试器那里做,这是没有意义的,因为传递给我的onEdit()函数的事件参数总是如果我从脚本编辑器中运行它,则不确定。

True - 因此请自行定义事件参数以进行调试。见How can I test a trigger function in GAS?

  

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

来查看日志

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

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

Logger = BetterLog.useSpreadsheet();

答案 2 :(得分:14)

2017年更新: 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 Object的{​​{3}}中的日志以查看输出

答案 3 :(得分:5)

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

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

答案 4 :(得分:5)

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

基本上只要脚本编辑器打开,事件就会写入日志并为您显示。如果其他人在其他地方的文件中,则不会显示。

答案 5 :(得分:3)

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

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

答案 6 :(得分:1)

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

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

基本上,它只是一个JavaScript output问题。

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

答案 7 :(得分:1)

只需调试电子表格代码,如下所示:

...
throw whatAmI;
...

显示如下:

enter image description here

答案 8 :(得分:0)

目前,您仅限于在文档中使用脚本的容器绑定性质。如果您在文档外部创建新脚本,那么您将能够将信息导出到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,所以我可以写信息并记录。

答案 9 :(得分:0)

正如通知一样。我为我的电子表格做了一个测试功能。我在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

答案 10 :(得分:0)

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

throw Error('hello world!');

将与console.log('hello world')

类似地显示在控制台中