2011-06-16 58 views
196

記錄填充消息和異常堆棧跟蹤的正確方法是什麼?slf4j:如何記錄格式化的消息,對象數組,異常

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

回答

302

作爲SLF4J 1.6.0的,在多個參數的存在,並且如果日誌語句中的最後一個參數是一個異常,那麼SLF4J將假定用戶希望將最後一個參數視爲異常而不是簡單參數。另見relevant FAQ entry

所以,寫(在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等)以及底層框架的配置方式。然而,如果最後一個參數是一個異常,它將被解釋爲無論底層框架如何。

+0

我試過1.6.1,輸出如下所示。請注意,堆棧跟蹤丟失: ' 2011-06-16 17:20:57,570 DEBUG [main] SLF4JDemo.main(12): 上下文信息一二三:1 2 3 java.lang.Exception:something出錯了' – rowe 2011-06-16 15:22:58

+4

您正在使用哪種基礎日誌記錄框架?正如我在上面的回答中所提到的,如果最後一個參數是一個異常,它將被解釋爲無論底層框架如何。 (測試了logback,slf4j-log4j12,slf4j-jdk14和slf4j-simple。) – Ceki 2011-06-20 10:37:08

+3

對不起,我沒有意識到在你的例子中你在對象數組中使用了n = 3的格式字符串佔位符和n + 1 = 4個元素。我在格式化字符串中有n個佔位符,並且在對象數組中還有n個元素,並將異常作爲第三個參數。我的期望是,這個例外將被打印stacktrace,但這從來沒有發生過。這是否按設計工作?另外,如果我在對象數組中有n個佔位符和n個元素,而最後一個元素是異常,我沒有看到任何堆棧跟蹤。也許在數組中有n + 1個對象的n個佔位符應該更強調一點。 – rowe 2011-06-22 13:19:00

4

除了@Ceki的答案,如果你使用的logback和設置配置文件在您的項目(通常logback.xml),你可以定義日誌繪製堆棧跟蹤使用

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

模式中的%ex是什麼使得差異