解决 SpringBoot 使用 log4j2 不能引入 SpringBoot 参数问题
系统环境:
- JAVA JDK 版本: 1.8
- SpringBoot版本: 2.5.7
参考地址:
示例地址:
一、问题描述
最近在使用 SpringBoot 框架时,尝试使用 Log4j2 替换了默认的日志框架 Logback,根据网上的说法,在 pom.xml 文件中添加如下配置即可:
<dependencies>
<!-- SpringBoot Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!--移除存在默认日志框架的 Logback 的 Longging 依赖包 --> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- Log4j2 Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
</dependencies>在之前使用 SpringBoot 2.x 默认的日志框架 Logback 的时候,可以配置 Logback 的 xml 文件中引用 SpringBoot 配置文件 application.yml 里面的参数,实现一个 Logback 模板,这样只需要实现一套日志模板,就可以应用在不同的项目里,根据项目配置的 SpringBoot 参数,实现日志自动配置。
在使用 Logback 框架时,我们可以在 Logback 配置文件中使用如下方式引入 SpringBoot 参数,比如引入 spring.application.name 参数的值,用法如下:
<springProperty scope="context" name="appName" source="spring.application.name" defaultValue="defaultName" />但是切换为 Log4j2 后,这种方式就不好使了,于是心理想着,肯定有相关解决办法,不可能切换到 log4j2 后,这么 low!
二、问题分析
经过网上查找一番,发现并没有很好的解决办法,网上文章千篇一律,最后抱着试试看的态度浏览了一遍 Log4j2 的官方文档,在浏览文档过程中,发现确实存在 Log4j2 引入 SpringBoot 配置文件参数的介绍,如下:

然后本人尝试使用这种方式,在 Log4j2 的 xml 配置文件中,添加了一行读取 SpringBoot 参数的配置,如下:
<Properties> <!--读取 SprigBoot 中的 spring.application.name 参数--> <property name="applicationName" value="${spring:spring.application.name}"/></Properties>引入变量时只需要在前面添加一个 ${spring:参数名称},即可引入 SpringBoot 中的参数。
然后就开始启动测试,发现居然不生效! 于是乎就访问了 Log4j2 的 Github,发现存在一个 log4j-spring-boot 项目,进入了看下源码中的 SpringLookup 类,就知道该项目就是解决问题的关键,于是在原先的 pom.xml 中引入了这个项目,问题得到了解决。
三、解决问题
在 pom.xml 引入 log4j-spring-boot 依赖,解决 Log4j2 中引入 Spring 参数不生效问题,文件内容如下:
pom.xml
<!-- SpringBoot Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!--移除 Logback--> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- Log4j2 Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <!-- Log4j SpringBoot |- 解决引入 SpringBoot 配置文件参数问题的依赖--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-spring-boot</artifactId> </dependency>然后 Log4j2 配置文件中,引入 SpringBoot 的 spring.application.name 参数,配置文件内容如下:
log4j2-spring.xml
<configuration>
<Properties> <!--读取 SprigBoot 中的 spring.application.name 参数--> <property name="applicationName" value="${spring:spring.application.name}"/> </Properties>
......(其它配置,略)
</configuration>四、创建示例项目
这里创建一个测试的 SpringBoot 使用 Log4j2 日志框架的示例项目,方便大家有个全面了解。
4.1 Maven 引入 Log4j2 依赖
在 Maven 的 pom.xml 文件中,引入 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">
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.7</version> </parent>
<groupId>club.mydlq</groupId> <artifactId>springboot-log4j2-read-example</artifactId> <version>0.0.1</version> <name>springboot-log4j2-read-example</name> <description>springboot log4j2 example</description>
<dependencies> <!-- SpringBoot Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!--移除 Logback--> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <!-- Log4j2 Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> <!-- Log4j SpringBoot --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-spring-boot</artifactId> </dependency> </dependencies>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
</project>4.2 创建 SpringBoot 配置文件
创建 SpringBoot 配置文件 application.yml,在里面添加 spring.application.name 参数,内容如下:
application.yml
spring: application: name: springboot-log4j2-example4.3 创建 Log4j2 配置文件
在 Log4j2 的 xml 配置文件 log4j2-spring.xml 中,添加一个引入 SpringBoot 的 spring.application.name 参数配置,内容如下:
log4j2-spring.xml
<?xml version="1.0" encoding="utf-8" ?><configuration>
<Properties> <!-- ===== 读取 SprigBoot 参数 ===== --> <property name="applicationName" value="${spring:spring.application.name}"/>
<!-- 配置日志文件、日志归档文件命名 --> <property name="FILE_PATH" value="/logs/${applicationName}.log"/> <property name="FILE_PATH_ARCHIVE" value="/logs/${applicationName}_%d{yyyy-MM-dd}.%i.log.gz"/>
<!-- 配置日志输出模式 --> <property name="LOG_PATTERN_CONSOLE" 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"/> <property name="LOG_PATTERN_FILE" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%15.15t] %-40.40c{1.}: %m%n%throwable"/> </Properties>
<appenders> <!--CONSOLE--> <console name="console" target="SYSTEM_OUT"> <PatternLayout pattern="${applicationName}${LOG_PATTERN_CONSOLE}" charset="UTF-8"/> </console>
<!--FILE--> <RollingFile name="file_info" fileName="${FILE_PATH}" filePattern="${FILE_PATH_ARCHIVE}"> <Filters> <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/> </Filters> <PatternLayout pattern="${LOG_PATTERN_FILE}" charset="UTF-8"/> <Policies> <SizeBasedTriggeringPolicy size="100MB"/> <TimeBasedTriggeringPolicy interval="1" modulate="true"/> </Policies> </RollingFile> </appenders>
<Loggers> <Root level="INFO" additivity="false" includeLocation="true"> <!--控制台--> <AppenderRef ref="console"/> <!--文件--> <AppenderRef ref="file_info"/> </Root> </Loggers>
</configuration>4.4 创建 SpringBoot 启动类
创建 SpringBoot 项目启动类,内容如下:
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplicationpublic class Application {
public static void main(String[] args) { SpringApplication.run(Application.class, args); }
}4.5 启动项目测试日志文件的命名
进入项目所在磁盘的 /logs 目录中,可以看到新的日志文件生成,并且命名为 springboot-log4j2-example.log,说明 Log4j2 配置已经成功读取了 SpringBoot 的 spring.application.name 参数,配置有效。
推荐大家自身去试试,这样每次 Log4j2 读取 SpringBoot 参数,一个模板可以多个项目中通用~
