slf4j:如何记录格式化的消息,对象数组,异常


274

记录填充的消息和异常的堆栈跟踪的正确方法是什么?

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

Answers:


426

从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个元素,外加一个异常作为第三个参数。我的期望是该异常将与stacktrace一起打印,但这从未发生。这按设计工作吗?另外,如果我在对象数组中有n个占位符和n个元素,但最后一个元素是例外,则看不到任何堆栈跟踪。也许应该更加强调数组中具有n + 1个对象的n个占位符。
Rowe 2011年

7
我要给@Ceki一个困难的时机,因为它不在Javadocs中,而是在Loggerjavadoc类的顶部: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是什么与众不同

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.