将Spring Boot中的日志库更改为Log4j2
如果要将Spring Boot的日志库从默认的Logback切换到log4j2,则需要保留以下配置。
自定义log4j2版本
12/11 更新:由于 log4j2 存在漏洞,追加说明了如何自定义 log4j2 版本。
...
apply(plugin = "io.spring.dependency-management")
...
extra["log4j2.version"] = "2.15.0"
...
io.spring.dependency-management プラグインを適用して SpringBoot アプリケーションの依存関係を管理しておく(多分、大体追記されている??)
spring bootのバージョンがアップデートされて log4j2 のバージョンも上がったら、extra[“log4j2.version”] = “2.15.0” は削除しないと逆に 2.15.0 に固定されてしまう
上記は Kotlin DSL の場合。Groovy なら ext[‘log4j2.version’] = ‘2.15.0’
参考链接
Spring Boot Gradle Plugin 参考指南 – 3.1.1. 自定义管理版本
依赖版本 – 2. 版本属性
升级 log4j2 的方式
调查时的版本
gradle版本为6.9
spring-boot-starter-web版本为2.5.0
spring-boot-starter-log4j2版本为2.5.0
spring-boot-starter-aop版本为2.5.0
jdk版本为liberica 11.0.11
将日志库从Logback切换到log4j2。
-
- 将spring-boot-starter-log4js添加到依赖关系中
- 从依赖关系中排除spring-boot-starter-logging
...
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-log4j2")
implementation("org.springframework.boot:spring-boot-starter-aop")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
configurations {
all {
exclude("org.springframework.boot", "spring-boot-starter-logging")
}
}
...
如果发生 LoggingException 的情况
在Maven上,有提到要在spring-boot-starter-web中排除spring-boot-starter-logging,所以我在Gradle中也按照此要求进行了描述,但在启动时却遇到了Caused by: org.apache.logging.log4j.LoggingException: log4j-slf4j-impl cannot be present withlog4j-to-slf4j的错误。
在Stack Overflow上发现需要从所有库中排除spring-boot-starter-logging,所以重写为configuration.all,切换到了log4j2。
// LogingExceptionが発生する書き方
implementation("org.springframework.boot:spring-boot-starter-web"){
exclude("org.springframework.boot","spring-boot-starter-logging")
}
// このように全ての依存関係から、spring-boot-starter-logging を除外する必要がある
configurations {
all {
exclude("org.springframework.boot", "spring-boot-starter-logging")
}
}
如果使用Gradle,可以使用模块替换功能。
通过在dependencies块内这样定义,不需要在exclude中排除,它会自动替换spring-boot-starter-logging为spring-boot-starter-log4j2所需的场景。
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")
}
}
}
将日志门面从SLF4J切换到Log4j2。
根据目前的设置,只需将日志输出从logback更改为log4j2,而日志门面仍然是slf4j。也就是说,现在已经切换到了slf4j + log4j2。如果还想将日志门面从slf4j更改为log4j2,只需更改Logger类即可。
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
// LogManagerクラスからLoggerクラスを取得する
private val logger: Logger = LogManager.getLogger(LoggingAdvice::class.java)
// SLF4J を使う場合は、LoggerFactoryを使う
//private val logger = LoggerFactory.getLogger(LoggingAdvice::class.java)
@Aspect
@Component
class LoggingAdvice {
...
}
最近的感觉是,如果使用SLF4J作为日志门面,它可以适配log4j2和logback的日志输出,所以没必要非要切换到log4j2。
log4j2 配置文件(参考)
在春季中,可以通过将 log4j2 的日志设置在 ./src/main/resources/log4j2-spring.xml 中进行配置和定制。
log4j2的配置文件可以使用YAML或JSON编写,但是从Spring中引用时,必须使用XML格式。此外,文件名必须为log4j2-spring.xml,并且没有添加’-spring’时,根据启动时的加载顺序,无法从配置文件中读取Spring的属性,因此请注意。
建议在日志配置中尽可能使用-spring变体(例如,使用logback-spring.xml而不是logback.xml)。如果使用标准的配置位置,Spring将无法完全控制日志的初始化。
以下是一个设定示例。
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%-5level}[%style{%t}{bright,blue}] %style{%C}{bright,yellow}: %m%n"/>
</Console>
<RollingFile name="RollingFile"
fileName="./logs/spring-boot-logger-log4j2.log"
filePattern="./logs/$${date:yyyy-MM}/spring-boot-log4j2-%d{-dd-MMMM-yyyy}-%i.log.gz">
<PatternLayout>
<pattern>%d %p %C [%t] %m%n</pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10 MB"/>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</configuration>
https://docs.spring.io/spring-boot/docs/3.0.3/reference/htmlsingle/#howto.logging.log4j.yaml-or-json-config
请参考以下链接。
Spring Boot的功能4.日志
Log4j 2 – 配置
(Baeldung) 在Spring Boot中进行日志记录
(stack overflow) Caused by: org.apache.logging.log4j.LoggingException: log4j-slf4j-impl不能与log4j-to-slf4j同时存在