私はオンラインで見つける多くの例からは、ドキュメントここでとスタックオーバーフローは、SLF4JでCONCATENATE文字列への正しい方法は、書式設定、組み込みの文字列を使用することです。
例えば :
LOGGER.error("ExceptionHandler throws {}" , appException);
また、私はノー書式設定をしようと、それは同じ結果を生成しました:
LOGGER.error("ExceptionHandler throws " , appException);
何らかの理由で、それは私のために働いていないと私は、私が行方不明ですか分かりません。我々はオブジェクトを渡すと、私たちは、異なるフォーマットを使用していますか?
上記の例は次のログメッセージを印刷しています。
2018-07-18 02:38:19 ERROR c.a.c.c.p.ExceptionProcessor:67 - ExceptionHandler throws {}
代わりに、私は定期的な連結を使用するときに私が得ることが期待メッセージ:
LOGGER.error("ExceptionHandler throws " + appException);
OR私は手動)(.toStringを呼び出すとき
LOGGER.error("ExceptionHandler throws {}" , appException.toString());
ソナーによると、この最後のオプションは正しい理由ではありません。
printf形式の文字列は、コンパイラによって、実行時に解釈するのではなく、検証されているので、彼らは間違った文字列が作成される結果の誤差を含むことができます。java.util.Formatter、java.lang.Stringで、に、java.io.PrintStream、MessageFormatの、およびjava.ioのフォーマット(...)メソッドを呼び出すときにこのルールは、静的に、引数にprintf形式の文字列の相関関係を検証します.PrintWriterクラスとのprintf(...)に、java.io.PrintStreamまたはてjava.io.PrintWriterクラスのメソッド。
AppExceptionクラスは以下の通りであります:
import java.io.Serializable;
import javax.ws.rs.core.Response.Status;
public class AppException extends Exception implements Serializable {
private static final long serialVersionUID = 1L;
private Error error;
private Status status;
public AppException(Error error, Status status) {
this.error = error;
this.status = status;
}
public AppException() {
}
public Error getError() {
return error;
}
public void setError(Error error) {
this.error = error;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
@Override
public String toString() {
return "AppException [error=" + error + ", status=" + status + "]";
}
}
私は次のように私のロガーを構築しています:
private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionProcessor.class);
そして、私が使用しています slf4j-api 1.7.22
あなたは信じてLOGGER.error("ExceptionHandler throws {}" , appException);
呼んでいます。
error(String format, Object arg)
それは実際に呼んでいます。
error(String msg, Throwable t)
それは、引数の型のためのより良いフィット感ですので。
あなたはそれが最初のものを呼び出したい場合は、に引数をキャストObject
:
LOGGER.error("ExceptionHandler throws {}" , (Object) appException);
またはコールtoString()
あなたのような、すでに試みました。
あなたのコードを書くために良いIDEを使用していた場合は、IDEを使用すると、そのうちの把握に役立ったでしょう。あなたは、メソッド呼び出しの上にマウスを合わせるとEclipseでの例は、それが呼ばされている方法を正確にあなたが表示されます。非常に便利な場所にオーバーロードがあるとき。
私は、コードを再構築し、2つのログエントリを追加:あなたが提案しているキャストとtoStringの呼び出しと別のものを。鋳造と1が期待通りに動作していないし、私が最初に掲載結果を生産している(何もメッセージなし)
再現することはできません。ここでMCVE(使用ですorg.slf4j:slf4j-simple:1.7.25
):
Logger logger = LoggerFactory.getLogger("Test");
Exception e = new Exception("Test");
logger.error("Test 1: {}", e); // calls error(String, Throwable)
logger.error("Test 2: {}", (Object) e); // calls error(String, Object)
出力
[main] ERROR Test - Test 1: {}
java.lang.Exception: Test
at Test.main(Test.java:8)
[main] ERROR Test - Test 2: java.lang.Exception: Test
最初の呼び出しプリントメッセージそのまま(と{}
)とスタックトレース。
二コール・プリント・メッセージ{}
例外テキストで置き換えます。