pera.coyote
pera.coyote

Reputation: 61

Different stack trace format in exception and logger

My exception's stack trace is printed differently if I use exception.printStackTrace() or if I use logger.error("message", exception). For example, I have exception:

public class TestException extends RuntimeException{

    private int status;

    public TestException(String message, int status) {
        super(message);
        this.status = status;
    }

    public TestException(String message, Throwable cause, int status) {
        super(message, cause);
        this.status = status;
    }

    @Override
    public String toString() {
        return super.toString() + ", status=" + status;
    }
}

As you can see I have overridden toString method that prints my exception status.

In main method I created two TestException's, one is cause of another:

public static void main(String[] args) {
    TestException innerException = new TestException("some inner test", 1);
    TestException exception = new TestException("some text", innerException, 2);

    exception.printStackTrace();
    LOGGER.error(exception.toString(), exception);
}

After running this, exception.printStackTrace() prints:

test.App$TestException: some text, status=2
    at test.App.main(App.java:66)
Caused by: test.App$TestException: some inner test, status=1
    at test.App.main(ErrorHandler.java:65)

As you can see, printStackTrace use my exception's toString method and writes exception status, but LOGGER.error prints without it:

    11:44:17.153 [main] ERROR test.App - test.App$TestException: some text, status=2
test.App$TestException: some text
    at test.App.main(App.java:66) [classes/:?]
Caused by: test.App$TestException: some inner test
    at test.App.main(App.java:65) ~[classes/:?]

How can I configure my logger to use my exceptions toString method when printing stack trace, same as exception.printStackTrace()?

I'm using log4j2, default spring boot 2.1.3 configuration.

Upvotes: 1

Views: 1449

Answers (1)

Mohsen
Mohsen

Reputation: 4643

Spring Boot automatically configures Log4j if it finds a file named log4j2.xml or log4j2.json or log4j2.yaml in the classpath.

You can configure the file with your own pattern. You can find patterns here https://logging.apache.org/log4j/2.x/manual/layouts.html

This is a sample log4j2.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
    <Properties>
        <Property name="LOG_PATTERN">
            %d{yyyy-MM-dd HH:mm:ss.SSS} %5p ${hostName} --- [%15.15t] %-40.40c{1.} : %m%n%ex
        </Property>
    </Properties>
    <Appenders>
        <Console name="ConsoleAppender" target="SYSTEM_OUT" follow="true">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="com.example.log4j2demo" level="debug" additivity="false">
            <AppenderRef ref="ConsoleAppender" />
        </Logger>

        <Root level="info">
            <AppenderRef ref="ConsoleAppender" />
        </Root>
    </Loggers>
</Configuration>

Upvotes: 1

Related Questions