答案 0 :(得分:5)
参考In the presence of an exception/throwable, is it possible to parameterize a logging statement?,你可以这样做,因为SLF4J 1.6.0,如果异常是最后一个参数:
是的,从 SLF4J 1.6.0 开始,但在之前的版本中没有。 SLF4J API支持在出现异常时进行参数化, a ssuming异常是最后一个参数。因此,
String s = "Hello world"; try { Integer i = Integer.valueOf(s); } catch (NumberFormatException e) { logger.error("Failed to format {}", s, e); }
将按预期打印NumberFormatException及其堆栈跟踪。 java编译器将调用带有String和two的错误方法 对象参数。 SLF4J,按照程序员的最多 可能的意图,将NumberFormatException实例解释为 throwable而不是未使用的Object参数。在SLF4J版本中 在1.6.0之前,只是忽略了NumberFormatException实例。
如果异常不是最后一个参数,则将其视为a 普通对象及其堆栈跟踪将不会被打印。但是,这样的 情况不应该在实践中发生。
作为一个示例实现,这是由 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;
}
答案 1 :(得分:0)
可能的原因是varargs必须是签名中的最后一个arg,添加Object参数(用于异常)后面跟Object ...参数很复杂。根据@Berger的回答,它似乎已在版本SLF4J 1.6.0中得到解决。但是,我以不同方式解决了同样的问题。我写了一个开源库MgntUtils(可从Maven Central仓库和github获得)。其中一个实用程序是从Throwable中提取堆栈跟踪作为String。此外,该实用程序还可以过滤掉堆栈跟踪的一些不相关的部分,并使其非常简洁且易于阅读格式。因此,在这种情况下,您可以将提取的堆栈跟踪作为varargs的一部分传递给记录器。我发现它非常方便,特别是过滤堆栈跟踪。它看起来像这样:
LOGGER.error("My message {} {}", MyStringParam, TextUtils.getStacktrace(e));
以下是文章的链接,该文章介绍了如何获取库以及如何使用它:MgntUtils Open source library库附带源代码和javadoc