在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是不是有點智障,這么拼接系統變量的搞法很容易混淆