为什么slf4j的Logger没有同时接受消息的varargs和异常的方法?

Ali*_*aka 2 java logging slf4j

SLF4J的Logger具有可以接受异常或varargs但不能同时接受两者的日志记录方法。

知道为什么吗?

缺少签名的问题在于,有时我想同时记录一个异常并为消息提供参数,但是我没有方法签名可以同时执行这两种操作。

Arn*_*aud 6

参照在异常/抛出的存在,是有可能进行参数的测井语句?,如果例外是最后一个参数,则可以从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);
}
Run Code Online (Sandbox Code Playgroud)

将按预期方式打印NumberFormatException及其堆栈跟踪。Java编译器将使用一个String和两个Object参数调用error方法。根据程序员的最大可能意图,SLF4J会将NumberFormatException实例解释为可抛出的,而不是未使用的Object参数。在1.6.0之前的SLF4J版本中,NumberFormatException实例被忽略。

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

作为示例实现,这是Logback调用的方法(此方法在类中,ch.qos.logback.classic.spi.EventArgUtil并通过调用ch.qos.logback.classic.spi.LoggingEvent):

public static final Throwable extractThrowable(Object[] argArray) {
    if (argArray == null || argArray.length == 0) {
        return null;
    }

    final Object lastEntry = argArray[argArray.length - 1];
    if (lastEntry instanceof Throwable) {
        return (Throwable) lastEntry;
    }
    return null;
}
Run Code Online (Sandbox Code Playgroud)

  • @AlikElzin-kilaka 但设计者没有这样做,因为他们希望将异常放在最后,因为当涉及到消息中的哪个标记与哪个参数相对应时,这样就不那么令人困惑了。 (2认同)