Spring Boot Log4j 2 example
In this tutorial, we will show you how to use Apache Log4j 2 in Spring Boot framework.
Technologies used :
- Spring Boot 2.1.2.RELEASE
- Spring 5.1.4.RELEASE
- Log4j 2.11.1
- Maven 3
- Java 8
1. Project Directory
2. Maven
The key is exclude the default logback, and include log4j with spring-boot-starter-log4j2
<?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>
<artifactId>logging-log4j2</artifactId>
<packaging>jar</packaging>
<name>Spring Boot log4j2 Example</name>
<url>https://www.mkyong.com</url>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- exclude logback , add log4j2 -->
<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>
<!-- asynchronous loggers -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.2</version>
</dependency>
<!-- for log4j2.yml, need jackson-databind and jackson-dataformat-yaml -->
<!-- spring-boot-starter-web -> spring-boot-starter-json -> jackson-databind-->
<!-- included by spring boot
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Package as an executable jar/war -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
</plugins>
</build>
</project>
Display the project dependencies.
$ mvn dependency:tree [INFO] \- org.springframework.boot:spring-boot-starter-log4j2:jar:2.1.2.RELEASE:compile [INFO] +- org.apache.logging.log4j:log4j-slf4j-impl:jar:2.11.1:compile <--- slf4j to log4j bridge [INFO] | \- org.apache.logging.log4j:log4j-api:jar:2.11.1:compile [INFO] +- org.apache.logging.log4j:log4j-core:jar:2.11.1:compile [INFO] +- org.apache.logging.log4j:log4j-jul:jar:2.11.1:compile [INFO] \- org.slf4j:jul-to-slf4j:jar:1.7.25:compile
$ mvn dependency:tree [INFO] org.springframework.boot:logging-log4j2:jar:1.0 [INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.1.2.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter-json:jar:2.1.2.RELEASE:compile [INFO] | | +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.8:compile [INFO] | | | \- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0:compile [INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.9.8:compile [INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.9.8:compile [INFO] | | \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.9.8:compile [INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.1.2.RELEASE:compile [INFO] | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.14:compile [INFO] | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.14:compile [INFO] | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.14:compile [INFO] | +- org.hibernate.validator:hibernate-validator:jar:6.0.14.Final:compile [INFO] | | +- javax.validation:validation-api:jar:2.0.1.Final:compile [INFO] | | +- org.jboss.logging:jboss-logging:jar:3.3.2.Final:compile [INFO] | | \- com.fasterxml:classmate:jar:1.4.0:compile [INFO] | +- org.springframework:spring-web:jar:5.1.4.RELEASE:compile [INFO] | | \- org.springframework:spring-beans:jar:5.1.4.RELEASE:compile [INFO] | \- org.springframework:spring-webmvc:jar:5.1.4.RELEASE:compile [INFO] | +- org.springframework:spring-aop:jar:5.1.4.RELEASE:compile [INFO] | +- org.springframework:spring-context:jar:5.1.4.RELEASE:compile [INFO] | \- org.springframework:spring-expression:jar:5.1.4.RELEASE:compile [INFO] +- org.springframework.boot:spring-boot-starter-thymeleaf:jar:2.1.2.RELEASE:compile [INFO] | +- org.thymeleaf:thymeleaf-spring5:jar:3.0.11.RELEASE:compile [INFO] | | +- org.thymeleaf:thymeleaf:jar:3.0.11.RELEASE:compile [INFO] | | | +- org.attoparser:attoparser:jar:2.0.5.RELEASE:compile [INFO] | | | \- org.unbescape:unbescape:jar:1.1.6.RELEASE:compile [INFO] | | \- org.slf4j:slf4j-api:jar:1.7.25:compile [INFO] | \- org.thymeleaf.extras:thymeleaf-extras-java8time:jar:3.0.2.RELEASE:compile [INFO] +- org.springframework.boot:spring-boot-starter:jar:2.1.2.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot:jar:2.1.2.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-autoconfigure:jar:2.1.2.RELEASE:compile [INFO] | +- javax.annotation:javax.annotation-api:jar:1.3.2:compile [INFO] | +- org.springframework:spring-core:jar:5.1.4.RELEASE:compile [INFO] | | \- org.springframework:spring-jcl:jar:5.1.4.RELEASE:compile [INFO] | \- org.yaml:snakeyaml:jar:1.23:compile [INFO] +- org.springframework.boot:spring-boot-starter-log4j2:jar:2.1.2.RELEASE:compile [INFO] | +- org.apache.logging.log4j:log4j-slf4j-impl:jar:2.11.1:compile [INFO] | | \- org.apache.logging.log4j:log4j-api:jar:2.11.1:compile [INFO] | +- org.apache.logging.log4j:log4j-core:jar:2.11.1:compile [INFO] | +- org.apache.logging.log4j:log4j-jul:jar:2.11.1:compile [INFO] | \- org.slf4j:jul-to-slf4j:jar:1.7.25:compile [INFO] +- com.lmax:disruptor:jar:3.4.2:compile [INFO] \- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:2.9.8:compile [INFO] \- com.fasterxml.jackson.core:jackson-core:jar:2.9.8:compile
3. log4j2.xml
3.1 Create a log4j2.xml in the project class path, src/resources/
<?xml version="1.0" encoding="UTF-8"?>
<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/app.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Logger name="com.mkyong" 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>
3.2 For log4j2.yml, we need to include jackson-databind and jackson-dataformat-yaml, since the jackson-databind is already included with Spring Boot Starter, so, we just need to include jackson-dataformat-yaml
<!-- spring-boot-starter-web -> spring-boot-starter-json -> jackson-databind--> <!-- included by spring boot <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> </dependency> --> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-yaml</artifactId> </dependency>
Configuration:
status: debug
appenders:
Console:
name: LogToConsole
PatternLayout:
Pattern: "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"
RollingFile:
- name: LogToRollingFile
fileName: logs/app.log
filePattern: "logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"
PatternLayout:
pattern: "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"
Policies:
SizeBasedTriggeringPolicy:
size: 10MB
DefaultRollOverStrategy:
max: 10
Loggers:
logger:
- name: com.mkyong
level: debug
additivity: false
AppenderRef:
- ref: LogToConsole
- ref: LogToRollingFile
Root:
level: error
AppenderRef:
ref: LogToConsole
4. Hello log4j2
4.1 A simple Spring MVC web application, logging with log4j2.
package com.mkyong;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Arrays;
import java.util.List;
@Controller
public class HelloController {
private static final Logger logger = LogManager.getLogger(HelloController.class);
private List<Integer> num = Arrays.asList(1, 2, 3, 4, 5);
@GetMapping("/")
public String main(Model model) {
// pre-java 8
if (logger.isDebugEnabled()) {
logger.debug("Hello from Log4j 2 - num : {}", num);
// java 8 lambda, no need to check log level
logger.debug("Hello from Log4j 2 - num : {}", () -> num);
model.addAttribute("tasks", num);
return "welcome"; //view
private int getNum() {
return 100;
4.2 Template
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head></head>
<body>
<h1>Spring Boot + log4j2 example</h1>
<ul>
<li th:each="task : ${tasks}" th:text="${task}"></li>
</ul>
</body>
</html>
5. Demo
5.1 Start Spring Boot
package com.mkyong;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class StartApplication {
public static void main(String[] args) {
SpringApplication.run(StartApplication.class, args);
http://localhost:8080
Review the logging :
19:10:08.723 [http-nio-8080-exec-1] DEBUG com.mkyong.HelloController - Hello from Log4j 2 - num : [1, 2, 3, 4, 5] 19:10:08.724 [http-nio-8080-exec-1] DEBUG com.mkyong.HelloController - Hello from Log4j 2 - num : [1, 2, 3, 4, 5]
6. Log4j 2 - Asynchronous Loggers
6.1 To enable asynchronous logging, we need to include disruptor
<dependency> <groupId>com.lmax</groupId> <artifactId>disruptor</artifactId> <version>3.4.2</version> </dependency>
6.2 Set the system property log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
$ mvn package $ java -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector -jar target/logging-log4j2-1.0.jar 019-03-27 19:28:57,185 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3 2019-03-27 19:28:57,189 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=AsyncLoggerRingBuffer 2019-03-27 19:28:57,194 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=StatusLogger 2019-03-27 19:28:57,195 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=ContextSelector 2019-03-27 19:28:57,195 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=Loggers,name=org.springframework.boot 2019-03-27 19:28:57,196 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=Loggers,name= 2019-03-27 19:28:57,196 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=Loggers,name=com.mkyong 2019-03-27 19:28:57,197 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=Appenders,name=LogToConsole 2019-03-27 19:28:57,200 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=Appenders,name=LogToFile
From:一号门
Previous:SLF4J Logback Tutorial

COMMENTS