Como depurar o script do Google Apps (também conhecido como onde o Logger.log faz logon?)

129

No Planilhas Google, você pode adicionar algumas funcionalidades de script. Estou adicionando algo para o onEditevento, mas não sei dizer se está funcionando. Pelo que sei, você não pode depurar um evento ao vivo no Google Sheets, portanto, você deve fazê-lo no depurador, o que é inútil, pois o argumento do evento passado para minha onEdit()função sempre será indefinido se eu o executar no Script Editor.

Então, eu estava tentando usar o Logger.logmétodo para registrar alguns dados sempre que a onEditfunção é chamada, mas isso também parece que só funciona quando executado a partir do Script Editor. Ao executá-lo no Script Editor, posso visualizar os logs acessandoView->Logs...

Eu esperava poder ver os logs quando o evento realmente for executado, mas não consigo descobrir.

Como depuro essas coisas?

d0c_s4vage
fonte
3
A mesma questão aqui - a resposta aceita não a responde, mas fornece muitas informações erradas.
precisa saber é o seguinte
Parece que eles resolveram isso agora. Desde que você abra o Editor de scripts da sua planilha, deixe essa guia aberta quando executar o material em sua planilha. Em seguida, volte para a guia script e ela terá as informações de log.
Phreakhead #
2
tldr; copie, cole e executeLogger.log('firstLog');MailApp.sendEmail({to:'[email protected]',subject: "subject here ^_^",body: Logger.getLog()});
Coty Embry 26/05
Maby, você deve alterar a resposta aceita ou adicionar uma nota de que o Stackdriver Logging está disponível.
precisa saber é o seguinte

Respostas:

83

ATUALIZAR:

Como está escrito nesta resposta,


Logger.logenviará a você um e-mail (eventualmente) de erros que ocorreram em seus scripts ou, se você estiver executando alguma coisa Script Editor, poderá visualizar o log da última função de execução acessando View->Logs(ainda no editor de scripts). Novamente, isso mostrará apenas o que foi registrado na última função que você executou de dentroScript Editor .

O script que eu estava tentando trabalhar tinha a ver com planilhas - criei uma coisa do tipo lista de verificação de toda a planilha que classificava os itens por prioridades e afins.

Os únicos gatilhos que instalei para esse script foram os gatilhos onOpen e onEdit. Depurar o gatilho onEdit foi o mais difícil de descobrir, porque eu continuava pensando que, se eu definisse um ponto de interrupção na minha função onEdit, abrisse a planilha, editasse uma célula, que meu ponto de interrupção seria acionado. Este não é o caso.

Para simular ter editado uma célula, eu queria acabar por ter de fazer algo na planilha real embora. Tudo o que fiz foi garantir que a célula que eu queria tratar como "editada" fosse selecionada e, em seguida Script Editor, eu iria para Run->onEdit. Então meu ponto de interrupção seria atingido.

No entanto, tive que parar de usar o argumento de evento que é passado para a função onEdit - você não pode simular isso Run->onEdit. Qualquer informação que eu precisasse da planilha, como qual célula foi selecionada, etc., tive que descobrir manualmente.

Enfim, resposta longa, mas eu descobri isso eventualmente.


EDIT :

Se você quiser ver a lista de tarefas que eu fiz, você pode conferir aqui

(sim, eu sei que alguém pode editá-lo - esse é o ponto de compartilhá-lo!)

Eu esperava que isso deixasse você ver o script também. Como você não pode vê-lo, aqui está:

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
fonte
Pff, o registro será visível apenas no correio? Isso meio que torna todos esses recursos de depuração e registro inúteis, porque efetivamente não podemos usar dados reais da planilha.
MrFox
Não. Como o autor disse, o registo está disponível no log (Script Editor, Vista, Log ou Ctrl-Enter)
rainabba
9
@rainabba Sim, o log está disponível no Editor de Script. No entanto, quando um script depende do argumento do evento e o argumento do evento não está disponível no Editor de scripts, significa efetivamente que os desenvolvedores desses tipos de scripts não têm como acessar em tempo real os logs.
10244 Jeff
1
Não pude comentar antes, por isso forneci uma resposta abaixo, mas: Se você tiver o editor de scripts aberto e VOCÊ acionar um evento na planilha aberta, poderá voltar à instância do navegador do editor de scripts e ver as informações nos Logs . Funciona bem desde que você não precise testar algo em um usuário que não pode abrir o script ou em um em que não possa fazer login.
Karl_S 30/09
1
Esta resposta está desatualizada e não deve ser vista como a resposta aceita. O registro do Stackdriver está disponível e funciona como um encanto. Dê uma olhada na resposta de partes aleatórias!
precisa saber é o seguinte
34

Até onde eu sei, você não pode depurar um evento ao vivo do google docs, então você deve fazê-lo no depurador, o que é inútil, pois o argumento do evento passado para a minha função onEdit () sempre será indefinido se eu executar do Editor de scripts.

Verdadeiro - defina você mesmo o argumento do evento para depuração. Consulte Como posso testar uma função de gatilho no GAS?

Eu estava tentando usar o método Logger.log para registrar alguns dados sempre que a função onEdit é chamada, mas isso também parece que só funciona quando executado no Editor de scripts. Quando o executo a partir do Editor de scripts, posso visualizar os logs em Exibir-> Logs ...

É verdade novamente, mas há ajuda. A biblioteca BetterLog de Peter Hermann redirecionará todos os logs para uma planilha, permitindo o registro mesmo a partir do código não anexado a uma instância do editor / depurador.

Se você estiver codificando um script contido em uma planilha, por exemplo, poderá adicionar apenas uma linha na parte superior do arquivo de script, e todos os logs irão para uma planilha "Logs" na planilha. Nenhum outro código é necessário, basta usar Logger.log()como você faria normalmente:

Logger = BetterLog.useSpreadsheet();
Mogsdad
fonte
1
Desatualizado. console.log()deve ser a melhor resposta agora
TheMaster
22

Atualização de 2017: o registro do Stackdriver já está disponível para o Script do Google Apps. Na barra de menus no editor de scripts, vá View > Stackdriver Loggingpara : para visualizar ou transmitir os logs.

console.log () vai escrever DEBUGmensagens de nível

Exemplo de onEdit()log:

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

Em seguida, verifique os logs na UI do Stackdriver rotulados onEdit() Event Objectpara ver a saída

partes aleatórias
fonte
A pergunta original pergunta especificamente sobre Logger.log. Como isso é diferente do console.logque você usa? Sou muito novo nas ferramentas, apenas tentando descobrir o que é tudo.
AnnanFay
5

Um pouco hacky, mas criei uma matriz chamada "console" e, a qualquer momento, desejava enviar para a console e enviei para a matriz. Então, sempre que eu queria ver a saída real, eu apenas retornava em consolevez do que estava retornando antes.

    //return 'console' //uncomment to output console
    return "actual output";
}
woojoo666
fonte
em js console.log('smth')funciona perfeitamente, mas e no GAS?
Igor Savinkin 03/04
1
O console.log não funcionará simplesmente porque o GAS não é um script em execução na mesma página da web da sua planilha, é um script manipulado pelo mecanismo de aplicativos do Google, então você deve seguir o seu pesado depurador Logger.log ou usar um truque como o meu
woojoo666
e quanto ao seu console 'array'? Quando I just returned consolevocê produz?
Igor Savinkin
2
Desculpe, mas não expliquei muito bem, mas essencialmente as funções da planilha retornam o valor para a célula. Portanto, se você retornar seu "console", verá tudo o que registrou na célula da planilha
woojoo666
5

Se você tiver o editor de scripts aberto, verá os logs em Exibir-> Logs. Se o seu script tiver um gatilho onedit, faça uma alteração na planilha que deve disparar a função com o editor de scripts aberto em uma segunda guia. Em seguida, vá para a guia do editor de scripts e abra o log. Você verá o que sua função passar para o registrador.

Basicamente, desde que o editor de scripts esteja aberto, o evento gravará no log e o mostrará para você. Não será exibido se outra pessoa estiver no arquivo em outro lugar.

Karl_S
fonte
5

Passei por esses posts e de alguma forma acabei encontrando uma resposta simples, que estou postando aqui para aqueles que desejam soluções curtas e agradáveis:

  1. Use console.log("Hello World")no seu script.
  2. Acesse https://script.google.com/home/my e selecione seu complemento.
  3. Clique no menu de reticências em Detalhes do projeto, selecione Execuções.

insira a descrição da imagem aqui

  1. Clique no cabeçalho da execução mais recente e leia o log.

insira a descrição da imagem aqui

Benjamin
fonte
Esse é o "log do Stackdriver" básico para os scripts do Google Apps criado após abril de 2019 (que é impossível ao acessar o Google Cloud Project para projetos "automáticos" por trás dos scripts do Google Apps). Se você alterar o GCP para um projeto de Script do Google Apps, as respostas regulares ao log do Stackdriver serão aplicadas.
tehhowch
1
Só vejo execuções diretas aqui (ou seja, aquelas para as quais cliquei em "executar" no editor de scripts), mas não vejo execuções causadas por uma alteração de dados na planilha. Como depuro esses?
Cris70
Eu não tentei isso muito. Eu imaginaria que, se uma alteração na planilha acionasse uma função e a função tivesse um log, o log seria exibido. As mudanças sempre seriam induzidas pelo usuário, certo?
Benjamin
1
Sim, eu teria imaginado isso também. Infelizmente, não é isso o que acontece :-( Alterações nos dados acionam minha função, mas as mensagens console.log () não são mostradas no log do Stackdriver. Tentei adicionar um ativador de alteração, mas que invoca minha função sem parâmetros: - (
Cris70 10/01
4

Estou tendo o mesmo problema, encontrei o abaixo na web em algum lugar ....

Os manipuladores de eventos no Docs são um pouco complicados. Como os documentos podem manipular várias edições simultâneas por vários usuários, os manipuladores de eventos são tratados no lado do servidor. O principal problema dessa estrutura é que, quando um script de acionador de eventos falha, ele falha no servidor. Se você quiser ver as informações de depuração, precisará configurar um gatilho explícito no menu de gatilhos que envia por e-mail as informações de depuração quando o evento falha, ou então falha silenciosamente.

Angus Keenan
fonte
Hmm, sim, eu me deparei com isso - ele me enviou um monte de erros de meus scripts na manhã seguinte. Eu fiz acabam por descobrir isso embora (a postar minha própria resposta agora)
d0c_s4vage
1

Está longe de ser elegante, mas durante a depuração, costumo fazer logon no Logger e, em seguida, uso getLog () para buscar seu conteúdo. Então eu:

  • salve os resultados em uma variável (que pode ser inspecionada no depurador do Google Scripts - isso funciona em casos em que não consigo definir um ponto de interrupção em algum código, mas posso definir um no código que é executado posteriormente)
  • escreva-o em algum elemento DOM temporário
  • exibi-lo em um alerta

Essencialmente, ele se torna uma saída JavaScript problema de .

Falta totalmente à funcionalidade das console.log()implementações modernas , mas o Logger ainda ajuda a depurar scripts do Google.

Michael Scheper
fonte
1

Apenas como um aviso. Eu fiz uma função de teste para minha planilha. Eu uso a variável google lança na função onEdit (e) (eu chamei de e). Então eu fiz uma função de teste assim:

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

A chamada dessa função de teste faz com que todo o código seja executado como você teve um evento na planilha. Acabei de colocar a célula que editei, o que me deu um resultado inesperado, definindo valor como o valor que coloquei na célula. OBS! para obter mais variáveis, o googles fornece a função, acesse aqui: https://developers.google.com/apps-script/guides/triggers/events#google_sheets_events

Meltinglava
fonte
0

Atualmente, você está confinado à natureza vinculada ao contêiner do uso de scripts nos documentos. Se você criar um novo script fora dos documentos, poderá exportar informações para uma planilha do Google e usá-las como uma ferramenta de registro.

Por exemplo, no seu primeiro bloco de código

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

Quando estou trabalhando com o GAS, tenho dois monitores (você pode usar duas janelas) configurados com um contendo o ambiente GAS e o outro com o SS, para que eu possa gravar e registrar informações.

JForgie
fonte
0

O console de desenvolvimento registrará erros gerados pelo script do aplicativo, para que você possa gerar um erro para registrá-lo como um console.log normal. Ele interromperá a execução, mas ainda poderá ser útil para a depuração passo a passo.

throw Error('hello world!');

aparecerá no console da mesma forma que console.log('hello world')

qwerty
fonte
0

basta depurar o código da planilha assim:

...
throw whatAmI;
...

mostra assim:

insira a descrição da imagem aqui

Toskan
fonte
Eu acho que você deve mencionar que a imagem mostra como uma função personalizada mostra um erro, mas o OP menciona que ele está usando um gatilho simples ( onEdit)
Rubén