Rails: registrando todo o rastreamento de pilha de uma exceção

110

Tenho tentado descobrir a maneira certa de registrar um rastreamento de pilha. Me deparei com este link que afirma que logger.error $ !, $ !. backtrace é o caminho a percorrer, mas isso não funciona para mim log_error, sim. De acordo com a documentação, não vejo como passar um segundo argumento para o método de erro funcionaria de qualquer maneira, porque o logger de ruby ​​que o rails usa aceita apenas um único argumento.

Estranhamente (ou talvez não), o segundo argumento é aceito sem reclamações do intérprete. No entanto, tudo o que eu passo a ele é ignorado.

Alguém pode explicar o que estou perdendo? Qualquer insight sobre para que serve o segundo argumento do erro e o que o está causando?

Moiz Raja
fonte

Respostas:

204

Se você olhar a fonte da classe BufferedLogger em ActiveSupport, verá que o segundo argumento é 'progname'. Isso é usado somente quando o primeiro argumento é nulo e você não forneceu nenhum bloco ou o bloco retorna um valor não verdadeiro.

Em essência, você não pode usar o segundo parâmetro para produzir coisas adicionais.

O que você quer fazer é algo mais parecido com:

begin
  raise
rescue => e
  logger.error e.message
  logger.error e.backtrace.join("\n")
end

Dependendo de como você configurou o registro, pode ser melhor iterar em cada linha do backtrace e imprimi-lo separadamente, já que certos registradores não geram novas linhas, caso em que você faria algo como:

begin
  raise
rescue => e
  logger.error e.message
  e.backtrace.each { |line| logger.error line }
end
líquido escuro
fonte
5
Gostaria de entrar usando "\ r \ n" para manter a compatibilidade entre plataformas.
James Watkins
10
Você não usaria $/, em vez disso, para ser compatível com várias plataformas? Deixe Ruby cuidar disso, pois \r\né específico apenas para algumas plataformas.
vgoff
12
Você pode obter sua mensagem dividida e ilegível porque chamar o logger várias vezes não é thread-safe. Enquanto o próprio logger é thread-safe. Normalmente, eu uno minha mensagem em uma string e a registro.
Morozov
Na época, o logger não parecia suportar novas linhas nas entradas de log, daí a divisão, mas sim, você está certo e deve estar ciente das limitações desta abordagem
darkliquid
+1 @JackWatson resposta absolutamente estranha porque não é thread-safe. É importante porque estamos falando de aplicativos da web aqui
EvAlex
16

Esta é a resposta.

begin
  raise
rescue => e
  logger.error ([e.message]+e.backtrace).join($/)
end
Kuboon
fonte
9
menos pontuação:Rails.logger.error [e.message, *e.backtrace].join($/)
artm