I want to print the stack trace when logging errors using this basic 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>
This is all I have in my dependencies:
<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>
When I run this (asdf doesn't exist):
public class Main {
public static void main(String[] args) {
Logger logger = LogManager.getLogger();
try {
new FileInputStream("asdf");
} catch(Exception e) {
logger.error(e);
}
}
}
my output is
throwable:
and I want something like this:
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)
documentation from PatternLayout at: https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout default (%throwable) should log the entire stack trace
Any help would be great!
Edit: I am using Java 8
You are using
Logger.error(Object)
. All logging methods with a single object parameter only log thetoString()
value of that object, even if it is a Throwable. In your case the appender pattern does not contain%m
/%msg
/%message
so you are only seeing "throwable:" in the console output.If we add the message to the pattern the output is:
This is a pretty common pitfall when using Log4j2 and sadly it appears this won't change in the future.
To properly log the exception and its stack trace you can either use one of the logging methods with separate
Throwable
parameter, e.g.Logger.error(String, Throwable)
, or you can useLogger.catching(Level, Throwable)
. However, the logging methods with message parameter should be preferred since they allow you to describe the context. Otherwise you might have a hard time finding out where the log message was actually created.