日志格式和可抛出对象,slf4j,参数

23
在将一些旧的记录器从 String.format 转换为较新的 slf4j {} 变量的过程中,我遇到了这种情况:
logger.error(String.format("%s ... %s ... %s", ...), e);

我想只使用{}并删除String格式,但是包含throwable的logger方法签名是: error(String msg, Throwable t) 所以在这种情况下我必须保留String.format吗?!
为什么没有这个呢: error(Throwable t, String format, Object... arguments)

2
嗯,实际上这里有一个重复的问题:https://dev59.com/DGw15IYBdhLWcg3w0fOh,但它在标题中使用了不同的关键词...也许我的问题会帮助其他人谷歌搜索。 - Christophe Roussy
@jmehrens,就是我在你上面评论中发布的链接。 - Christophe Roussy
关闭重复问题的投票将自动发布一个带有重复链接的评论... - jmehrens
1
@ChristopheRoussy 这是在“org.slf4j logger如何使用throwable格式化”的搜索字符串中谷歌搜索结果的第一项,谢谢! - Betlista
1个回答

41

从SLF4J 1.6.0版本开始,当存在多个参数且日志语句中的最后一个参数是异常时,SLF4J会认为用户想要将最后一个参数作为异常而不是简单参数。

因此,在编写代码时(在SLF4J 1.6.x及更高版本中),

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

http://www.slf4j.org/faq.html#paramException:

"从 SLF4J 1.6.0 开始支持参数化异常,之前的版本不支持。SLF4J API 支持在存在异常的情况下进行参数化,假设异常是最后一个参数。"


好的,所以它在幕后是智能的 :) - Christophe Roussy
5
一个完全错误的答案被点赞了。所描述的行为与SLF4J无关,可能是您的日志记录实现引起的混淆。实际上,在SLF4J 1.7.x中,Logger接口具有以下方法签名: public void error(String format, Object... arguments); 显然与最后一个异常是否为Throwable无关。这留给实际的日志记录实现来处理。 - Anton Pryamostanov
2
@AntonPryamostanov http://www.slf4j.org/faq.html#paramException @AntonPryamostanov http://www.slf4j.org/faq.html#paramException - Christophe Roussy
6
@AntonPryamostanov,这是完全正确的答案。是的,SLF4J选择即使对于格式化方法也将Throwable作为最后一个参数接受,这意味着可变参数重载无法将其静态类型化为Throwable——(String,Object ...,Throwable)的签名是不可能的,这是编译器错误,因为可变参数必须是最后一个。因此,他们显然决定即使是非可变参数的重载也不会费心去打字。尽管如此,文档明确指出,如果您将Throwable作为最后一个参数传递,它将被视为Throwable而不是消息格式化参数。 - Vsevolod Golovanov
2
@AntonPryamostanov,我刚刚明确解释了为什么没有这样的签名。 - Vsevolod Golovanov
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接