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


129

在Google表格中,您可以添加一些脚本功能。我为onEdit活动添加了一些内容,但无法确定它是否有效。据我所知,您无法从Google Sheets调试实时事件,因此您必须从调试器中进行调试,这是没有意义的,因为onEdit()如果我从Script Editor

因此,Logger.log无论何时onEdit调用该函数,我都试图使用该方法记录一些数据,但这似乎也仅在从中运行时才起作用Script Editor。从中运行时Script Editor,我可以通过转到以下位置查看日志View->Logs...

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

我该如何调试这些东西?


3
同样的问题在这里-接受的答案无法回答,但给出了很多明显的错误信息。
Hippyjim

看来他们现在已解决此问题。只要您从电子表格中打开“脚本编辑器”,就可以在工作表中运行该标签时将该选项卡保持打开状态。然后返回脚本选项卡,其中将包含日志记录信息。
phreakhead

2
tldr; 复制,粘贴和运行Logger.log('firstLog');MailApp.sendEmail({to:'yourEmailAddressHere@someone.com',subject: "subject here ^_^",body: Logger.getLog()});
Coty Embry

Maby,您应该更改接受的答案或添加注释Stackdriver Logging可用。
botenvouwer

Answers:


83

更新:

就像在这个答案中写的,


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

我尝试使用的脚本与电子表格有关-我做了一个电子表格待办事项清单类型的东西,可以按优先级等对项目进行排序。

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

为了模拟已经编辑的单元格,我没有最终不得不做一些实际的电子表格,但。我所做的只是确保选择了希望将其视为“已编辑”的单元格,然后Script Editor进入Run->onEdit。然后我的断点就会被击中。

但是,我确实必须停止使用传递给onEdit函数的事件参数-您无法通过做模拟Run->onEdit。我需要从电子表格中获取的任何信息,例如选择了哪个单元格等等,我都必须手动找出。

无论如何,答案很长,但我最终弄清楚了。


编辑

如果您想查看我制作的待办事项清单,可以在此处查看

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

我希望它也能让您看到脚本。由于您在此处看不到它,因此它是:

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();
};

PFF,日志记录仅在邮件中可见?这样有点使所有这些调试和日志记录功能无用,因为实际上我们不能使用电子表格中的真实数据。
MrFox 2013年

否。正如作者所说,日志可以在日志中找到(脚本编辑器,视图,日志或Ctrl-Enter)
rainabba 2013年

9
@rainabba是的,可以在脚本编辑器中进行日志记录。但是,当脚本依赖于事件参数,而事件参数在“脚本编辑器”中不可用时,这实际上意味着这些类型的脚本的开发人员无法实时访问日志。
杰夫

1
我之前无法发表评论,所以我在下面提供了一个答案,但是:如果您打开了脚本编辑器,并且在打开的电子表格中触发了事件,则可以返回到脚本编辑器浏览器实例,然后在日志中查看信息。 。只要您不必在无法打开脚本或无法登录的用户的身份下进行测试,它就可以正常工作。
Karl_S 2016年

1
该答案已过时,不应视为已接受的答案。Stackdriver Logging可用并且像超级按钮一样工作。看看随机部分的答案!
botenvouwer

34

据我所知,您无法从Google文档中调试实时事件,因此您必须从调试器中进行调试,这毫无意义,因为如果我运行,传递给我的onEdit()函数的事件参数将始终是未定义的从脚本编辑器中获取。

正确-因此请自行定义事件参数以进行调试。请参阅如何在GAS中测试触发功能?

每当尝试调用onEdit函数时,我都试图使用Logger.log方法记录一些数据,但这似乎也仅在从脚本编辑器运行时才起作用。当我从脚本编辑器运行它时,可以通过查看->日志...来查看日志。

再次正确,但有帮助。彼得·赫尔曼(Peter Hermann)的BetterLog库会将所有日志重定向到电子表格,甚至可以从未附加到编辑器/调试器实例的代码进行日志记录。

例如,如果您使用电子表格包含的脚本进行编码,则可以仅将这一行添加到脚本文件的顶部,所有日志将进入电子表格中的“日志”工作表。无需其他代码,只需照常使用即可Logger.log()

Logger = BetterLog.useSpreadsheet();

1
过时的。console.log()现在应该是最好的答案
TheMaster

22

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});
}

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


最初的问题专门询问Logger.log。这与console.log您使用的有什么不同?我对这些工具还很陌生,所以只想弄清楚一切是什么。
AnnanFay

5

有点hacky,但是我创建了一个名为“ console”的数组,并且每当我想输出到控制台时,我都会推送到该数组。然后,每当我想查看实际输出时,我都只是返回console而不是之前返回的内容。

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

在js中 console.log('smth')工作完美,但在GAS中如何?
Igor Savinkin

1
的console.log将不只是工作,因为天然气是不是在同一个网页为您的电子表格运行脚本,它们是由谷歌的应用引擎处理脚本,让你不得不按照他们的笨重Logger.log调试器或使用黑客像我
woojoo666

您的阵列“控制台”如何?什么时候I just returned console输出?
Igor Savinkin

2
抱歉,我的解释不是很好,但是电子表格函数实际上会将值返回到单元格,因此,如果返回“控制台”,您将看到在电子表格单元格中记录的所有内容
woojoo666 2015年

5

如果您打开了脚本编辑器,则将在“查看”->“日志”下看到日志。如果您的脚本具有onedit触发器,请对电子表格进行更改,以在第二个选项卡中打开脚本编辑器的情况下触发该功能。然后转到脚本编辑器选项卡并打开日志。您将看到任何传递给记录器的功能。

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


5

我遍历了这些帖子,最终以某种方式找到了一个简单的答案,我在这里针对那些想要简短而又甜蜜的解决方案的人发布:

  1. console.log("Hello World")在脚本中使用。
  2. 转到https://script.google.com/home/my,然后选择您的加载项。
  3. 单击“项目详细信息”上的省略号菜单,选择“执行”。

在此处输入图片说明

  1. 单击最新执行的标题并阅读日志。

在此处输入图片说明


这是2019年4月之后创建的Google Apps脚本的基本“堆栈驱动程序日志记录”(当无法访问Google Cloud Project时,“ Apps脚本”后面的“自动”项目无法使用)。如果您更改了Google Apps脚本项目的GCP,则适用常规Stackdriver日志记录答案。
tehhowch

1
我在这里只看到直接执行(即在脚本编辑器中单击“运行”的直接执行),但是看不到工作表中的数据更改导致的执行。我该如何调试?
Cris70

我没有尝试过对不起。我可以想象,如果工作表中的更改触发了一个函数并且该函数具有一个日志,那么该日志也会显示出来。更改永远都是用户引起的,对吧?
本杰明

1
是的,我也可以想象得到。不幸的是,这不会发生:-(数据更改确实触发了我的功能,但是console.log()消息未显示在Stackdriver日志中。 -(
Cris70

4

我遇到了同样的问题,我在网上某个地方找到了以下内容...。

不过,文档中的事件处理程序有些棘手。由于文档可以处理多个用户的多个同时编辑,因此事件处理程序在服务器端进行处理。这种结构的主要问题是,事件触发脚本失败时,它将在服务器上失败。如果要查看调试信息,则需要在“触发器”菜单下设置一个显式触发器,以便在事件失败时将调试信息通过电子邮件发送给您,否则它将以静默方式失败。


嗯,是的,我确实遇到了这个问题-第二天早上,它通过电子邮件向我发送了很多错误。我确实弄清楚了(现在发布我自己的答案)
d0c_s4vage 2012年

1

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

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

本质上,它变成了 JavaScript输出问题。

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


1

只是通知。我为电子表格做了一个测试功能。我在onEdit(e)函数中使用了Google抛出的变量(我称之为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())
}

调用此测试函数可使所有代码在电子表格中发生事件时运行。我只是把我编辑的单元格的位置放进去,给了我一个意想不到的结果,将值设置为我放入单元格中的值。OBS!有关Google为该函数提供的更多变量的信息,请访问:https : //developers.google.com/apps-script/guides/triggers/events#google_sheets_events


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,因此我可以向其中写入信息并进行日志记录。


0

开发控制台将记录由应用脚本引发的错误,因此您只需抛出一个错误即可将其记录为普通console.log。它会停止执行,但是对于逐步调试仍然有用。

throw Error('hello world!');

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


0

像这样调试电子表格代码:

...
throw whatAmI;
...

显示如下:

在此处输入图片说明


我觉得你必须提到的是,图像显示了如何自定义功能显示了一个错误,但OP提到,他是用一个简单的触发器(onEdit
鲁本
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.