Configure Log4j 2 Logging in Spring Boot Configure Log4j 2 Logging in Spring Boot

Page content

In this quick tutorial, we’ll configure Log4j 2 logging by replacing it with the default Logback config in the Spring Boot application.

Add Log4j 2 Dependency in Spring Boot

We need to do two things here:-

  1. Exclude default logging dependency org.springframework.boot:spring-boot-starter-logging from all the other dependencies.
  2. Add Log4j 2 org.springframework.boot:spring-boot-starter-log4j2 dependency.

The way to do this in Maven pom.xml and Gradle build.gradle is a bit different. Let’s look at the examples:-

Maven pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</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>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

Gradle build.gradle

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-log4j2'
}

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

We can also use Module replacement feature to tell Gradle that any occurrences of the default logging starter should be replaced by the Log4j 2 starter, as shown in the following example:-

dependencies {
    implementation "org.springframework.boot:spring-boot-starter-log4j2"
    modules {
        module("org.springframework.boot:spring-boot-starter-logging") {
            replacedBy("org.springframework.boot:spring-boot-starter-log4j2", "Use Log4j2 instead of Logback")
        }
    }
}

That’s it. You have replaced Logback with Log4j 2 logging framework. Spring Boot auto-configures log4j2 once it finds the jar in the classpath.


LoggingException in Project Startup

If you have configured Log4j 2 in your Spring Boot Project using Maven or Gradle and getting the following Logging Exception on application startup:-

Caused by: org.apache.logging.log4j.LoggingException: log4j-slf4j-impl cannot be present with log4j-to-slf4j

Solution: According to Spring Boot Documentation, you should exclude the spring-boot-starter-logging module from all the dependencies, not just from spring-boot-starter-web.

You should not face this issue if you have followed this tutorial for Log4j 2 configuration.

Add Log4j 2 Properties in Spring Boot

Spring boot application uses the default configuration when no configuration or property file is located in the classpath. You can provide your configuration by placing the log4j2.xml file in src/main/resources folder of your project.

📖springboot-application
  ⏷📁src
    ⏷📁main
      ⏵📁java
      ⏷📁resources
        ✅log4j2.xmlapplication.yml
  pom.xml
  build.gradle

log4j2.xml

Example of log4j2.xml configuration which prints the messages to the console and in rolling file:-

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
    <Properties>
        <Property name="LOG_PATH">target/logs</Property>
        <Property name="ROLLING_FILE_NAME">application</Property>
        <Property name="LOG_PATTERN">%clr{%d{yyyy-MM-dd HH:mm:ss.SSS}}{faint} %clr{%5p} %clr{${sys}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %msg%n%throwable
        </Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT" follow="true">
            <PatternLayout pattern="${LOG_PATTERN}"/>
        </Console>
        <RollingFile name="RollingFile" fileName="${LOG_PATH}/${ROLLING_FILE_NAME}.log"
                     filePattern="${LOG_PATH}/${ROLLING_FILE_NAME}_%d{yyyy-MM-dd}.log">
            <PatternLayout pattern="${LOG_PATTERN}"/>
            <Policies>
                <!-- Causes a rollover if the log file is older than the current JVM's start time -->
                <OnStartupTriggeringPolicy/>
                <!-- Causes a rollover once the date/time pattern no longer applies to the active file -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <!-- Causes a rollover once the size of file exceed -->
                <SizeBasedTriggeringPolicy size="10MB" />
            </Policies>
            <!-- Max 10 files will be created everyday -->
            <DefaultRolloverStrategy max="10">
                <Delete basePath="${LOG_PATH}" maxDepth="10">
                    <!-- Delete all files older than 30 days -->
                    <IfLastModified age="30d" />
                </Delete>
            </DefaultRolloverStrategy>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="INFO" additivity="false">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>
</Configuration>

Let’s test our log4j2.xml configuration by writing a JUnit test case:-

@SpringBootTest
public class Log4J2ConfigTest {

  private static final Logger log = LogManager.getLogger(Log4J2ConfigTest.class);

  @Test
  public void testLoggingLevels() {
    log.trace("Trace message is logged!");
    log.debug("Debug message is logged!");
    log.info("Info message is logged!");
    log.warn("Warning message is logged!");
    try {
      throw new RuntimeException("Unknown error");
    } catch (Exception e) {
      log.error("Error message is logged!", e);
    }
  }
}

We see the logging output is printed to the console as per the log-pattern specified in the log4j2.xml

2023-10-07 14:21:55.239  INFO 16816 --- [Test worker] c.e.d.c.Log4J2ConfigTest : Started Log4J2ConfigTest in 7.159 seconds (JVM running for 11.532)
2023-10-07 14:21:55.959 DEBUG 16816 --- [Test worker] c.e.d.c.Log4J2ConfigTest : Debug message is logged!
2023-10-07 14:21:55.960  INFO 16816 --- [Test worker] c.e.d.c.Log4J2ConfigTest : Info message is logged!
2023-10-07 14:21:55.960  WARN 16816 --- [Test worker] c.e.d.c.Log4J2ConfigTest : Warning message is logged!
2023-10-07 14:21:55.961 ERROR 16816 --- [Test worker] c.e.d.c.Log4J2ConfigTest : Error message is logged!
java.lang.RuntimeException: Unknown error