Spring Boot のロギングライブラリのデフォルトは Logback で、ファサードとして SLF4J が使われる。
これを 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 プラグインリファレンスガイド - 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 を除外(<exclusion>
)するとあったので、gradle でもそれに従って記述したが、起動時にCaused by: org.apache.logging.log4j.LoggingException: log4j-slf4j-impl cannot be present with log4j-to-slf4j
が発生してしまった。
stackoverflow にて「全てのライブラリから 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ならModule replacement が使える
exclude
で除外しなくても dependenciesブロック内で次のように定義することで、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 に切り替わったことになる。ロギングファサードもsl4jから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 {
...
}
(2023.03.29補足)
ロギングファサードは SLF4J を使った方が ログ出力はlog4j2/logbackのどちらにも対応するので、無理にlog4j2に切り替えなくても良い気がするのが最近のお気持ち
log4j2 の設定ファイル (参考)
Spring における log4j2 のロギング設定は、 ./src/main/resources/log4j2-spring.xml
に記述することでカスタマイズできる。
log4j2 の設定ファイルは YAML や JSON でも書けるが、Spring からは、XML 形式でないと参照しない模様。
また、ファイル名は log4j2-spring.xml
と、'-spring' をつけないと起動時のロード順によって 設定ファイルから Springのプロパティが読み込めないので注意する。
「4.8.カスタムログ設定」 より
可能な場合、ロギング構成に -spring バリアントを使用することをお勧めします(たとえば、logback.xml ではなく logback-spring.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>
YAMLなど XML以外のフォーマットで読み込むためには 必要なDependencyを追加すれば良さそう(動作は未確認)
参考リンク
Spring Boot の機能 4.ログ
Log4j 2 - configuration
(Baeldung) Logging in Spring Boot
(stack overflow) Caused by: org.apache.logging.log4j.LoggingException: log4j-slf4j-impl cannot be present with log4j-to-slf4j