Comment déboguer Google Apps Script (c'est-à-dire où se connecte Logger.log?)

129

Dans Google Sheets, vous pouvez ajouter des fonctionnalités de script. J'ajoute quelque chose pour l' onEditévénement, mais je ne peux pas dire si cela fonctionne. Pour autant que je sache, vous ne pouvez pas déboguer un événement en direct à partir de Google Sheets, vous devez donc le faire à partir du débogueur, ce qui est inutile car l'argument d'événement passé à ma onEdit()fonction sera toujours indéfini si je l'exécute à partir du Script Editor.

J'essayais donc d'utiliser la Logger.logméthode pour enregistrer certaines données chaque fois que la onEditfonction est appelée, mais cela semble aussi que cela ne fonctionne que lorsqu'il est exécuté à partir du Script Editor. Lorsque je l'exécute à partir de Script Editor, je peux afficher les journaux en accédant àView->Logs...

J'espérais pouvoir voir les journaux à partir du moment où l'événement est réellement exécuté, mais je ne peux pas le comprendre.

Comment déboguer ce truc?

d0c_s4vage
la source
3
Même problème ici - la réponse acceptée ne répond pas mais donne beaucoup d'informations erronées.
Hippyjim
Il semble qu'ils ont corrigé cela maintenant. Tant que vous ouvrez l'éditeur de script à partir de votre feuille de calcul, laissez cet onglet ouvert lorsque vous exécutez le contenu de votre feuille. Revenez ensuite à l'onglet de script et il contiendra les informations de journalisation.
phreakhead
2
tldr; copier, coller et exécuterLogger.log('firstLog');MailApp.sendEmail({to:'[email protected]',subject: "subject here ^_^",body: Logger.getLog()});
Coty Embry
Maby, vous devez modifier la réponse acceptée ou ajouter une note indiquant que Stackdriver Logging est disponible.
botenvouwer

Réponses:

83

METTRE À JOUR:

Comme écrit dans cette réponse,


Logger.logvous enverra un e-mail (éventuellement) des erreurs qui se sont produites dans vos scripts, ou, si vous exécutez des choses à partir de Script Editor, vous pouvez afficher le journal de la dernière fonction exécutée en allant à View->Logs(toujours dans l'éditeur de script). Encore une fois, cela ne vous montrera que tout ce qui a été enregistré à partir de la dernière fonction que vous avez exécutée de l'intérieurScript Editor .

Le script que j'essayais de faire fonctionner avait à voir avec des feuilles de calcul - j'ai créé une feuille de calcul de type todo-checklist qui triait les éléments par priorités, etc.

Les seuls déclencheurs que j'ai installés pour ce script étaient les déclencheurs onOpen et onEdit. Le débogage du déclencheur onEdit était le plus difficile à comprendre, car je n'arrêtais pas de penser que si je définissais un point d'arrêt dans ma fonction onEdit, ouvrais la feuille de calcul, modifiais une cellule, mon point d'arrêt serait déclenché. Ce n'est pas le cas.

Pour simuler avoir édité une cellule, je ne finissent par avoir à faire quelque chose dans la feuille de calcul réelle cependant. Tout ce que j'ai fait était de m'assurer que la cellule que je voulais traiter comme "éditée" était sélectionnée, puis dans Script Editor, j'irais Run->onEdit. Ensuite, mon point d'arrêt serait atteint.

Cependant, j'ai dû arrêter d'utiliser l'argument d'événement qui est passé dans la fonction onEdit - vous ne pouvez pas simuler cela en faisant Run->onEdit. Toutes les informations dont j'avais besoin dans la feuille de calcul, comme la cellule sélectionnée, etc., je devais les déterminer manuellement.

Bref, longue réponse, mais je l'ai finalement compris.


MODIFIER :

Si vous voulez voir la liste de contrôle des tâches que j'ai créée, vous pouvez la consulter ici

(oui, je sais que n'importe qui peut le modifier - c'est le but de le partager!)

J'espérais que cela vous permettrait également de voir le script. Puisque vous ne pouvez pas le voir là-bas, le voici:

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
la source
Pff, la journalisation ne sera visible que dans les e-mails? Cela rend en quelque sorte toutes ces fonctionnalités de débogage et de journalisation inutiles, car nous ne pouvons effectivement pas utiliser les données réelles de la feuille de calcul.
MrFox
Non. Comme l'auteur l'a dit, la journalisation est disponible dans le journal (éditeur de script, vue, journal ou Ctrl-Entrée)
rainabba
9
@rainabba Oui, la journalisation est disponible dans l'éditeur de script. Cependant, lorsqu'un script dépend de l'argument d'événement et que l'argument d'événement n'est pas disponible dans l'éditeur de script, cela signifie en fait que les développeurs de ces types de scripts n'ont aucun moyen d'accéder aux journaux en temps réel.
Jeff
1
Je n'ai pas pu commenter auparavant, j'ai donc fourni une réponse ci-dessous, mais: SI vous avez ouvert l'éditeur de script et que VOUS déclenchez un événement dans la feuille de calcul ouverte, vous pouvez revenir à l'instance de navigateur de l'éditeur de script et voir les informations dans les journaux . Cela fonctionne bien tant que vous n'avez pas à tester quelque chose sous un utilisateur qui ne peut pas ouvrir le script ou avec lequel vous ne pouvez pas vous connecter.
Karl_S
1
Cette réponse est dépassée et ne doit pas être considérée comme la réponse acceptée. Stackdriver Logging est disponible et fonctionne comme un charme. Jetez un œil à la réponse aléatoire!
botenvouwer
34

Pour autant que je sache, vous ne pouvez pas déboguer un événement en direct à partir de Google Docs, vous devez donc le faire à partir du débogueur, ce qui est inutile puisque l'argument d'événement passé à ma fonction onEdit () sera toujours indéfini si je lance à partir de l'éditeur de script.

Vrai - définissez vous-même l'argument d'événement pour le débogage. Voir Comment puis-je tester une fonction de déclenchement dans GAS?

J'essayais d'utiliser la méthode Logger.log pour enregistrer certaines données chaque fois que la fonction onEdit est appelée, mais cela semble aussi que cela ne fonctionne que lorsqu'il est exécuté à partir de l'éditeur de script. Lorsque je l'exécute à partir de l'éditeur de script, je peux afficher les journaux en allant dans Affichage-> Journaux ...

C'est encore vrai, mais il y a de l'aide. La bibliothèque BetterLog de Peter Hermann redirigera tous les journaux vers une feuille de calcul, permettant la journalisation même à partir de code qui n'est pas attaché à une instance de l'éditeur / débogueur.

Si vous codez dans un script contenu dans une feuille de calcul, par exemple, vous pouvez ajouter uniquement cette ligne en haut de votre fichier de script, et tous les journaux iront dans une feuille "Journaux" dans la feuille de calcul. Aucun autre code nécessaire, utilisez simplement Logger.log()comme vous le feriez habituellement:

Logger = BetterLog.useSpreadsheet();
Mogsdad
la source
1
Dépassé. console.log()devrait être la meilleure réponse maintenant
TheMaster
22

Mise à jour 2017: Stackdriver Logging est désormais disponible pour Google Apps Script. Dans la barre de menus de l'éditeur de script, allez à: View > Stackdriver Loggingpour afficher ou diffuser les journaux.

console.log () écrira les DEBUGmessages de niveau

Exemple de onEdit()journalisation:

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

Vérifiez ensuite les journaux dans l' interface utilisateur de Stackdriver étiquetés onEdit() Event Objectpour voir le résultat

parties aléatoires
la source
La question originale pose spécifiquement sur Logger.log. En quoi est-ce différent de celui console.logque vous utilisez? Je suis très nouveau dans les outils, alors j'essaie simplement de comprendre ce que tout est.
AnnanFay
5

Un peu hacky, mais j'ai créé un tableau appelé "console", et chaque fois que je voulais sortir sur console, j'ai poussé vers le tableau. Ensuite, chaque fois que je voulais voir la sortie réelle, je revenais simplement consoleau lieu de ce que je retournais avant.

    //return 'console' //uncomment to output console
    return "actual output";
}
woojoo666
la source
dans js console.log('smth')fonctionne parfaitement, mais qu'en est-il dans GAS?
Igor Savinkin le
1
console.log ne fonctionnera pas simplement parce que GAS ne sont pas des scripts exécutés dans la même page Web que votre feuille de calcul, ce sont des scripts gérés par le moteur d'application de Google, vous devez donc suivre leur débogueur Logger.log peu maniable ou utiliser un hack comme le mien
woojoo666
que diriez-vous de votre «console» de tableau? Quand I just returned consolecomment le sortez-vous?
Igor Savinkin le
2
Désolé, je n'ai pas très bien expliqué, mais essentiellement les fonctions de feuille de calcul renvoient la valeur à la cellule, donc si vous renvoyez votre «console», vous verrez tout ce que vous avez connecté dans votre cellule de feuille de calcul
woojoo666
5

Si vous avez ouvert l'éditeur de script, vous verrez les journaux sous Affichage-> Journaux. Si votre script a un déclencheur onedit, apportez une modification à la feuille de calcul qui devrait déclencher la fonction avec l'éditeur de script ouvert dans un deuxième onglet. Accédez ensuite à l'onglet de l'éditeur de script et ouvrez le journal. Vous verrez tout ce que votre fonction transmet à l'enregistreur.

En gros, tant que l'éditeur de script est ouvert, l'événement écrira dans le journal et le montrera pour vous. Il ne montrera pas si quelqu'un d'autre est dans le fichier ailleurs.

Karl_S
la source
5

J'ai parcouru ces articles et j'ai fini par trouver une réponse simple, que je poste ici pour ceux qui veulent des solutions courtes et douces:

  1. Utilisez console.log("Hello World")dans votre script.
  2. Accédez à https://script.google.com/home/my et sélectionnez votre module complémentaire.
  3. Cliquez sur le menu points de suspension sur Détails du projet, sélectionnez Exécutions.

entrez la description de l'image ici

  1. Cliquez sur l'en-tête de la dernière exécution et lisez le journal.

entrez la description de l'image ici

Benjamin
la source
Il s'agit de la "journalisation Stackdriver" de base pour les scripts Google Apps créés après avril 2019 (lorsque l'accès au projet Google Cloud pour les projets "automatiques" derrière les scripts d'applications est devenu impossible). Si vous modifiez le GCP d'un projet Apps Script, les réponses classiques de la journalisation Stackdriver s'appliquent.
tehhowch le
1
Je ne vois ici que les exécutions directes (c'est-à-dire celles pour lesquelles j'ai cliqué sur "exécuter" dans l'éditeur de script), mais je ne vois pas les exécutions causées par un changement de données dans la feuille. Comment les déboguer?
Cris70
Je n'ai pas essayé ça désolé. J'imagine que si un changement dans la feuille déclenchait une fonction et que la fonction avait un journal, le journal s'afficherait. Les changements seraient toujours induits par l'utilisateur, n'est-ce pas?
Benjamin le
1
Oui, j'aurais aussi imaginé ça. Malheureusement, ce n'est pas ce qui se passe :-( Les ​​modifications apportées aux données déclenchent ma fonction, mais les messages console.log () ne sont pas affichés dans le journal Stackdriver. J'ai essayé d'ajouter un activateur de modification, mais cela appelle ma fonction sans paramètres: - (
Cris70
4

J'ai le même problème, j'ai trouvé ce qui suit sur le Web quelque part ...

Les gestionnaires d'événements dans Docs sont cependant un peu compliqués. Étant donné que les documents peuvent gérer plusieurs modifications simultanées par plusieurs utilisateurs, les gestionnaires d'événements sont gérés côté serveur. Le problème majeur avec cette structure est que lorsqu'un script de déclenchement d'événement échoue, il échoue sur le serveur. Si vous voulez voir les informations de débogage, vous devrez configurer un déclencheur explicite dans le menu des déclencheurs qui vous enverra les informations de débogage lorsque l'événement échouera, sinon il échouera silencieusement.

Angus Keenan
la source
Hmm, ouais, je suis tombé sur ça - ça m'a envoyé tout un tas d'erreurs de mes scripts le lendemain matin. J'ai fini par le comprendre (en publiant ma propre réponse maintenant)
d0c_s4vage
1

C'est loin d'être élégant, mais pendant le débogage, je me connecte souvent au Logger, puis j'utilise getLog () pour récupérer son contenu. Ensuite, soit je:

  • enregistrer les résultats dans une variable (qui peut être inspectée dans le débogueur Google Scripts - cela fonctionne dans les cas où je ne peux pas définir un point d'arrêt dans certains codes, mais je peux en définir un dans le code qui sera exécuté plus tard)
  • l'écrire dans un élément DOM temporaire
  • l'afficher dans une alerte

Essentiellement, cela devient simplement un problème de sortie JavaScript .

Il manque cruellement des fonctionnalités des console.log()implémentations modernes , mais le Logger aide toujours à déboguer les scripts Google.

Michael Scheper
la source
1

Juste comme un avis. J'ai créé une fonction de test pour ma feuille de calcul. J'utilise la variable google jette dans la fonction onEdit (e) (je l'ai appelée e). Ensuite, j'ai créé une fonction de test comme celle-ci:

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

L'appel de cette fonction de test fait exécuter tout le code comme vous aviez un événement dans la feuille de calcul. Je viens de mettre la possibilité de la cellule que j'ai éditée qui m'a donné un résultat inattendu, en définissant la valeur comme la valeur que j'ai mise dans la cellule. OBS! pour plus de variables que googles donne à la fonction, allez ici: https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events

Meltinglava
la source
0

Actuellement, vous êtes confiné à la nature liée au conteneur de l'utilisation de scripts dans les documents. Si vous créez un nouveau script à l'extérieur de la documentation, vous pourrez exporter des informations vers une feuille de calcul Google et l'utiliser comme un outil de journalisation.

Par exemple dans votre premier bloc de code

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

Lorsque je travaille avec GAS, j'ai deux moniteurs (vous pouvez utiliser deux fenêtres) configurés avec l'un contenant l'environnement GAS et l'autre contenant le SS afin que je puisse écrire des informations et me connecter.

JForgie
la source
0

La console de développement consignera les erreurs générées par le script de l'application, vous pouvez donc simplement lancer une erreur pour la consigner en tant que console.log normale. Cela arrêtera l'exécution, mais cela pourrait toujours être utile pour le débogage étape par étape.

throw Error('hello world!');

apparaîtra dans la console de la même manière que console.log('hello world')

qwerty
la source
0

déboguez simplement le code de votre feuille de calcul comme ceci:

...
throw whatAmI;
...

montre comme ça:

entrez la description de l'image ici

Toskan
la source
Je pense que vous devriez mentionner que l'image montre comment une fonction personnalisée affiche une erreur mais l'OP mentionne qu'il utilise un simple déclencheur ( onEdit)
Rubén