解决 SpringBoot 使用 log4j2 不能引入 SpringBoot 参数问题

解决 SpringBoot 使用 log4j2 不能引入 SpringBoot 参数问题

文章目录

  !版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。


系统环境:

  • JAVA JDK 版本: 1.8
  • SpingBoot版本: 2.5.7

参考地址:

示例地址:

一、问题描述

最近在使用 SpringBoot 框架时,尝试使用 Log4j2 替换了默认的日志框架 Logback,根据网上的说法,在 pom.xml 文件中添加如下配置即可:

 1<dependencies>
 2
 3    <!-- SpringBoot Web -->
 4    <dependency>
 5        <groupId>org.springframework.boot</groupId>
 6        <artifactId>spring-boot-starter-web</artifactId>
 7        <!--移除存在默认日志框架的 Logback 的 Longging 依赖包 -->
 8        <exclusions>
 9            <exclusion>
10                <groupId>org.springframework.boot</groupId>
11                <artifactId>spring-boot-starter-logging</artifactId>
12            </exclusion>
13        </exclusions>
14    </dependency>
15    <!-- Log4j2 Starter -->
16    <dependency>
17        <groupId>org.springframework.boot</groupId>
18        <artifactId>spring-boot-starter-log4j2</artifactId>
19    </dependency>
20
21</dependencies>

在之前使用 SpringBoot 2.x 默认的日志框架 Logback 的时候,可以配置 Logback 的 xml 文件中引用 SpringBoot 配置文件 application.yml 里面的参数,实现一个 Logback 模板,这样只需要实现一套日志模板,就可以应用在不同的项目里,根据项目配置的 SpringBoot 参数,实现日志自动配置。

在使用 Logback 框架时,我们可以在 Logback 配置文件中使用如下方式引入 SpringBoot 参数,比如引入 spring.application.name 参数的值,用法如下:

1<springProperty scope="context" name="appName" source="spring.application.name" defaultValue="defaultName" />

但是切换为 Log4j2 后,这种方式就不好使了,于是心理想着,肯定有相关解决办法,不可能切换到 log4j2 后,这么 low!

二、问题分析

经过网上查找一番,发现并没有很好的解决办法,网上文章千篇一律,最后抱着试试看的态度浏览了一遍 Log4j2 的官方文档,在浏览文档过程中,发现确实存在 Log4j2 引入 SpringBoot 配置文件参数的介绍,如下:

然后本人尝试使用这种方式,在 Log4j2 的 xml 配置文件中,添加了一行读取 SpringBoot 参数的配置,如下:

1<Properties>
2    <!--读取 SprigBoot 中的 spring.application.name 参数-->
3    <property name="applicationName" value="${spring:spring.application.name}"/>
4</Properties>

引入变量时只需要在前面添加一个 ${spring:参数名称},即可引入 SpringBoot 中的参数。

然后就开始启动测试,发现居然不生效! 于是乎就访问了 Log4j2 的 Github,发现存在一个 log4j-spring-boot 项目,进入了看下源码中的 SpringLookup 类,就知道该项目就是解决问题的关键,于是在原先的 pom.xml 中引入了这个项目,问题得到了解决。

三、解决问题

pom.xml 引入 log4j-spring-boot 依赖,解决 Log4j2 中引入 Spring 参数不生效问题,文件内容如下:

pom.xml

 1    <!-- SpringBoot Web -->
 2    <dependency>
 3        <groupId>org.springframework.boot</groupId>
 4        <artifactId>spring-boot-starter-web</artifactId>
 5        <!--移除 Logback-->
 6        <exclusions>
 7            <exclusion>
 8                <groupId>org.springframework.boot</groupId>
 9                <artifactId>spring-boot-starter-logging</artifactId>
10            </exclusion>
11        </exclusions>
12    </dependency>
13    <!-- Log4j2 Starter -->
14    <dependency>
15        <groupId>org.springframework.boot</groupId>
16        <artifactId>spring-boot-starter-log4j2</artifactId>
17    </dependency>
18    <!-- Log4j SpringBoot |- 解决引入 SpringBoot 配置文件参数问题的依赖-->
19    <dependency>
20        <groupId>org.apache.logging.log4j</groupId>
21        <artifactId>log4j-spring-boot</artifactId>
22    </dependency>

然后 Log4j2 配置文件中,引入 SpringBoot 的 spring.application.name 参数,配置文件内容如下:

log4j2-spring.xml

 1<configuration>
 2
 3    <Properties>
 4        <!--读取 SprigBoot 中的 spring.application.name 参数-->
 5        <property name="applicationName" value="${spring:spring.application.name}"/>
 6    </Properties>
 7    
 8    ......(其它配置,略)
 9
10</configuration>

四、创建示例项目

这里创建一个测试的 SpringBoot 使用 Log4j2 日志框架的示例项目,方便大家有个全面了解。

4.1 Maven 引入 Log4j2 依赖

在 Maven 的 pom.xml 文件中,引入 log4j2 相关依赖,内容如下:

pom.xml

 1<?xml version="1.0" encoding="UTF-8"?>
 2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4
 5    <parent>
 6        <groupId>org.springframework.boot</groupId>
 7        <artifactId>spring-boot-starter-parent</artifactId>
 8        <version>2.5.7</version>
 9    </parent>
10
11    <groupId>club.mydlq</groupId>
12    <artifactId>springboot-log4j2-read-example</artifactId>
13    <version>0.0.1</version>
14    <name>springboot-log4j2-read-example</name>
15    <description>springboot log4j2 example</description>
16
17    <dependencies>
18        <!-- SpringBoot Web -->
19        <dependency>
20            <groupId>org.springframework.boot</groupId>
21            <artifactId>spring-boot-starter-web</artifactId>
22            <!--移除 Logback-->
23            <exclusions>
24                <exclusion>
25                    <groupId>org.springframework.boot</groupId>
26                    <artifactId>spring-boot-starter-logging</artifactId>
27                </exclusion>
28            </exclusions>
29        </dependency>
30        <!-- Log4j2 Starter -->
31        <dependency>
32            <groupId>org.springframework.boot</groupId>
33            <artifactId>spring-boot-starter-log4j2</artifactId>
34        </dependency>
35        <!-- Log4j SpringBoot -->
36        <dependency>
37            <groupId>org.apache.logging.log4j</groupId>
38            <artifactId>log4j-spring-boot</artifactId>
39        </dependency>
40    </dependencies>
41
42    <build>
43        <plugins>
44            <plugin>
45                <groupId>org.springframework.boot</groupId>
46                <artifactId>spring-boot-maven-plugin</artifactId>
47            </plugin>
48        </plugins>
49    </build>
50
51</project>

4.2 创建 SpringBoot 配置文件

创建 SpringBoot 配置文件 application.yml,在里面添加 spring.application.name 参数,内容如下:

application.yml

1spring:
2  application:
3    name: springboot-log4j2-example

4.3 创建 Log4j2 配置文件

在 Log4j2 的 xml 配置文件 log4j2-spring.xml 中,添加一个引入 SpringBoot 的 spring.application.name 参数配置,内容如下:

log4j2-spring.xml

 1<?xml version="1.0" encoding="utf-8" ?>
 2<configuration>
 3
 4    <Properties>
 5        <!-- ===== 读取 SprigBoot 参数 ===== -->
 6        <property name="applicationName" value="${spring:spring.application.name}"/>
 7
 8        <!-- 配置日志文件、日志归档文件命名 -->
 9        <property name="FILE_PATH" value="/logs/${applicationName}.log"/>
10        <property name="FILE_PATH_ARCHIVE" value="/logs/${applicationName}_%d{yyyy-MM-dd}.%i.log.gz"/>
11
12        <!-- 配置日志输出模式 -->
13        <property name="LOG_PATTERN_CONSOLE"
14                  value="%clr{%d{yyyy-MM-dd HH:mm:ss.SSS}}{faint} %clr{%5p} %clr{${sys:PID}}{magenta} %clr{---}{faint} %clr{[%15.15t]}{faint} %clr{%-40.40c{1.}}{cyan} %clr{:}{faint} %m%n%xwEx"/>
15        <property name="LOG_PATTERN_FILE"
16                  value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%15.15t] %-40.40c{1.}: %m%n%throwable"/>
17    </Properties>
18
19    <appenders>
20        <!--CONSOLE-->
21        <console name="console" target="SYSTEM_OUT">
22            <PatternLayout pattern="${applicationName}${LOG_PATTERN_CONSOLE}" charset="UTF-8"/>
23        </console>
24
25        <!--FILE-->
26        <RollingFile name="file_info" fileName="${FILE_PATH}" filePattern="${FILE_PATH_ARCHIVE}">
27            <Filters>
28                <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
29            </Filters>
30            <PatternLayout pattern="${LOG_PATTERN_FILE}" charset="UTF-8"/>
31            <Policies>
32                <SizeBasedTriggeringPolicy size="100MB"/>
33                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
34            </Policies>
35        </RollingFile>
36    </appenders>
37
38    <Loggers>
39        <Root level="INFO" additivity="false" includeLocation="true">
40            <!--控制台-->
41            <AppenderRef ref="console"/>
42            <!--文件-->
43            <AppenderRef ref="file_info"/>
44        </Root>
45    </Loggers>
46
47</configuration>

4.4 创建 SpringBoot 启动类

创建 SpringBoot 项目启动类,内容如下:

 1import org.springframework.boot.SpringApplication;
 2import org.springframework.boot.autoconfigure.SpringBootApplication;
 3
 4@SpringBootApplication
 5public class Application {
 6
 7    public static void main(String[] args) {
 8        SpringApplication.run(Application.class, args);
 9    }
10
11}

4.5 启动项目测试日志文件的命名

进入项目所在磁盘的 /logs 目录中,可以看到新的日志文件生成,并且命名为 springboot-log4j2-example.log,说明 Log4j2 配置已经成功读取了 SpringBoot 的 spring.application.name 参数,配置有效。

推荐大家自身去试试,这样每次 Log4j2 读取 SpringBoot 参数,一个模板可以多个项目中通用~

---END---

如果本文对你有帮助,可以关注我的公众号"小豆丁技术栈"了解最新动态,顺便也请帮忙 github 点颗星哦~感谢~


  !版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。