[Spring Boot2] Commons logback configuration

As I did before, I’d like to extract common class/configuration into framework module, which makes developed easy to do their work and easy to modify commonly.

This time I extracted logback configuration into framework, and it will read spring boot’s properties, generate log files dynamically.

logback-spring-common.xml:

<?xml version="1.0" encoding="UTF-8"?>
<included>
    <springProperty scope="context" name="app.name" source="spring.application.name"/>
    <springProperty scope="context" name="app.log.path" source="spring.application.log-path"/>

    <contextName>${app.name}</contextName>
    <property name="default_charset" value="UTF-8"/>

    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%clr(%date){blue} - %clr([%thread]){magenta} - %clr([%-5level]){cyan} - %clr([%class.%method(line:%line)]){cyan} - %clr(%msg%n)</pattern>
            <charset>${default_charset}</charset>
        </encoder>
    </appender>

    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <append>true</append>
        <prudent>false</prudent>
        <file>${app.log.path}/${app.name}.log</file>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%date - [%thread] - [%-5level] - [%class.%method(line:%line)] - %msg%n</pattern>
            <charset>${default_charset}</charset>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${app.log.path}/${app.name}.log_%d{yyyy-MM-dd}</fileNamePattern>
            <maxHistory>15</maxHistory>
        </rollingPolicy>
    </appender>

    <appender name="json" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <append>true</append>
        <prudent>false</prudent>
        <file>${app.log.path}/${app.name}.json</file>
        <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
            <timestampFormat>yyyy-MM-dd HH:mm:ss.SSS Z</timestampFormat>
            <jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
                <prettyPrint>false</prettyPrint>
            </jsonFormatter>
            <appendLineSeparator>true</appendLineSeparator>
        </layout>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${app.log.path}/${app.name}.json_%d{yyyy-MM-dd}</fileNamePattern>
            <maxHistory>15</maxHistory>
        </rollingPolicy>
    </appender>

    <springProfile name="dev">
        <root level="INFO">
            <appender-ref ref="console"/>
        </root>
    </springProfile>

    <springProfile name="stg">
        <root level="INFO">
            <appender-ref ref="file"/>
        </root>
    </springProfile>

    <springProfile name="uat,prd">
        <root level="INFO">
            <appender-ref ref="json"/>
        </root>
    </springProfile>
</included>


I defined three appenders, console/file/json, I think it’s easy to understand use console in dev environment. In STG we used raw text to store logs, developers prefer to this, and they can find out exception easily by using grep/tail. In UAT/PRD, we used json format to store logs, and configured logstash to collect logs then send to kibana.

In application it’s very easily to configure logback, you just add framework dependency in pom.xml,

and then create logback-spring.xml as below:

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <include resource="com/xxx/xxx/api/framework/resource/logback-spring-common.xml"/>
</configuration>