slf4j:フォーマットされたメッセージ、オブジェクト配列、例外をログに記録する方法


275

設定されたメッセージと例外のスタックトレースの両方をログに記録する正しい方法は何ですか?

logger.error(
    "\ncontext info one two three: {} {} {}\n",
    new Object[] {"1", "2", "3"},
    new Exception("something went wrong"));

次のような出力を生成したいと思います。

context info one two three: 1 2 3
java.lang.Exception: something went wrong
stacktrace 0
stacktrace 1
stacktrace ...

slf4jバージョン1.6.1


3
slf4jが標準の%sスタイルの代わりに独自のフォーマット文字列構文を使用する理由がわかりません。迷惑です。
キー

@KeithTyler私は{}もっと好きです、味の問題...
Betlista

@KeithTyler toString()引数のメソッドは高価になる可能性があります。この構文では、各オブジェクトへの参照のみが渡さtoString()れ、特定のメッセージが実際にログに記録されている場合にのみメソッドが呼び出されます。info()ログ呼び出しで参照されるオブジェクトtoString()は、ログレベルがWARNそれ以上の場合、メソッドが呼び出されません。{}構文は、これがないことをユーザーに思い出させてくれますString.format()様操作、彼らはその目的ではなく、文字列表現を渡す必要がありますすなわち。
user149408

回答:


427

SLF4J 1.6.0以降、複数のパラメーターが存在し、ロギングステートメントの最後の引数が例外である場合、SLF4Jはユーザーが最後の引数を単純なパラメーターではなく例外として処理することを望んでいると想定します。関連するFAQエントリも参照してください。

したがって、次のように記述します(SLF4Jバージョン1.7.x以降)

 logger.error("one two three: {} {} {}", "a", "b", 
              "c", new Exception("something went wrong"));

または書き込み(SLF4Jバージョン1.6.x)

 logger.error("one two three: {} {} {}", new Object[] {"a", "b", 
              "c", new Exception("something went wrong")});

譲ります

one two three: a b c
java.lang.Exception: something went wrong
    at Example.main(Example.java:13)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at ...

正確な出力は、基になるフレームワーク(logback、log4jなど)と基になるフレームワークの構成方法によって異なります。ただし、最後のパラメーターが例外である場合、基になるフレームワークに関係なく、そのように解釈されます。


4
どの基本的なロギングフレームワークを使用していますか?上記の私の回答で述べたように、最後のパラメーターが例外である場合、基になるフレームワークに関係なく、そのように解釈されます。(logback、slf4j-log4j12、slf4j-jdk14、slf4j-simpleでテストされています。)
Ceki

3
申し訳ありませんが、あなたの例では、フォーマット文字列にn = 3のプレースホルダーを使用し、オブジェクト配列にn + 1 = 4の要素を使用していることを認識できませんでした。フォーマット文字列にn個のプレースホルダーがあり、オブジェクト配列にn個の要素があり、3番目のパラメーターとして例外がありました。私の期待は、例外がスタックトレースで出力されることでしたが、これは決して起こりませんでした。これは設計どおりに機能しますか?また、オブジェクト配列にn個のプレースホルダーとn個の要素があり、最後の要素を除いて、スタックトレースが表示されない場合。おそらく、配列内のn + 1個のオブジェクトを持つn個のプレースホルダーをもう少し強調する必要があります。
Rowe

7
私は@CekiがJavadocにないことに苦労していましたが、Javadoc Loggerクラスの先頭にあります:slf4j.org/apidocs/org/slf4j/Logger.html
Adam Gent

1
改善依頼を作成しましたので、よろしければ投票してください。
Betlista

8

@Cekiの回答に加えて、logbackを使用しており、プロジェクトに構成ファイル(通常はlogback.xml)を設定している場合は、ログを定義してスタックトレースをプロットすることもできます。

<encoder>
    <pattern>%date |%-5level| [%thread] [%file:%line] - %msg%n%ex{full}</pattern> 
</encoder>

パターン内の%exが違いを生む

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.