Configuring Spring Boot to use Log4j

This article introduces you to using Log4j in Spring Boot application by showing the configuration steps you need to put in place and a sample application that uses log4j.

Spring Logging at high level

Out of the box, Spring Boot configures logging via Logback to log to the console at the level INFO. In most cases, this would be fine to manage your applications, however if you decide that you’d rather use Log4j or Log4j2, then you need to change your dependencies to include the appropriate starter for the logging implementation you want to use and to exclude Logback.
If you are using Maven to manage your builds, you can simply exclude Logback by excluding the default logging starter transitively resolved by the root starter dependency:

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

In Gradle, you can place the exclusion under the configurations section:

configurations { 
   all*.exclude group:'org.springframework.boot', module:'spring-boot-starter-logging' 
}

Having excluded the default logging starter, you can now include the starter for the logging implementation you’d rather use. With a Maven build you can add Log4j like this:

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

If you are using Gradle build, then  you can add Log4j like this:

compile("org.springframework.boot:spring-boot-starter-log4j")

If you’d rather use Log4j2, change the artifact to:

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

Is Spring Boot log4j2 starter safe against CVE-2021-44832?

If your Spring Boot version is older than v2.5.8 you are using a vulnerable version of Log4j2. To secure your application against CVE-2021-44832 we highly recommend to upgrade to the latest Spring Boot release which will pick up Log4J v2.17.0.

If you cannot upgrade to the latest Spring Boot version, you should override the log4j2 version available in Spring Boot starter. When using Spring Boot parent POM, it is sufficient to set the log4j2.version property accordingly:

<properties>
    <log4j2.version>2.17.1</log4j2.version>
</properties>

Using Log4j2 in a Spring Boot application

Right now you know how to configure Log4j2 in a Spring Boot application. In this section we will demonstrate how to use this library in an example application.

Firstly, create an application with any starter, for example with Spring Boot initializer.

Then, within your application, reference the org.apache.logging.log4j.LogManager Class to get a Logger for the current Class. Example:

import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.List;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

@Component
public class CustomerRepository {
    List<Customer> customerList = new ArrayList<Customer>();
    private static final Logger logger = LogManager.getLogger(CustomerRepository.class);
    @PostConstruct
    public void init(){

        Customer c1 = new Customer(1, "frank");
        Customer c2 = new Customer(2, "john");

        customerList.add(c1);
        logger.debug("Added Customer : {}", () -> c1);
        customerList.add(c2);
        logger.debug("Added Customer : {}", () -> c2);
    }
    public List<Customer> getData() {
        return customerList;
    }
}

When you are done with your application, add in your resources folder the Log4j2 configuration file, for example log4j2.xml file:

<Configuration status="DEBUG">
    <Appenders>
        <Console name="LogToConsole" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <File name="LogToFile" fileName="logs/application.log">
            <PatternLayout>
                <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
            </PatternLayout>
        </File>
    </Appenders>
    <Loggers>
        <Logger name="com.example.demolog4j2" level="debug" additivity="false">
            <AppenderRef ref="LogToFile"/>
            <AppenderRef ref="LogToConsole"/>
        </Logger>
        <Logger name="org.springframework.boot" level="error" additivity="false">
            <AppenderRef ref="LogToConsole"/>
        </Logger>
        <Root level="error">
            <AppenderRef ref="LogToFile"/>
            <AppenderRef ref="LogToConsole"/>
        </Root>
    </Loggers>
</Configuration>

Log4j2 without a configuration file?

Log4j has a default configuration. Therefore, if you don’t override it, it will log to the console, showing messages classified as “error” or higher.

If you run the above application using that configuration file, the start up log messages will be printed in the file logs/application.log:

spring boot log4j example

Source code: You can download the example Spring Boot with Log4j application here: https://github.com/fmarchioni/masterspringboot/tree/master/log/demo-log4j2