1

我想在使用这个基本的 Log4j log4j2.xml 记录错误时打印堆栈跟踪:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="throwable: %throwable"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="error">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

这就是我的依赖项中的所有内容:

    <dependencies>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.13.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.3</version>
        </dependency>
    </dependencies>

当我运行它时(asdf 不存在):

public class Main {
    public static void main(String[] args) {
        Logger logger = LogManager.getLogger();
        try {
            new FileInputStream("asdf");
        } catch(Exception e) {
            logger.error(e);
        }
    }
}

我的输出是

throwable: 

我想要这样的东西:

throwable: java.io.FileNotFoundException: asdf (No such file or directory)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(FileInputStream.java:195)
    at java.io.FileInputStream.<init>(FileInputStream.java:138)
    at java.io.FileInputStream.<init>(FileInputStream.java:93)
    at Main.main(Main.java:10)

PatternLayout 的文档位于:https ://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout default (%throwable) 应该记录整个堆栈跟踪

任何帮助都会很棒!

编辑:我正在使用 Java 8

4

1 回答 1

1

您正在使用Logger.error(Object). 所有具有单个对象参数的日志记录方法仅记录该toString()对象的值,即使它是 Throwable。在您的情况下,appender 模式不包含%m//所以您只能在控制台输出中看到“throwable:”。 如果我们将消息添加到模式中,则输出为:%msg%message

throwable: java.io.FileNotFoundException: asdf (The system cannot find the file specified) 

在使用 Log4j2 时,这是一个很常见的陷阱,遗憾的是,这似乎在未来不会改变

要正确记录异常及其堆栈跟踪,您可以使用其中一种带有单独Throwable参数的记录方法,例如Logger.error(String, Throwable),或者您可以使用Logger.catching(Level, Throwable). 但是,应该首选带有消息参数的日志记录方法,因为它们允许您描述上下文。否则,您可能很难找出日志消息的实际创建位置。

于 2020-09-03T20:35:38.893 回答