Logging configuration

2019-05-17 java

There is nothing fundamentally new in this article. It’s just a quick reminder (to myself) about Java logging framework configuration.

The configuration files will contain:

  • Console aka stdout output

  • Rolling file output with both date and size rolling policies. Rotating the file every day is practical because it allows to find yesterday’s failure cause easily. Rotating when the file reaches a given size allows to protect against disk flood.

  • Sample log patterns to help formating log file.

Logging libraries support multiple configuration file format: XML, Properties, YAML…​ I chose to use XML, it’s a matter of taste.

Logback

pom.xml
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <scope>runtime</scope>
        </dependency>

Logback implements SLF4J from the ground up.

logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">(1)
    <!-- Properties -->
    <property name="log.dir" value="target/log" />(2)

    <!-- Appenders -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>(3)
            <pattern>%date{HH:mm:ss.SSS} %-5level [%thread] %logger{1} - %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>blog.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${log.dir}/blog.%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <maxFileSize>10MB</maxFileSize>
            <maxHistory>10</maxHistory>
            <totalSizeCap>100MB</totalSizeCap>
        </rollingPolicy>
        <encoder>(4)
            <pattern>%date{ISO8601} %-5level [%thread] %logger - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- Loggers -->
    <logger name="com.github.gquintana.logging" level="DEBUG"/>
    <root level="DEBUG">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>
1 The debug flag enables Logback startup logs.
2 The log.dir property can be overriden at JVM (-Dlog.dir=…​) or OS level.
3 The pattern is documented in the layout section.
4 Format the date in ISO8601.

You can force Logback to use a specific configuration file using a JVM property -Dlogback.configurationFile=/path/to/config.xml.

The Logback Manual contains detailed information.

Log4J2

pom.xml
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <scope>runtime</scope>
        </dependency>

The Log4J2-SLF4J adapter is in the Log4J2 group.

log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace">(1)
    <!-- Properties -->
    <Properties>(2)
        <Property name="logDir">${sys:log.dir:-target/log}</Property>
    </Properties>

    <!-- Appenders -->
    <Appenders>
        <Console name="CONSOLE">(3)
            <PatternLayout pattern="%date{HH:mm:ss.SSS} %-5level [%thread] %logger{1} - %msg%n"/>
        </Console>
        <RollingFile name="FILE"
                     fileName="${logDir}/blog.log"
                     filePattern="${logDir}/blog.%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout>(4)
                <Pattern>%d{ISO8601} %-5level [%thread] %logger %m%n</Pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="1m" />
            </Policies>
            <Strategies>
                <DefaultRolloverStrategy max="10"/>
            </Strategies>
        </RollingFile>
    </Appenders>

    <!-- Loggers -->
    <Loggers>
        <Logger name="com.github.gquintana.logging" level="debug"/>
        <Root level="info">
            <AppenderRef ref="CONSOLE"/>
            <AppenderRef ref="FILE"/>
        </Root>
    </Loggers>
</Configuration>
1 Setting status to trace or debug shows Log4J2 internal logs.
2 The logDir property is set from JVM property (-Dlog.dir=…​) with default value. See Property substitution in documentation.
3 The PatternLayout is documented in the layout section.
4 Format the date in ISO8601.

You can tell Log4J2 to load a specific configuration file using a JVM property -Dlog4j.configurationFile=/path/to/config.xml.

The Log4J2 Manual contains extensive documentation.

Log4J1

Even if it’s deprecated, let’s end with the venerable Log4J v1 library.

pom.xml
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <scope>runtime</scope>
        </dependency>

The Log4J1-SLF4J adapter is in the SLF4J group.

log4j.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">(1)
    (2)
    <!-- Appenders -->
    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">(3)
            <param name="ConversionPattern" value="%d{HH:mm:ss.SSS} %-5p %c{1} - %m%n"/>
        </layout>
    </appender>
    <appender name="FILE" class="org.apache.log4j.RollingFileAppender">(4)
        <param name="File" value="${log.dir}/blog.log"/>
        <param name="MaxFileSize" value="10MB"/>
        <param name="MaxBackupIndex" value="10"/>
        <layout class="org.apache.log4j.PatternLayout">(5)
            <param name="ConversionPattern" value="%d{ISO8601} %-5p [%t] %c - %m%n"/>
        </layout>
    </appender>
    <!-- Loggers -->
    <root>
        <priority value="INFO"/>
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
    </root>
</log4j:configuration>
1 Like Logback, the debug flag enables Log4J1 internal logs.
2 There aren’t any properties in Log4J1.
3 The PatternLayout is documented in the JavaDoc.
4 There is no DailyRollingFileAppender in Log4J1 unless you add log4j-extras extension. Even with this extension, one can not mix size and time rollover.
5 Format the date in ISO8601.

You shouldn’t forget file:/ if you use specific configuration file with the JVM property -Dlog4j.configuration=file:///path/to/config.xml.

The Log4J1 Manual is only a quick introduction. By the time, there was a book .