Как отладить Google Apps Script (aka, где Logger.log регистрируется?)

В Google Sheets вы можете добавить некоторые функции сценариев. Я добавляю что-то для события onEdit, но не могу сказать, работает ли оно. Насколько я могу судить, вы не можете отлаживать живое событие из Google Sheets, поэтому вы должны делать это из отладчика, что бессмысленно, поскольку аргумент события, передаваемый моей функции onEdit(), всегда будет неопределенным, если я onEdit() это из Script Editor.

Итак, я пытался использовать метод Logger.log для регистрации некоторых данных при каждом onEdit функции onEdit, но похоже, что это работает только при запуске из Script Editor. Когда я запускаю его из Script Editor, я могу просмотреть журналы, перейдя в View->Logs...

Я надеялся, что смогу увидеть журналы, когда событие действительно будет выполнено, но я не могу понять это.

Как мне отладить этот материал?

Ответ 1

ОБНОВИТЬ:

Как написано в этом ответе,


Logger.log либо отправит вам электронное письмо (в конце концов) об ошибках, которые произошли в ваших скриптах, либо, если вы запускаете что-либо из Script Editor, вы можете просмотреть журнал из функции последнего запуска, перейдя в View->Logs (все еще в редакторе скриптов). Опять же, это покажет вам только то, что было зарегистрировано из последней функции, которую вы запустили из Script Editor.

Скрипт, который я пытался заставить работать, был связан с электронными таблицами - я создал таблицу типа todo-checklist, которая сортировала элементы по приоритетам и тому подобное.

Единственными триггерами, которые я установил для этого скрипта, были триггеры onOpen и onEdit. Труднее всего было отладить триггер onEdit, потому что я продолжал думать, что если я установлю точку останова в своей функции onEdit, открою электронную таблицу, отредактирую ячейку, то моя точка останова будет активирована. Это не вариант.

Чтобы имитировать редактирование ячейки, мне пришлось что-то делать в реальной таблице. Все, что я сделал, - убедился, что ячейка, которую я хотел, чтобы она Run->onEdit "отредактированной", была выбрана, затем в Script Editor я Run->onEdit бы к 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();
};

Ответ 2

Насколько я могу судить, вы не можете отлаживать живое событие из документов Google, поэтому вы должны делать это из отладчика, что бессмысленно, так как аргумент события, передаваемый моей функции onEdit(), всегда будет неопределенным, если я запустлю это из редактора сценариев.

Верно - так что определите аргумент события самостоятельно для отладки. См. Как я могу проверить триггерную функцию в GAS?

Я пытался использовать метод Logger.log для регистрации некоторых данных при каждом вызове функции onEdit, но, похоже, это работает только при запуске из редактора сценариев. Когда я запускаю его из редактора сценариев, я могу просмотреть журналы, перейдя в View-> Журналы...

Верно снова, но есть помощь. Библиотека Peter Hermann BetterLog перенаправит все журналы в электронную таблицу, позволяя вести журналы даже из кода, который не присоединен к экземпляру редактора/отладчика.

Например, если вы кодируете сценарий, содержащий электронную таблицу, вы можете добавить только одну эту строку в начало файла сценария, и все журналы перейдут на лист "Журналы" в электронной таблице. Никакого другого кода не требуется, просто используйте Logger.log() как обычно:

Logger = BetterLog.useSpreadsheet();

Ответ 3

Обновление 2017 года: ведение журнала Stackdriver теперь доступно для скрипта Google Apps. В строке меню в редакторе сценариев View > Stackdriver Logging: 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 чтобы увидеть выходные данные.

Ответ 4

Немного взломанный, но я создал массив под названием "console", и в любое время, когда я хотел вывести на консоль, я нажал на массив. Затем всякий раз, когда я хотел видеть фактический вывод, я просто возвращал console вместо того, что я возвращал раньше.

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

Ответ 5

Если у вас открыт редактор script, вы увидите журналы в разделе "Просмотр" > "Журналы". Если ваш script имеет триггер onedit, внесите изменение в электронную таблицу, которая должна вызвать функцию с редактором script, открытым во второй вкладке. Затем перейдите на вкладку редактора script и откройте журнал. Вы увидите, что ваша функция переходит к регистратору.

В принципе до тех пор, пока редактор script открыт, событие будет записываться в журнал и показывать его для вас. Он не будет отображаться, если кто-то еще находится в файле в другом месте.

Ответ 6

У меня такая же проблема, я нашел ниже в Интернете где-то....

Обработчики событий в Документах немного сложны. Поскольку документы могут обрабатывать несколько одновременных изменений несколькими пользователями, обработчики событий обрабатываются на стороне сервера. Основная проблема с этой структурой заключается в том, что при сбое события script он терпит неудачу на сервере. Если вы хотите просмотреть информацию об отладке, вам нужно будет установить явный триггер в меню триггеров, который отправит вам информацию об отладке, когда событие завершится неудачно, или иначе оно будет терпеть неудачу.

Ответ 7

Это далеко не изящно, но во время отладки я часто вхожу в Logger, а затем getLog() извлекает его содержимое. Тогда я либо:

  • сохранить результаты в переменной (которая может быть проверена в отладчике скриптов Google - это работает в случаях, когда я не могу установить контрольную точку в каком-то коде, но я могу установить ее в код, который будет выполнен позже)
  • записать его в некоторый временный элемент DOM
  • отобразите его в alert

По существу, он просто становится выходом JavaScript.

Он сильно лишен функциональности современных реализаций console.log(), но Logger по-прежнему помогает отлаживать скрипты Google.

Ответ 8

просто отладьте код вашей электронной таблицы следующим образом:

...
throw whatAmI;
...

показывает так:

enter image description here

Ответ 9

В настоящее время вы ограничиваетесь контейнером, связанным с использованием сценариев в документах. Если вы создаете новый script внутри внешних документов, вы сможете экспортировать информацию в электронную таблицу 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, чтобы я мог писать информацию и записывать журнал.

Ответ 10

Как уведомление. Я сделал тестовую функцию для своей таблицы. Я использую переменную google throw в функции 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())
}

Вызов этой тестовой функции делает весь код запущенным, поскольку у вас было событие в электронной таблице. Я просто вложил в ячейку я, отредактированный whitch, дал мне неожиданный результат, установив значение как значение, которое я положил в ячейку. OBS! для большего количества переменных googles дает функции здесь: https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events

Ответ 11

Консоль dev будет регистрировать ошибки, генерируемые сценарием приложения, поэтому вы можете просто сгенерировать ошибку, чтобы она регистрировалась как обычный console.log. Это остановит выполнение, но все равно может быть полезно для пошаговой отладки.

throw Error('hello world!');

будет отображаться в консоли аналогично console.log('hello world')