jsonspring-bootspring-logbackhttpexchange

Spring boot 3 and logback: Get all logs in JSON format


I want to convert all logs to JSON format. I have a Spring boot 3 application configured with Logback for logging as below:

pom.xml:

<dependency>
    <groupId>ch.qos.logback.contrib</groupId>
    <artifactId>logback-json-classic</artifactId>
    <version>0.1.5</version>
</dependency>

<dependency>
    <groupId>ch.qos.logback.contrib</groupId>
    <artifactId>logback-jackson</artifactId>
    <version>0.1.5</version>
</dependency>

logback-spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
                <timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
                <timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId>
                <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
                    <prettyPrint>true</prettyPrint>
                </jsonFormatter>
            </layout>
        </encoder>
    </appender>

    <springProfile name="local">
        <root level="DEBUG">
            <appender-ref ref="CONSOLE"/>
        </root>
    </springProfile>
</configuration>

In the output, I get RAW and JSON formatted logs alongside:

2023-07-21T14:41:24.899+02:00  INFO 34088 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
{
  "timestamp" : "2023-07-21T12:41:24.899Z",
  "level" : "INFO",
  "thread" : "SpringApplicationShutdownHook",
  "logger" : "com.zaxxer.hikari.HikariDataSource",
  "message" : "HikariPool-1 - Shutdown completed.",
  "context" : "default"
}

What should I do to get only JSON formatted logs?


Solution

  • The logback-spring.xml includes the org/springframework/boot/logging/logback/base.xml resource that configures the root logger that produces the regular logs.

    Instead of base.xml include defaults.xml in logback-spring.xml, and add configuration for root logger if local profile is not active:

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
                <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
                    <timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
                    <timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId>
                    <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
                        <prettyPrint>true</prettyPrint>
                    </jsonFormatter>
                </layout>
            </encoder>
        </appender>
    
        <springProfile name="local">
            <root level="DEBUG">
                <appender-ref ref="CONSOLE"/>
            </root>
        </springProfile>
    
        <springProfile name="!local">
            <root level="INFO">
                <appender-ref ref="CONSOLE"/>
            </root>
        </springProfile>
    </configuration>
    

    Keep in mind that base.xml contains the configuration for a file appender, which should also be added to logback-spring.xml if needed.