How to add indentation for multiline log output

Viewed 199

I don't think, I'm the first one who wants this, but I cannot find a configuration for it.

A typical logback log output looks as follows:

2021-01-07 13:26:04,639 [MyThread] ERROR [] one.of.my.Classes - Some nice error message : java.lang.RuntimeException
java.lang.RuntimeException: null
    at one.of.my.Classes.method0(Classes:123)
    at one.of.my.Classes.method2(Classes:33)
    ...
Caused by: foo.bar.AnotherException: Blah
    at one.of.my.other.Clazz(Foo.java:693)
    ...
2021-01-07 13:26:04,639 [MyThread]  INFO [] one.of.my.Classes - Multi line info message
Second line
Third line
2021-01-07 13:26:04,639 [MyThread]  INFO [] Some other output

To make the output easier to read and also easier to process by log parsers, I'd like to add indentation for lines, which belong to another line, for example:

2021-01-07 13:26:04,639 [MyThread] ERROR [] one.of.my.Classes - Some nice error message : java.lang.RuntimeException
    java.lang.RuntimeException: null
        at one.of.my.Classes.method0(Classes:123)
        at one.of.my.Classes.method2(Classes:33)
        ...
    Caused by: foo.bar.AnotherException: Blah
        at one.of.my.other.Clazz(Foo.java:693)
        ...
2021-01-07 13:26:04,639 [MyThread]  INFO [] one.of.my.Classes - Multi line info message
    Second line
    Third line
2021-01-07 13:26:04,639 [MyThread]  INFO [] Some other output

So, how can I achieve this with logback?

1 Answers

You can implement your own custom Layout for the logger.

Layouts are logback components responsible for transforming an incoming event into a String.

It's up to you what to do with the log message. Simple example:

public class MyLayout extends LayoutBase<ILoggingEvent> {
    
    @Override
    public String doLayout(ILoggingEvent event) {
        StringBuffer sbuf = new StringBuffer(128);
        sbuf.append(event.getTimeStamp() - event.getLoggerContextVO().getBirthTime());
        sbuf.append(" ");
        sbuf.append(event.getLevel());
        sbuf.append(event.getLoggerName());
        sbuf.append(" - ");
        //few indentations for a new line
        sbuf.append(event.getFormattedMessage().replaceAll("\n", "\n  ")); 
        sbuf.append(CoreConstants.LINE_SEPARATOR);
        return sbuf.toString();
    }
}

logback.xml

<configuration>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="com.log.test.layout.MyLayout" />
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="CONSOLE"/>
    </root>

</configuration>
Related