如何将完整的堆栈跟踪写入日志?

26

我捕获了一个异常,想要将堆栈跟踪信息写入日志中,代码如下:

log.warn(e.getMessage());

但是它所说的只有这些

null

所以我把它改成了

log.warn(e.toString());

现在它只说

java.lang.NullPointerException

我该如何将完整的堆栈跟踪信息写入日志,以便查看在应用程序中生成这个异常的位置?

6个回答

40

通常情况下:

log.warn("message", e);

但这也取决于您所使用的日志框架。


9

7
如果您使用Java 8,可以执行以下操作:
LOGGER.error("Caught exception while methodX. Please investigate: " 
    + exception 
    + Arrays.asList(exception.getStackTrace())
    .stream()
    .map(Objects::toString)
    .collect(Collectors.joining("\n"))
);

它运行得非常好,而且在调试会话期间异常未被正确记录时也非常有用。 - alexandrul
我发现上述处理比log.error("message", e)慢得多。我已经在我的调试会话中尝试过了,如果你编写全局处理程序,值得检查一下。 - Charith De Silva
3
Arrays.asList(...).stream() 可以简化为 Arrays.stream(e.getStackTrace())。 - Shadoninja

5
使用log4j,可以通过以下方式完成:
logger.error("An error occurred", exception);

第一个参数是要显示的消息,第二个参数是要记录堆栈跟踪的异常(throwable)。

另一种选择是使用commons-logging,但其用法相同:

log.error("Message", exception);

通过java.util.logging,可以进行如下操作:

logger.log(Level.SEVERE, "Message", exception);

3
在你的异常方法中,包含消息的底层字符串Stringnull
上面的答案现在被划掉了,但仍然有效,只是e不为null,但是Throwable类的detailMessage私有实例变量为null,这就是为什么e.getMessage()是字符串null,但是e.toString()(调用底层的null detailMessage.toString)会抛出NullPointerException

1
如果e为null,log.warn(e.getMessage());将会抛出异常,并且不会打印“null”。 - Peter Štibraný
不会的,它会抛出一个 NPE。 - Noel M

0
如果您使用的是 Java 8 之前的版本,您可以尝试以下方法:
            LOGGER.error("Error al recuperar proveedores de la base de datos: " + 
            e + Arrays.asList(e.getStackTrace()).stream().map(new Function(){
                    @Override
                    public Object apply(Object t) {
                        return t.toString();
                    }
                }).collect(Collectors.joining("\n")));

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