it-swarm.com.ru

Как отладить Google Apps Script (иначе, куда входит Logger.log?)

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

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

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

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

91
Markus Orreilly

Обновление: 

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

  • StackDriver Logging сейчас является предпочтительным методом ведения журнала. 

  • Используйте console.log() для входа в strackdriver.


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

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

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

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

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

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

Logger = BetterLog.useSpreadsheet();
29
Mogsdad

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, чтобы увидеть выходные данные

11
random-parts

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

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

5
Karl_S

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

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

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

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

3
Angus Keenan

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

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

По сути, это просто становится вывод JavaScript проблема.

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

1
Michael Scheper

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

Просто как уведомление. Я сделал тестовую функцию для моей таблицы. Я использую переменную 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#google_sheets_events

0
Meltinglava Outland

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

throw Error('hello world!');

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

0
qwerty

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

...
throw whatAmI;
...

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

 enter image description here

0
Toskan