解決springboot 2.x集成log4j2調試日志無法關閉的問題
springboot2.x集成log4j2時,始終無法關閉log4j2自身的日志輸出
已經做瞭如下配置:
在log4j2.xml的配置文件中,配置configuration的status屬性為OFF;
確認系統所有地方無配置log4j2.debug;
如上配置都無法解決問題,隻能從源碼著手一探究竟。
從log4j2-api包中,找到StatusLogger,其設置日志輸出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的級別默認是設置為error,僅當有設置log4j2.debug時,才會輸出trace日志。
那log4j2.debug屬性在哪設置的呢?帶著這個問題,尋找到瞭SystemPropertiesPropertySource。這個類在裝載屬性到Environment前有做自定義處理:
private static final String PREFIX ="log4j2."; @Override public CharSequence getNormalForm(final Iterable<?extends CharSequence> tokens) { return PREFIX + Util.joinAsCamelCase(tokens); }
如上述代碼所示,該操作會解釋所有系統屬性,然後按解析後的token自行加上log4j2.的前綴。在這裡導致瞭日志系統認為需要debug,進而輸出trace日志的問題。
那系統屬性上的debug哪來的呢?
首先,本地進程是以run模式啟動的,環境變量也沒有自行設置debug參數,為何會有jvm啟動參數中會有 “-Ddebug” 的存在?
查看運行進程的Configurations配置如下所示:
springboot有一個自定義配置,默認是勾上瞭enable debug output。把這個去掉,再次運行發現-Ddebug沒有瞭,日志也正常瞭。
不過即便如此,log4j2是不是有點智障,這麼拼接系統變量的搞法很容易混淆
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>
去掉默認的logback配置:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions><!-- 去掉默認配置 --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency>
添加配置文件:
配置logging.config
以上是整合操作的必要配置,配置完成啟動報錯。
問題排查
根據異常信息描述,找到源碼中初始化的代碼:Log4J2LoggingSystem.loadConfiguration
繼續跟進:
發現是一個抽象方法,idea中使用ctrl+alt+B查找實現類:
因為使用的是yml,所以實現類應該是YamlConfig這個,找到具體實現:
通過debug發現isActive是false,所以返回null。在此類中找到isActive的含義:
這是關鍵的邏輯,原來回去檢查是否存在上面幾個依賴的類,調試返現沒有YAMLFactory這個類,可以看出這個類是jackson包中的,看來是少依賴瞭包。
解決
引入jackson-dataformat-yaml依賴:
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-yaml</artifactId> </dependency>
啟動正常,問題解決。
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- springboot2.x隻需兩步快速整合log4j2的方法
- springboot log4j2不能打印框架錯誤日志的解決方案
- SpringBoot整合log4j2日志的實現
- 聊聊maven的pom.xml中的exclusions標簽的作用
- spring boot整合log4j2及MQ消費處理系統日志示例