记录器格式和throwable,slf4j

Chr*_*ssy 12 java logging slf4j

在将一些旧记录器转换String.format为较新的slf4j {}变体的过程中,我偶然发现了这种情况:

logger.error(String.format("%s ... %s ... %s", ...), e);
Run Code Online (Sandbox Code Playgroud)

我想只使用{}并删除String格式,但是,包含throwable的记录器方法签名是:

error(String msg, Throwable t)

所以我必须保持String.format这种情况?!

为什么没有:

error(Throwable t, String format, Object... arguments)

Mat*_* G. 20

从SLF4J 1.6.0开始,如果存在多个参数,并且如果日志语句中的最后一个参数是异常,则SLF4J将假定用户希望将最后一个参数视为异常而不是简单参数.

所以,写(在SLF4J版本1.7.x及更高版本中)

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

会做你想要实现的......

  • 一个完全错误的答案被赞成。所描述的行为与 SLF4J 无关,可能是您对记录器实现感到困惑。实际上,在 SLF4J 1.7.x 中,Logger 接口具有方法签名:“public void error(String format, Object...arguments);”,这显然与最后一个异常是否可抛出无关。留给实际的记录器实现来处理这个问题。 (3认同)
  • @AntonPryamostanov,这是一个完全正确的答案。是的,SLF4J 选择接受 Throwable 作为最后一个参数,即使对于格式化方法也是如此,这意味着 varargs 重载不能将其静态类型为 Throwable - “(String, Object..., Throwable)” 的签名是不可能的,它是一个编译器错误,因为 varargs 必须是最后一个。因此,他们显然决定不费心输入它,即使有非可变参数重载。尽管如此,有明确记录表明,如果您将 Throwable 作为最后一个参数传递,它将被视为此类参数,而不是消息格式化参数。 (3认同)
  • @AntonPryamostanov http://www.slf4j.org/faq.html#paramException (2认同)
  • @AntonPryamostanov,我实际上只是解释了没有这样的签名以及原因。 (2认同)