解決springboot 2.x集成log4j2調(diào)試日志無法關(guān)閉的問題
springboot2.x集成log4j2時,始終無法關(guān)閉log4j2自身的日志輸出
已經(jīng)做了如下配置:
在log4j2.xml的配置文件中,配置configuration的status屬性為OFF;
確認(rèn)系統(tǒng)所有地方無配置log4j2.debug;
如上配置都無法解決問題,只能從源碼著手一探究竟。
從log4j2-api包中,找到StatusLogger,其設(shè)置日志輸出level的代碼如下:
private StatusLogger(final String name,final MessageFactory messageFactory) {
super(name, messageFactory);
final String dateFormat = PROPS.getStringProperty(STATUS_DATE_FORMAT, Strings.EMPTY);
final boolean showDateTime = !Strings.isEmpty(dateFormat);
this.logger =new SimpleLogger("StatusLogger", Level.ERROR,false,true, showDateTime,false,
dateFormat, messageFactory, PROPS, System.err);
this.listenersLevel = Level.toLevel(DEFAULT_STATUS_LEVEL, Level.WARN).intLevel();
// LOG4J2-1813 if system property "log4j2.debug" is defined, print all status logging
if (isDebugPropertyEnabled()) {
logger.setLevel(Level.TRACE);
}
}
從上述代碼可以看出,level的級別默認(rèn)是設(shè)置為error,僅當(dāng)有設(shè)置log4j2.debug時,才會輸出trace日志。
那log4j2.debug屬性在哪設(shè)置的呢?帶著這個問題,尋找到了SystemPropertiesPropertySource。這個類在裝載屬性到Environment前有做自定義處理:
private static final String PREFIX ="log4j2.";
@Override
public CharSequence getNormalForm(final Iterable<?extends CharSequence> tokens) {
return PREFIX + Util.joinAsCamelCase(tokens);
}
如上述代碼所示,該操作會解釋所有系統(tǒng)屬性,然后按解析后的token自行加上log4j2.的前綴。在這里導(dǎo)致了日志系統(tǒng)認(rèn)為需要debug,進(jìn)而輸出trace日志的問題。
那系統(tǒng)屬性上的debug哪來的呢?
首先,本地進(jìn)程是以run模式啟動的,環(huán)境變量也沒有自行設(shè)置debug參數(shù),為何會有jvm啟動參數(shù)中會有 “-Ddebug” 的存在?
查看運行進(jìn)程的Configurations配置如下所示:

springboot有一個自定義配置,默認(rèn)是勾上了enable debug output。把這個去掉,再次運行發(fā)現(xiàn)-Ddebug沒有了,日志也正常了。
不過即便如此,log4j2是不是有點智障,這么拼接系統(tǒng)變量的搞法很容易混淆
springboot整合log4j2遇到的一個坑
項目中使用springboot,需要用log4j2做日志框架
問題
項目啟動報錯:Could not initialize Log4J2 logging from classpath:log4j2-dev.yml

是一個無法初始化Log4J2配置的問題,項目中采用的yml的配置文件。
前置操作
首先引入依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
去掉默認(rèn)的logback配置:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions><!-- 去掉默認(rèn)配置 -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
添加配置文件:

配置logging.config

以上是整合操作的必要配置,配置完成啟動報錯。
問題排查
根據(jù)異常信息描述,找到源碼中初始化的代碼:Log4J2LoggingSystem.loadConfiguration

繼續(xù)跟進(jìn):

發(fā)現(xiàn)是一個抽象方法,idea中使用ctrl+alt+B查找實現(xiàn)類:

因為使用的是yml,所以實現(xiàn)類應(yīng)該是YamlConfig這個,找到具體實現(xiàn):

通過debug發(fā)現(xiàn)isActive是false,所以返回null。在此類中找到isActive的含義:

這是關(guān)鍵的邏輯,原來回去檢查是否存在上面幾個依賴的類,調(diào)試返現(xiàn)沒有YAMLFactory這個類,可以看出這個類是jackson包中的,看來是少依賴了包。
解決
引入jackson-dataformat-yaml依賴:
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
啟動正常,問題解決。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java根據(jù)模板實現(xiàn)填充word內(nèi)容并轉(zhuǎn)換為pdf
這篇文章主要為大家詳細(xì)介紹了java如何根據(jù)模板實現(xiàn)填充word內(nèi)容并轉(zhuǎn)換為pdf,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-04-04
Spring通過ApplicationContext主動獲取bean的方法講解
今天小編就為大家分享一篇關(guān)于Spring通過ApplicationContext主動獲取bean的方法講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03
Java中@RequiredArgsConstructor注解的基本用法
這篇文章主要介紹了Java中@RequiredArgsConstructor注解的基本用法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-09-09
Java?Spring框架創(chuàng)建項目與Bean的存儲與讀取詳解
本篇文章將介紹Spring項目的創(chuàng)建,IDEA國內(nèi)源的配置以及Bean的存儲與讀取,所謂的Bean其實就是對象的意思,更詳細(xì)地說Spring Bean是被實例的,組裝的及被Spring 容器管理的Java對象2022-07-07
Java數(shù)據(jù)結(jié)構(gòu)之紅黑樹的實現(xiàn)方法和原理詳解
這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之紅黑樹的實現(xiàn)方法和原理,紅黑樹是一種特殊的二叉查找樹,每個結(jié)點都要儲存位表示結(jié)點的顏色,或紅或黑,本文將通過示例為大家詳細(xì)講講紅黑樹的原理及實現(xiàn),感興趣的朋友可以了解一下2024-02-02
SpringBoot中注解實現(xiàn)定時任務(wù)的兩種方式
這篇文章主要介紹了SpringBoot中注解實現(xiàn)定時任務(wù)的兩種方式,SpringBoot 定時任務(wù)是一種在SpringBoot應(yīng)用中自動執(zhí)行任務(wù)的機制,通過使用Spring框架提供的@Scheduled注解,我們可以輕松地創(chuàng)建定時任務(wù),需要的朋友可以參考下2023-10-10

