Log4j 2 not logging out %throwable

3.2k views Asked by At

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

1

There are 1 answers

2
Marcono1234 On BEST ANSWER

You are using Logger.error(Object). All logging methods with a single object parameter only log the toString() 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:

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

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 use Logger.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.