Rails:例外のスタックトレース全体をログに記録する


110

スタックトレースをログに記録する正しい方法を理解しようとしています。私はlogger.error $!、$ !. backtraceが進むべき道であると述べているこのリンクに出くわしましたが、それは私にとっては機能しませんlog_errorはそうします。ドキュメンテーションによると、railsが使用するルビーロガーは単一の引数しか受け入れないため、エラーメソッドに2番目の引数を渡すとどうなるかわかりません。

奇妙なことに(あるいはそうでないかもしれませんが)2番目の引数は、通訳の不満なしに受け入れられます。ただし、渡したものはすべて無視されます。

誰かが私が欠けているものを説明できますか?エラーの2番目の引数が何のためのものか、それを何が食べているのかについての洞察はありますか?

回答:


204

ActiveSupportのBufferedLoggerクラスのソースを見ると、2番目の引数が 'progname'であることがわかります。これは、最初の引数がnilで、ブロックを指定していないか、ブロックがtrue以外の値を返す場合にのみ使用されます。

本質的に、2番目のパラメーターを使用して追加のものを出力することはできません。

あなたがしたいことは、もっと似たものです:

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

ロギングの設定方法によっては、特定のロガーが改行を出力しないため、バックトレースの各行を繰り返し処理して個別に印刷する方がよい場合があります。その場合は、次のようにします。

begin
  raise
rescue => e
  logger.error e.message
  e.backtrace.each { |line| logger.error line }
end

5
「\ r \ n」を使用して参加し、クロスプラットフォームの互換性を維持します。
James Watkins

10
$/代わりに、クロスプラットフォーム互換にするために使用しませんか?\r\nいくつかのプラットフォームにのみ固有であるため、Rubyで処理してください。
vgoff、2015年

12
ロガーを複数回呼び出すことはスレッドセーフではないため、メッセージが分割されて読めなくなる可能性があります。ロガー自体はスレッドセーフですが。通常、メッセージを1つの文字列で結合し、ログに記録します。
モロゾフ2015

当時、ロガーはログエントリの改行をサポートしていなかったため、分割されましたが、そうです。そうです。このアプローチの制限に注意する必要があります
darkliquid

+1 @JackWatsonはスレッドセーフではないため、まったく奇妙な答えです。ここではWebアプリについて話しているため、これは重要です
EvAlex

16

これが答えです。

begin
  raise
rescue => e
  logger.error ([e.message]+e.backtrace).join($/)
end

9
句読点の減少:Rails.logger.error [e.message, *e.backtrace].join($/)
artm '15年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.