Jak debugować Google Apps Script (czyli gdzie logger.log się loguje?)


129

W Arkuszach Google możesz dodać funkcje skryptów. Dodam coś do onEditwydarzenia, ale nie wiem, czy to działa. O ile wiem, nie możesz debugować wydarzenia na żywo z Arkuszy Google, więc musisz to zrobić z debugera, co jest bezcelowe, ponieważ argument zdarzenia przekazany do mojej onEdit()funkcji będzie zawsze niezdefiniowany, jeśli uruchomię go z Script Editor.

Próbowałem więc użyć tej Logger.logmetody do rejestrowania niektórych danych za każdym razem, gdy onEditfunkcja zostanie wywołana, ale to również wygląda na to, że działa tylko po uruchomieniu z Script Editor. Kiedy uruchamiam go z poziomu Script Editor, mogę przeglądać dzienniki, przechodząc doView->Logs...

Miałem nadzieję, że będę mógł zobaczyć dzienniki z czasu rzeczywistego wykonania zdarzenia, ale nie mogę tego rozgryźć.

Jak mogę debugować te rzeczy?


3
Ten sam problem - zaakceptowana odpowiedź nie daje odpowiedzi, ale zawiera wiele błędnych informacji.
Hippyjim

Wygląda na to, że naprawili to teraz. Dopóki otwierasz Edytor skryptów z arkusza kalkulacyjnego, pozostaw tę kartę otwartą, gdy uruchamiasz elementy w arkuszu. Następnie wróć do zakładki skryptu i będzie zawierała informacje o logowaniu.
phreakhead

2
tldr; kopiuj, wklejaj i uruchamiajLogger.log('firstLog');MailApp.sendEmail({to:'yourEmailAddressHere@someone.com',subject: "subject here ^_^",body: Logger.getLog()});
Coty Embry

Maby, zmień zaakceptowaną odpowiedź lub dodaj uwagę, że usługa Stackdriver Logging jest dostępna.
botenvouwer

Odpowiedzi:


83

AKTUALIZACJA:

Jak napisano w tej odpowiedzi,


Logger.logwyśle ​​Ci e-mail (ostatecznie) o błędach, które wystąpiły w twoich skryptach lub, jeśli uruchamiasz rzeczy z Script Editor, możesz wyświetlić dziennik z funkcji ostatniego uruchomienia, przechodząc do View->Logs(nadal w edytorze skryptów). Ponownie, pokaże ci tylko wszystko, co zostało zarejestrowane z ostatniej funkcji, którą uruchomiłeś od wewnątrzScript Editor .

Skrypt, który próbowałem uruchomić, dotyczył arkuszy kalkulacyjnych - utworzyłem arkusz kalkulacyjny typu lista kontrolna zadań, który posortował elementy według priorytetów i tym podobne.

Jedyne wyzwalacze, które zainstalowałem dla tego skryptu, to wyzwalacze onOpen i onEdit. Debugowanie wyzwalacza onEdit było najtrudniejsze do rozgryzienia, ponieważ ciągle myślałem, że jeśli ustawię punkt przerwania w mojej funkcji onEdit, otworzę arkusz kalkulacyjny, wyedytuję komórkę, mój punkt przerwania zostanie wyzwolony. Nie o to chodzi.

Aby zasymulować edycję komórki, musiałem jednak zrobić coś w rzeczywistym arkuszu kalkulacyjnym. Jedyne, co zrobiłem, to upewnienie się, że komórka, którą chciałem traktować jako „edytowaną”, została wybrana, a następnie Script Editorprzejdę do Run->onEdit. Wtedy mój punkt przerwania zostałby trafiony.

Jednak musiałem przestać używać argumentu zdarzenia, który jest przekazywany do funkcji onEdit - nie można tego zasymulować Run->onEdit. Wszelkie informacje, których potrzebowałem z arkusza kalkulacyjnego, takie jak wybrana komórka itp., Musiałem ustalić ręcznie.

Tak czy inaczej, długa odpowiedź, ale w końcu to rozgryzłem.


EDYCJA :

Jeśli chcesz zobaczyć listę kontrolną rzeczy do zrobienia, możesz sprawdzić ją tutaj

(tak, wiem, że każdy może to edytować - o to właśnie chodzi w udostępnianiu!)

Miałem nadzieję, że dzięki temu zobaczysz również scenariusz. Ponieważ nie możesz tego zobaczyć, oto jest:

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, logowanie będzie widoczne tylko w mailu? To sprawia, że ​​wszystkie te funkcje debugowania i logowania są bezużyteczne, ponieważ w praktyce nie możemy używać prawdziwych danych z arkusza kalkulacyjnego.
MrFox,

Nie. Jak powiedział autor, logowanie jest dostępne w logu (Edytor skryptów, Widok, Log lub Ctrl-Enter)
rainabba

9
@rainabba Tak, logowanie jest dostępne w edytorze skryptów. Jednak gdy skrypt zależy od argumentu zdarzenia, a argument zdarzenia nie jest dostępny w Edytorze skryptów, oznacza to w praktyce, że twórcy skryptów tego typu nie mają możliwości uzyskania dostępu do dzienników w czasie rzeczywistym.
Jeff

1
Nie mogłem wcześniej komentować, więc przedstawiłem odpowiedź poniżej, ale: JEŚLI masz otwarty edytor skryptów i TY wywołujesz zdarzenie w otwartym arkuszu kalkulacyjnym, możesz wrócić do instancji przeglądarki edytora skryptów i zobaczyć informacje w dziennikach . Działa dobrze, o ile nie musisz testować czegoś pod użytkownikiem, który nie może otworzyć skryptu lub takiego, na którego nie możesz się zalogować.
Karl_S

1
Ta odpowiedź jest nieaktualna i nie powinna być postrzegana jako akceptowana odpowiedź. Usługa Stackdriver Logging jest dostępna i działa jak marzenie. Spójrz na odpowiedź na losowe części!
botenvouwer

34

O ile wiem, nie można debugować wydarzenia na żywo z dokumentów Google, więc musisz to zrobić z debugera, co jest bezcelowe, ponieważ argument zdarzenia przekazany do mojej funkcji onEdit () zawsze będzie niezdefiniowany, jeśli uruchomię z Edytora skryptów.

Prawda - więc zdefiniuj samodzielnie argument zdarzenia do debugowania. Zobacz Jak mogę przetestować funkcję wyzwalania w GAS?

Próbowałem użyć metody Logger.log do rejestrowania niektórych danych za każdym razem, gdy wywoływana jest funkcja onEdit, ale to też wygląda na to, że działa tylko po uruchomieniu z Edytora skryptów. Kiedy uruchamiam go z Edytora skryptów, mogę wyświetlić dzienniki, przechodząc do Widok-> Dzienniki ...

To znowu prawda, ale jest pomoc. Biblioteka BetterLog Petera Hermanna przekieruje wszystkie dzienniki do arkusza kalkulacyjnego, umożliwiając logowanie nawet z kodu, który nie jest dołączony do instancji edytora / debugera.

Jeśli na przykład kodujesz w skrypcie zawierającym arkusz kalkulacyjny, możesz dodać tylko ten jeden wiersz na początku pliku skryptu, a wszystkie dzienniki zostaną umieszczone w arkuszu „Dzienniki” w arkuszu kalkulacyjnym. Żaden inny kod nie jest potrzebny, po prostu użyj Logger.log()tak, jak zwykle:

Logger = BetterLog.useSpreadsheet();

1
Przestarzały. console.log()powinna być teraz najlepszą odpowiedzią
TheMaster

22

Aktualizacja 2017: usługa Stackdriver Logging jest teraz dostępna dla Google Apps Script. Z paska menu w edytorze skryptów przejdź View > Stackdriver Loggingdo : aby wyświetlić lub przesłać strumieniowo dzienniki.

console.log () zapisze DEBUGkomunikaty poziomu

Przykładowe onEdit()logowanie:

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

Następnie sprawdź dzienniki w interfejsie użytkownika Stackdriver oznaczone etykietą, onEdit() Event Objectaby zobaczyć dane wyjściowe


Oryginalne pytanie dotyczy konkretnie Logger.log. Czym się to różni od tego, console.logktórego używasz? Jestem bardzo nowy w narzędziach, więc po prostu próbuję dowiedzieć się, co to jest.
AnnanFay,

5

Trochę hacky, ale utworzyłem tablicę o nazwie „konsola” i za każdym razem, gdy chciałem wyświetlać dane wyjściowe na konsolę, wypychałem do tablicy. Potem, ilekroć chciałem zobaczyć rzeczywisty wynik, po prostu wracałem consolezamiast tego, co zwracałem wcześniej.

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

w js console.log('smth')działa idealnie, ale co w przypadku GAS?
Igor Savinkin

1
console.log nie będzie działać po prostu dlatego, że GAS nie są skryptami działającymi na tej samej stronie internetowej co twój arkusz kalkulacyjny, są to skrypty obsługiwane przez silnik aplikacji Google, więc musisz śledzić ich nieporęczny debugger Logger.log lub użyć
hacka

co z twoją 'konsolą' tablicy? Kiedy I just returned consolejak to drukujesz?
Igor Savinkin

2
Przepraszam, że nie wyjaśniłem dobrze, ale zasadniczo funkcje arkusza kalkulacyjnego zwracają wartość do komórki, więc jeśli
zwrócisz

5

Jeśli masz otwarty edytor skryptów, zobaczysz dzienniki w obszarze Widok-> Dzienniki. Jeśli Twój skrypt ma wyzwalacz onedit, wprowadź zmianę w arkuszu kalkulacyjnym, która powinna wyzwolić funkcję w edytorze skryptów otwartym w drugiej karcie. Następnie przejdź do zakładki edytora skryptów i otwórz dziennik. Zobaczysz wszystko, co funkcja przekazuje rejestratorowi.

Zasadniczo tak długo, jak długo edytor skryptów jest otwarty, zdarzenie zapisze się w dzienniku i pokaże go Tobie. Nie pokaże, czy ktoś inny jest w pliku w innym miejscu.


5

Przejrzałem te posty i jakoś znalazłem prostą odpowiedź, którą zamieszczam tutaj dla tych, którzy chcą krótkich i słodkich rozwiązań:

  1. Użyj console.log("Hello World")w swoim skrypcie.
  2. Wejdź na https://script.google.com/home/my i wybierz swój dodatek.
  3. Kliknij menu wielokropka na Szczegóły projektu, wybierz Wykonania.

wprowadź opis obrazu tutaj

  1. Kliknij nagłówek ostatniego wykonania i przeczytaj dziennik.

wprowadź opis obrazu tutaj


To jest podstawowe „logowanie Stackdriver” dla Google Apps Scripts utworzone po kwietniu 2019 r. (Czyli wtedy, gdy dostęp do projektu Google Cloud dla „automatycznych” projektów za pomocą Apps Scripts stał się niemożliwy). Jeśli zmienisz GCP dla projektu Apps Script, obowiązują zwykłe odpowiedzi dotyczące logowania w usłudze Stackdriver.
tehhowch

1
Widzę tu tylko wykonania bezpośrednie (tj. Te, dla których kliknąłem „uruchom” w edytorze skryptów), ale nie widzę wykonań spowodowanych zmianą danych w arkuszu. Jak je debugować?
Cris70

Przepraszam, nie próbowałem tego. Wyobrażam sobie, że gdyby zmiana w arkuszu wyzwoliła funkcję, a funkcja miałaby dziennik, dziennik pojawiłby się razem. Zmiany zawsze byłyby wywołane przez użytkowników, prawda?
Benjamin

1
Tak, też bym to sobie wyobraził. Niestety tak się nie dzieje :-( Zmiany danych wyzwalają moją funkcję, ale komunikaty console.log () nie są wyświetlane w dzienniku Stackdrivera. Próbowałem dodać aktywator zmiany, ale wywołuje to moją funkcję bez parametrów: - (
Cris70

4

Mam ten sam problem, poniżej znalazłem gdzieś w sieci ....

Obsługa zdarzeń w Dokumentach jest jednak trochę skomplikowana. Ponieważ dokumenty mogą obsługiwać wiele jednoczesnych edycji przez wielu użytkowników, programy obsługi zdarzeń są obsługiwane po stronie serwera. Głównym problemem związanym z tą strukturą jest to, że gdy skrypt wyzwalacza zdarzenia zawiedzie, na serwerze kończy się niepowodzeniem. Jeśli chcesz zobaczyć informacje o debugowaniu, musisz ustawić jawny wyzwalacz w menu wyzwalaczy, który wyśle ​​Ci e-mailem informacje o debugowaniu, gdy zdarzenie się nie powiedzie, w przeciwnym razie zakończy się niepowodzeniem.


Hmm, tak, natknąłem się na to - następnego ranka wysłało mi e-mailem całą masę błędów z moich skryptów.
Skończyło

1

Nie jest to eleganckie, ale podczas debugowania często loguję się do Loggera, a następnie używam getLog () do pobrania jego zawartości. Następnie ja albo:

  • zapisać wyniki do zmiennej (które mogą być poddane inspekcji w ciągu Skrypty Google debugger-to na obejście przypadkach, gdy nie można ustawić punkt przerwania w niektórych kodu, ale można ustawić jeden na kod, który zostanie wykonany później)
  • zapisz go do jakiegoś tymczasowego elementu DOM
  • wyświetlić go w alercie

Zasadniczo staje się to problemem wyjściowym JavaScript .

Rażąco brakuje mu funkcjonalności nowoczesnych console.log()implementacji, ale Logger nadal pomaga debugować Google Scripts.


1

Tylko jako uwaga. Zrobiłem funkcję testową dla mojego arkusza kalkulacyjnego. Używam zmiennej Google wrzuca w funkcji onEdit (e) (nazwałem to e). Następnie wykonałem taką funkcję testową:

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

Wywołanie tej funkcji testowej powoduje, że cały kod działa tak, jak zdarzenie w arkuszu kalkulacyjnym. Po prostu wstawiłem posiadaną komórkę, którą edytowałem, co dało mi nieoczekiwany wynik, ustawiając wartość jako wartość, którą umieściłem w komórce. OBS! aby uzyskać więcej zmiennych, które Google daje funkcji, przejdź tutaj: https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events


0

Obecnie jesteś ograniczony do kontenera związanego z używaniem skryptów w dokumentach. Jeśli utworzysz nowy skrypt poza dokumentami, będziesz mógł wyeksportować informacje do arkusza kalkulacyjnego Google i używać go jako narzędzia do logowania.

Na przykład w pierwszym bloku kodu

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

Kiedy pracuję z GASem, mam dwa monitory (można użyć dwóch okien) skonfigurowane z jednym zawierającym środowisko GAS, a drugim zawierającym SS, więc mogę zapisywać informacje i logować się.


0

Konsola programisty będzie rejestrować błędy generowane przez skrypt aplikacji, więc możesz po prostu zgłosić błąd, aby został zarejestrowany jako normalny plik console.log. Zatrzyma wykonywanie, ale nadal może być przydatny do debugowania krok po kroku.

throw Error('hello world!');

pojawi się w konsoli podobnie do console.log('hello world')


0

po prostu zdebuguj kod swojego arkusza kalkulacyjnego w następujący sposób:

...
throw whatAmI;
...

pokazuje tak:

wprowadź opis obrazu tutaj


Myślę, że powinieneś wspomnieć, że obraz pokazuje, jak funkcja niestandardowa pokazuje błąd, ale OP wspomina, że ​​używa prostego wyzwalacza ( onEdit)
Rubén
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.