Java 为什么';t slf4j';s Logger有一个方法,该方法接受消息的varargs和异常?

Java 为什么';t slf4j';s Logger有一个方法,该方法接受消息的varargs和异常?,java,logging,slf4j,Java,Logging,Slf4j,具有接受异常或同时接受异常的日志记录方法 知道为什么吗 缺少签名的问题是,有时我想记录一个异常并向消息提供参数,但我没有一个方法签名来同时记录这两个异常。参考,从SLF4J 1.6.0开始,如果异常是最后一个参数,您可以这样做: 是的,从SLF4J 1.6.0开始,但不在以前的版本中。SLF4J API支持在出现异常时进行参数化, 假设异常是最后一个参数。因此, String s = "Hello world"; try { Integer i = Integer.valueOf(s)

具有接受异常或同时接受异常的日志记录方法

知道为什么吗

缺少签名的问题是,有时我想记录一个异常并向消息提供参数,但我没有一个方法签名来同时记录这两个异常。

参考,从SLF4J 1.6.0开始,如果异常是最后一个参数,您可以这样做:

是的,从SLF4J 1.6.0开始,但不在以前的版本中。SLF4J API支持在出现异常时进行参数化, 假设异常是最后一个参数。因此,

String s = "Hello world";

try {
    Integer i = Integer.valueOf(s);
} catch (NumberFormatException e) {
    logger.error("Failed to format {}", s, e);
}
将按预期打印NumberFormatException及其堆栈跟踪。 java编译器将调用错误方法,使用一个字符串和两个字符串 对象参数。SLF4J,符合程序员的最新要求 可能的意图,将NumberFormatException实例解释为 可丢弃,而不是未使用的对象参数。在SLF4J版本中 在1.6.0之前,NumberFormatException实例被忽略

如果异常不是最后一个参数,它将被视为 将不打印普通对象及其堆栈跟踪。但是, 在实践中不应出现这种情况

作为一个示例实现,这是由Logback调用的方法(此方法位于类
ch.qos.Logback.classic.spi.EventArgUtil
中,并由
ch.qos.Logback.classic.spi.LoggingEvent
调用):


可能的原因是varargs必须是签名中的最后一个arg,并且在Object之后添加一个Object参数(用于异常)非常复杂。。。参数根据@Berger的回答,该问题似乎已在SLF4J 1.6.0版中解决。然而,我以不同的方式解决了同样的问题。我编写了一个开源库MgntUtils(可从Maven Central repository和github获得)。其中一个实用程序是将stacktrace作为字符串从Throwable中提取出来。此外,该实用程序还可以选择性地过滤掉stacktrace中一些不相关的部分,并使其格式非常简洁易读。因此,在本例中,您可以将提取的stacktrace作为varargs的一部分传递给记录器。我发现使用过滤stacktrace非常方便。它看起来是这样的:

LOGGER.error("My message {} {}", MyStringParam, TextUtils.getStacktrace(e));

下面是文章的链接,它解释了从哪里获取库以及如何使用库:库附带了源代码,javadoc

在varargs中将异常作为参数传递是否有点混乱?另外,如果我想将异常作为实际参数传递给消息,该怎么办。我需要记住
toString()
getMessage()
。令人困惑且容易出错。当然这可能容易出错,但这仍然是该功能当前的实现方式。在方法签名中,异常可能在消息之前设置。它本来是向后兼容的,并且仍然有一个显式的异常参数。@AlikElzin kilaka,但设计者没有这样做,因为他们希望异常是最后一个,因为这样在消息中的哪个标记与哪个参数相对应时就不那么混乱了。
LOGGER.error("My message {} {}", MyStringParam, TextUtils.getStacktrace(e));