Bagaimana cara debug Google Apps Script (alias kemana Logger.log masuk?)

129

Di Google Sheets, Anda dapat menambahkan beberapa fungsi skrip. Saya menambahkan sesuatu untuk onEditacara tersebut, tetapi saya tidak tahu apakah itu berfungsi. Sejauh yang saya tahu, Anda tidak dapat men-debug acara langsung dari Google Sheets, jadi Anda harus melakukannya dari debugger, yang tidak ada gunanya karena argumen acara yang dilewatkan ke onEdit()fungsi saya akan selalu tidak terdefinisi jika saya menjalankannya dari Script Editor.

Jadi, saya mencoba menggunakan Logger.logmetode untuk mencatat beberapa data setiap kali onEditfungsi dipanggil, tetapi ini sepertinya hanya berfungsi ketika dijalankan dari Script Editor. Ketika saya menjalankannya dari Script Editor, saya dapat melihat log dengan pergi keView->Logs...

Saya berharap saya bisa melihat log dari saat acara tersebut benar-benar dieksekusi, tetapi saya tidak bisa mengetahuinya.

Bagaimana cara men-debug hal ini?

d0c_s4vage
sumber
3
Masalah yang sama di sini - jawaban yang diterima tidak menjawabnya tetapi memberikan banyak info yang salah.
Hippyjim
Sepertinya mereka memperbaikinya sekarang. Selama Anda membuka Script Editor dari spreadsheet Anda, biarkan tab itu terbuka ketika Anda menjalankan hal-hal di Sheet Anda. Kemudian kembali ke tab skrip dan akan ada info Logging di dalamnya.
phreakhead
2
tldr; salin, tempel, dan jalankanLogger.log('firstLog');MailApp.sendEmail({to:'[email protected]',subject: "subject here ^_^",body: Logger.getLog()});
Coty Embry
Maby Anda harus mengubah jawaban yang diterima atau menambahkan catatan bahwa Stackdriver Logging tersedia.
botenvouwer

Jawaban:

83

MEMPERBARUI:

Seperti yang tertulis dalam jawaban ini ,


Logger.logakan mengirimi Anda email (akhirnya) kesalahan yang terjadi dalam skrip Anda, atau, jika Anda menjalankan sesuatu dari Script Editor, Anda dapat melihat log dari fungsi yang terakhir dijalankan dengan masuk ke View->Logs(masih dalam editor skrip). Sekali lagi, itu hanya akan menunjukkan kepada Anda apa pun yang dicatat dari fungsi terakhir yang Anda jalankan dari dalamScript Editor .

Skrip yang saya coba kerjakan berkaitan dengan spreadsheet - Saya membuat jenis spreadsheet todo-checklist yang mengurutkan item berdasarkan prioritas dan semacamnya.

Satu-satunya pemicu yang saya instal untuk skrip itu adalah pemicu onOpen dan onEdit. Melakukan debug pada pemicu onEdit adalah yang paling sulit untuk diketahui, karena saya terus berpikir bahwa jika saya menetapkan breakpoint pada fungsi onEdit saya, membuka spreadsheet, mengedit sel, bahwa breakpoint saya akan dipicu. Ini bukan kasusnya.

Untuk mensimulasikan setelah diedit sel, saya tidak akhirnya harus melakukan sesuatu dalam spreadsheet yang sebenarnya sekalipun. Yang saya lakukan hanyalah memastikan sel yang saya inginkan untuk diperlakukan sebagai "diedit" dipilih, lalu masuk Script Editor, saya akan pergi ke Run->onEdit. Maka breakpoint saya akan dipukul.

Namun, saya harus berhenti menggunakan argumen acara yang diteruskan ke fungsi onEdit - Anda tidak dapat mensimulasikannya dengan melakukan Run->onEdit. Setiap info yang saya butuhkan dari spreadsheet, seperti sel mana yang dipilih, dll, saya harus mencari tahu secara manual.

Ngomong-ngomong, jawaban panjang, tapi akhirnya aku yang menemukannya.


EDIT :

Jika Anda ingin melihat daftar todo yang saya buat, Anda dapat memeriksanya di sini

(ya, saya tahu siapa pun dapat mengeditnya - itulah gunanya membagikannya!)

Saya berharap itu akan membiarkan Anda melihat skrip juga. Karena Anda tidak dapat melihatnya di sana, ini dia:

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();
};
d0c_s4vage
sumber
Pff, logging hanya akan terlihat melalui email? Itu membuat semua fitur debugging dan logging ini menjadi tidak berguna, karena secara efektif kita tidak dapat menggunakan data nyata dari spreadsheet.
MrFox
Tidak. Seperti yang dikatakan penulis, logging tersedia di log (Editor Skrip, Lihat, Masuk atau Ctrl-Enter)
rainabba
9
@rainabba Ya, logging tersedia di Editor Skrip. Namun, ketika skrip bergantung pada argumen acara dan argumen acara tidak tersedia di Editor Skrip, itu secara efektif berarti bahwa pengembang skrip jenis ini tidak memiliki cara waktu nyata untuk mengakses log.
Jeff
1
Saya tidak bisa berkomentar sebelumnya, jadi saya memberikan jawaban di bawah ini, tetapi: JIKA Anda memiliki editor skrip terbuka dan ANDA memicu acara di spreadsheet terbuka, Anda dapat kembali ke instance browser editor skrip dan melihat informasi dalam Log . Ini berfungsi dengan baik selama Anda tidak perlu menguji sesuatu di bawah pengguna yang tidak dapat membuka skrip atau yang Anda tidak bisa masuk sebagai.
Karl_S
1
Jawaban ini sudah usang dan jangan dilihat sebagai jawaban yang diterima. Stackdriver Logging tersedia dan berfungsi seperti pesona. Lihatlah jawaban bagian acak!
botenvouwer
34

Sejauh yang saya tahu, Anda tidak dapat men-debug acara langsung dari google docs, jadi Anda harus melakukannya dari debugger, yang tidak ada gunanya karena argumen acara yang dilewatkan ke fungsi onEdit () saya akan selalu tidak terdefinisi jika saya menjalankan itu dari Editor Skrip.

Benar - jadi tentukan sendiri argumen acara untuk debugging. Lihat Bagaimana saya bisa menguji fungsi pemicu di GAS?

Saya mencoba menggunakan metode Logger.log untuk mencatat beberapa data setiap kali fungsi onEdit dipanggil, tetapi sepertinya ini hanya berfungsi ketika dijalankan dari Editor Skrip. Ketika saya menjalankannya dari Editor Skrip, saya dapat melihat log dengan membuka View-> Logs ...

Benar lagi, tetapi ada bantuan. Pustaka BetterLog Peter Hermann akan mengarahkan semua log ke spreadsheet, memungkinkan pencatatan bahkan dari kode yang tidak dilampirkan ke instance editor / debugger.

Misalnya, jika Anda mengkode dalam skrip yang berisi spreadsheet, Anda dapat menambahkan hanya satu baris ini ke bagian atas file skrip Anda, dan semua log akan masuk ke lembar "Log" di spreadsheet. Tidak perlu kode lain, cukup gunakan Logger.log()seperti biasa:

Logger = BetterLog.useSpreadsheet();
Mogsdad
sumber
1
Ketinggalan jaman. console.log()harus menjadi jawaban terbaik sekarang
TheMaster
22

Pembaruan 2017: Pencatatan Stackdriver sekarang tersedia untuk Google Apps Script. Dari bilah menu di editor skrip, goto: View > Stackdriver Logginguntuk melihat atau mengalirkan log.

console.log () akan menulis DEBUGpesan level

Contoh onEdit()logging:

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

Kemudian periksa log di UI Stackdriver berlabel onEdit() Event Objectuntuk melihat output

bagian acak
sumber
Pertanyaan asli secara khusus bertanya tentang Logger.log. Bagaimana ini berbeda dari console.logyang Anda gunakan? Saya sangat baru dengan alat jadi hanya mencoba mencari tahu apa semuanya.
AnnanFay
5

Sedikit hacky, tapi saya membuat array yang disebut "konsol", dan kapan saja saya ingin output ke konsol saya mendorong ke array. Lalu setiap kali saya ingin melihat hasil aktual, saya hanya kembali, consolebukan apa pun yang saya kembali sebelumnya.

    //return 'console' //uncomment to output console
    return "actual output";
}
woojoo666
sumber
di js console.log('smth')berfungsi dengan baik, tapi bagaimana dengan GAS?
Igor Savinkin
1
console.log tidak akan berfungsi hanya karena GAS bukan skrip yang berjalan di halaman web yang sama dengan spreadsheet Anda, skrip tersebut ditangani oleh mesin app google sehingga Anda harus mengikuti debugger Logger.log yang sulit atau menggunakan peretasan seperti milik saya
woojoo666
bagaimana dengan 'konsol' array Anda? Kapan I just returned consoleAnda mengeluarkannya?
Igor Savinkin
2
Maaf saya tidak menjelaskan dengan baik, tetapi fungsi spreadsheet pada dasarnya mengembalikan nilai ke sel, jadi jika Anda mengembalikan "konsol" Anda, Anda akan melihat semua yang Anda login di dalam sel spreadsheet Anda
woojoo666
5

Jika Anda memiliki editor skrip terbuka, Anda akan melihat log di bawah-> Log. Jika skrip Anda memiliki pemicu onedit, buat perubahan ke spreadsheet yang seharusnya memicu fungsi dengan editor skrip dibuka di tab kedua. Lalu buka tab editor skrip dan buka log. Anda akan melihat apa pun fungsi Anda lewat ke logger.

Pada dasarnya selama editor skrip terbuka, acara akan menulis ke log dan menunjukkannya untuk Anda. Itu tidak akan ditampilkan jika orang lain ada di file di tempat lain.

Karl_S
sumber
5

Saya telah membaca tulisan-tulisan ini dan akhirnya menemukan jawaban yang sederhana, yang saya posting di sini untuk mereka yang menginginkan solusi singkat dan manis:

  1. Gunakan console.log("Hello World")dalam skrip Anda.
  2. Buka https://script.google.com/home/my dan pilih add-on Anda.
  3. Klik pada menu elipsis pada Detail Proyek, pilih Eksekusi.

masukkan deskripsi gambar di sini

  1. Klik pada tajuk eksekusi terakhir dan baca log.

masukkan deskripsi gambar di sini

Benjamin
sumber
Ini adalah "Stackdriver logging" dasar untuk Google Apps Script yang dibuat setelah April 2019 (yang ketika mengakses Proyek Google Cloud untuk proyek "otomatis" di belakang Apps Script menjadi tidak mungkin). Jika Anda mengubah GCP untuk proyek Script Aplikasi, maka jawaban logging Stackdriver biasa berlaku.
tehhowch
1
Saya hanya melihat eksekusi langsung di sini (yaitu yang saya klik "jalankan" di editor skrip), tetapi saya tidak melihat eksekusi yang disebabkan oleh perubahan data di sheet. Bagaimana cara men-debug itu?
Cris70
Saya belum mencobanya maaf. Saya akan membayangkan bahwa jika perubahan pada lembar memicu fungsi dan fungsi memiliki log, log akan muncul bersama. Perubahan akan selalu disebabkan oleh pengguna, bukan?
Benjamin
1
Ya, saya akan membayangkan itu juga. Sayangnya bukan itu yang terjadi :-( Perubahan pada data memicu fungsi saya, tetapi pesan console.log () tidak ditampilkan di log Stackdriver. Saya mencoba menambahkan aktivator yang sedang diubah, tetapi itu memanggil fungsi saya tanpa parameter: - (
Cris70
4

Saya mengalami masalah yang sama, saya menemukan di bawah ini di web di suatu tempat ....

Penangan acara di Documents sedikit rumit. Karena dokumen dapat menangani beberapa pengeditan simultan oleh beberapa pengguna, penangan acara ditangani di sisi server. Masalah utama dengan struktur ini adalah bahwa ketika skrip pemicu peristiwa gagal, maka gagal di server. Jika Anda ingin melihat info debug, Anda harus menyiapkan pemicu eksplisit di bawah menu pemicu yang mengirimkan info debug kepada Anda saat acara gagal atau jika tidak maka diam-diam akan gagal.

Angus Keenan
sumber
Hmm, ya, saya memang mengalami hal ini - itu mengirimi saya banyak kesalahan dari skrip keesokan paginya. Saya akhirnya menemukan jawabannya (memposting jawaban saya sendiri sekarang)
d0c_s4vage
1

Ini jauh dari anggun, tetapi saat debugging, saya sering masuk ke Logger, dan kemudian menggunakan getLog () untuk mengambil isinya. Lalu, saya juga:

  • menyimpan hasil ke variabel (yang dapat diperiksa dalam debugger Google Scripts - ini bekerja di sekitar kasus di mana saya tidak dapat menetapkan breakpoint dalam beberapa kode, tetapi saya dapat mengatur satu dalam kode yang akan dieksekusi nanti)
  • tulis ke beberapa elemen DOM sementara
  • tampilkan dalam peringatan

Pada dasarnya, itu hanya menjadi masalah keluaran JavaScript .

Itu sangat tidak memiliki fungsionalitas console.log()implementasi modern , tetapi Logger masih membantu debug Google Script.

Michael Scheper
sumber
1

Sama seperti pemberitahuan. Saya membuat fungsi pengujian untuk spreadsheet saya. Saya menggunakan variabel google throws pada fungsi onEdit (e) (saya menyebutnya e). Lalu saya membuat fungsi tes seperti ini:

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

Memanggil fungsi tes ini membuat semua kode berjalan saat Anda memiliki acara di spreadsheet. Saya baru saja memasukkan sel yang saya edit dan whitch memberi saya hasil yang tidak terduga, menetapkan nilai sebagai nilai yang saya masukkan ke dalam sel. OBS! untuk lebih banyak variabel yang diberikan Google ke fungsi, buka di sini: https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events

Meltinglava
sumber
0

Saat ini Anda terbatas pada sifat terikat wadah menggunakan skrip dalam dokumen. Jika Anda membuat skrip baru di dalam di luar dokumen maka Anda akan dapat mengekspor informasi ke google spreadsheet dan menggunakannya seperti alat pencatatan.

Misalnya di blok kode pertama Anda

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

Ketika saya bekerja dengan GAS, saya memiliki dua monitor (Anda dapat menggunakan dua jendela) yang diatur dengan satu berisi lingkungan GAS dan yang lainnya berisi SS sehingga saya dapat menulis informasi dan log.

JForgie
sumber
0

Konsol dev akan mencatat kesalahan yang dilemparkan oleh skrip aplikasi, jadi Anda bisa membuang kesalahan untuk membuatnya masuk sebagai console.log normal. Ini akan menghentikan eksekusi, tetapi mungkin masih berguna untuk debugging langkah demi langkah.

throw Error('hello world!');

akan muncul di konsol mirip dengan console.log('hello world')

qwerty
sumber
0

cukup debug kode spreadsheet Anda seperti ini:

...
throw whatAmI;
...

acara seperti ini:

masukkan deskripsi gambar di sini

Toskan
sumber
Saya pikir Anda harus menyebutkan bahwa gambar menunjukkan bagaimana fungsi kustom menunjukkan kesalahan tetapi OP menyebutkan bahwa ia menggunakan pemicu sederhana ( onEdit)
Rubén