Using Log4J2 with Spring Boot

Spring boot starter projects enable quick development boot applications.  Starter projects has a default dependency on spring-boot-starter-logging. This library configures logback as the default logging implementation. However some may prefer to use log4J2 instead of Logback to write application logs. Both works with the SLF4J facade API and hence it is possible to switch from Logback to log4j2 without changing any code.

Modify the gradle file of your spring boot project to use log4j2 instead of logback implementation,

  • Exclude the spring-boot-starter-logging dependency.
  • Add an explicit dependency on spring-boot-starter-log4j2.

Sample Gradle File to Configure Log4J2 (build.gradle)

buildscript {
    ext {
        springBootVersion = '1.5.2.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'

version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    compile('org.springframework.boot:spring-boot-starter-web') {
       exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'   
    }
    
    compile('org.springframework.boot:spring-boot-starter-log4j2')
    
    testCompile('org.springframework.boot:spring-boot-starter-test')
}

Sample POM File to Configure Log4J2 (pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.quickprogrammingtips.springboot</groupId>
    <artifactId>logdemo2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>logdemo2</name>
    <description>Spring Boot Demo</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
        <relativePath />
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Sample Spring Boot Controller Class (SLF4J Logging)

package com.quickprogrammingtips.springboot;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloWorldController {
    private static final Logger LOG = LoggerFactory.getLogger(HelloWorldController.class);

    @RequestMapping("/hello")
    @ResponseBody
    String home() {
        LOG.warn("sending hello world response...");
        return "Hello World!";
    }
}

The logging configuration in application.properties works even when you replace logback with log4j2. However if you want to fine tune log4j2 logging, you can add log4j2.xml or log4j2-spring.xml to the src/main/resources folder of your spring boot project.

Why Replace Logback with Log4J2?

Logback and log4j2 are good logging implementations designed to replace the older log4J implementation. However log4j2 has some advantages over logback,

  • Log4j2 is designed as an audit logging framework. During reconfiguration, events are retained and exceptions from appenders can be visible to the application.
  • Uses high speed asynchronous implementation. In multithreaded applications up to 10x performance compared to logback.
  • Simple and easy to use plugin system and support for message objects.
  • Advanced support for filters, custom log levels, layouts and Java 5 concurrency support.

Dependencies of Spring-boot-starter-logging

  • logback-classic - An SLF4J native logging implementation
  • jcl-over-slf4j - Apache Commons Logging implemented over SLF4J
  • jul-to-slf4j - JDK logging to SLF4J bridge
  • log4j-over-slf4j - Log4J implemented over SLF4J

Dependencies of Spring-boot-starter-log4j2

  • log4j-slf4j-impl - SLF4J logging binding of log4j2 core
  • log4j-api - Log4j2 API
  • log4j-core - Log4j2 implementation
  • jcl-over-slf4j - Apache Commons Logging implemented over SLF4J
  • jul-to-slf4j - JDK logging to SLF4J bridge