Как отладить Google Apps Script (иначе, куда входит Logger.log?)
В Google Sheets вы можете добавить некоторые функции сценариев. Я добавляю что-то для onEdit
событие, но я не могу сказать, работает ли оно. Насколько я могу судить, вы не можете отлаживать живое событие из Google Sheets, поэтому вы должны делать это от отладчика, что бессмысленно, поскольку аргумент события передан моему onEdit()
функция всегда будет неопределенной, если я запусту ее из Script Editor
,
Итак, я пытался использовать Logger.log
метод для регистрации некоторых данных всякий раз, когда onEdit
Функция вызывается, но, похоже, это работает только при запуске из Script Editor
, Когда я запускаю его из Script Editor
Я могу просмотреть журналы, перейдя в View->Logs...
Я надеялся, что смогу увидеть журналы, когда событие действительно будет выполнено, но я не могу понять это.
Как мне отладить этот материал?
13 ответов
Logger.log
либо отправит вам по электронной почте (в конце концов) сообщения об ошибках, которые произошли в ваших скриптах, либо, если вы запускаете что-то из Script Editor
, вы можете просмотреть журнал из функции последнего запуска, перейдя в View->Logs
(все еще в редакторе сценариев). Опять же, это покажет вам только то, что было зарегистрировано из последней функции, которую вы запустили изнутри Script Editor
,
Сценарий, который я пытался заставить работать, был связан с электронными таблицами - я создал таблицу типа todo-checklist, которая сортировала элементы по приоритетам и тому подобное.
Единственными триггерами, которые я установил для этого скрипта, были триггеры 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();
};
Насколько я могу судить, вы не можете отлаживать живое событие из документации Google, поэтому вы должны делать это из отладчика, что бессмысленно, так как аргумент события, передаваемый моей функции onEdit(), всегда будет неопределенным, если я запустлю это из редактора сценариев.
Верно - так что определите аргумент события самостоятельно для отладки. См. Как я могу проверить триггерную функцию в GAS?
Я пытался использовать метод Logger.log для регистрации некоторых данных при каждом вызове функции onEdit, но, похоже, это работает только при запуске из редактора сценариев. Когда я запускаю его из редактора сценариев, я могу просмотреть журналы, перейдя в View->Logs...
Верно снова, но есть помощь. Библиотека Питера Германа BetterLog перенаправит все журналы в электронную таблицу, позволяя вести журналы даже из кода, который не присоединен к экземпляру редактора / отладчика.
Например, если вы кодируете сценарий, содержащий электронную таблицу, вы можете добавить только одну эту строку в начало файла сценария, и все журналы перейдут на лист "Журналы" в электронной таблице. Никакой другой код не нужен, просто используйте Logger.log()
как обычно:
Logger = BetterLog.useSpreadsheet();
Обновление 2017 года: ведение журнала Stackdriver теперь доступно для скрипта 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 с меткой onEdit() Event Object
чтобы увидеть результат
Я просмотрел эти сообщения и каким-то образом нашел простой ответ, который я публикую здесь для тех, кому нужны короткие и приятные решения:
- Использовать
console.log("Hello World")
в вашем сценарии. - Перейдите на https://script.google.com/home/my и выберите свое дополнение.
- Нажмите на многоточие в меню "Сведения о проекте" и выберите "Выполнения".
- Щелкните заголовок последнего выполнения и прочтите журнал.
Для проектов Apps Script, привязанных к одному листу (или документу) — в 2022 году —View
меню, как предлагают другие ответы. Вместо этого вам нужно заглянуть вExecutions
меню на левой боковой панели, чтобы увидеть выполнение вашихonSelectionChange
функция (или любая другая функция), оттуда вы можете нажатьREFRESH
пока твойconsole.log
появляются сообщения.
Немного хакерский, но я создал массив под названием "консоль", и каждый раз, когда я хотел выводить данные на консоль, я помещал их в массив. Тогда всякий раз, когда я хотел увидеть фактический результат, я просто возвращался console
вместо того, что я возвращал раньше.
//return 'console' //uncomment to output console
return "actual output";
}
Если у вас открыт редактор сценариев, вы увидите журналы под View->Logs. Если в вашем скрипте есть триггер onedit, внесите изменения в электронную таблицу, которая должна активировать функцию с помощью редактора скриптов, открытого на второй вкладке. Затем перейдите на вкладку редактора сценариев и откройте журнал. Вы увидите, что ваша функция передает регистратору.
В основном, пока открыт редактор сценариев, событие будет записывать в журнал и показывать его вам. Это не покажет, если кто-то еще находится в файле в другом месте.
У меня та же проблема, я нашел где-то ниже в Интернете...
Обработчики событий в Документах немного сложны. Поскольку документы могут обрабатывать несколько одновременных изменений несколькими пользователями, обработчики событий обрабатываются на стороне сервера. Основная проблема, связанная с этой структурой, заключается в том, что при сбое сценария запуска события происходит сбой на сервере. Если вы хотите просмотреть информацию об отладке, вам нужно установить явный триггер в меню триггеров, которое отправит вам информацию об отладке по электронной почте при сбое события, иначе оно произойдет автоматически.
Просто как уведомление. Я сделал тестовую функцию для моей таблицы. Я использую переменную google throws в функции onEdit(e) (я назвал ее 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
Это далеко не элегантно, но во время отладки я часто регистрируюсь в Logger, а затем использую getLog() для извлечения его содержимого. Тогда я либо:
- сохранить результаты в переменной (которую можно проверить в отладчике Google Scripts - это работает в тех случаях, когда я не могу установить точку останова в каком-то коде, но я могу установить точку в коде, который выполняется позже)
- запишите это во временный элемент DOM
- отобразить его в предупреждении
По сути, это просто становится проблемой вывода JavaScript.
Ему крайне не хватает функциональности современного console.log()
реализации, но Logger по-прежнему помогает отлаживать Google Scripts.
В настоящее время вы ограничены использованием скриптов в документации. Если вы создадите новый скрипт внутри документа, то сможете экспортировать информацию в электронную таблицу 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, чтобы я мог записывать информацию и регистрировать ее.
Консоль dev будет регистрировать ошибки, генерируемые сценарием приложения, поэтому вы можете просто сгенерировать ошибку, чтобы она регистрировалась как обычный console.log. Это остановит выполнение, но все равно может быть полезно для пошаговой отладки.
throw Error('hello world!');
будет отображаться в консоли аналогично console.log('hello world')
Просто отладьте код вашей электронной таблицы следующим образом:
...
throw whatAmI;
...
показывает так: