從一個log4j2的xml配置說起
對于做后端的同學(xué)來說陨倡,log是分析bug瞎嬉、查找問題不可或缺的工具敦姻,好的日志配置將使我們的開發(fā)工作如虎添翼社搅。 把視線聚焦到j(luò)ava蝇狼,常用的日志工具有l(wèi)og4j谅猾,log4j2以及l(fā)ogback等领斥,其中l(wèi)og4j2功能較為強(qiáng)大映九,運行效率也較高梦湘,我們就來用一個例子看一看log4j2的配置思路,下面就是這個配置文件:
<Configuration status="WARN" monitorInterval="30">
<Properties>
<Property name="instance">$${sys:instance}</Property>
<Property name="log.dir">$${sys:logdir}</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="[%date{yyyy-MM-dd HH:mm:ss.SSS}][%thread][%level][%class][%line]:%message%n"/>
</Console>
<RollingRandomAccessFile name="infoLog" fileName="${log.dir}/${instance}-info.log"
filePattern="${log.dir}/%d{yyyy-MM}/${instance}-info-%d{yyyy-MM-dd}-%i.log.gz"
append="true">
<PatternLayout
pattern="[%date{yyyy-MM-dd HH:mm:ss.SSS}][%thread][%level][%class][%line]:%message%n"/>
<Filters>
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
</Filters>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
</RollingRandomAccessFile>
<RollingRandomAccessFile name="warnLog" fileName="${log.dir}/${instance}-warn.log"
filePattern="${log.dir}/%d{yyyy-MM}/${instance}-warn-%d{yyyy-MM-dd}-%i.log.gz"
append="true">
<Filters>
<ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout
pattern="[%date{yyyy-MM-dd HH:mm:ss.SSS}][%thread][%level][%class][%line]:%message%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
</RollingRandomAccessFile>
<RollingRandomAccessFile name="errorLog" fileName="${log.dir}/${instance}-error.log"
filePattern="${log.dir}/%d{yyyy-MM}/${instance}-error-%d{yyyy-MM-dd}-%i.log.gz"
append="true">
<Filters>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
<PatternLayout
pattern="[%date{yyyy-MM-dd HH:mm:ss.SSS}][%thread][%level][%class][%line]:%message%n"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="20 MB"/>
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<!-- 第三方的軟件日志級別 -->
<logger name="org.springframework" level="info" additivity="true">
<AppenderRef ref="warnLog"/>
<AppenderRef ref="errorLog"/>
</logger>
<logger name="java.sql.PreparedStatement" level="debug" additivity="true">
<AppenderRef ref="Console"/>
</logger>
<!-- root logger 配置 -->
<Root level="info" includeLocation="true">
<AppenderRef ref="infoLog"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
什么是status和monitorInterval
我們看到,Configuration有2個屬性status和monitorInterval捌议,它們分別是log4j2自身組件的日志級別以及重新刷新配置文件的時間哼拔,通過配置status可以看到log4j2相關(guān)的日志,配置monitorInterval可以通過修改配置文件來改變?nèi)罩九渲谩?/p>
log4j2的層次結(jié)構(gòu)
從上面的log4j2.xml配置文件中瓣颅,我們可以看到log4j2的配置文件中主要分為2塊倦逐,一塊為appender,描述了如何記錄日志宫补,另外一部分是log config檬姥,記錄了哪種日志對應(yīng)哪種級別。 而不同的LogConfig之間其實是有繼承關(guān)系的粉怕,子LogConfig會繼承parent的屬性健民,而所有LogConfig都繼承自Root LogConfig。所以即使只配置了root logger贫贝,你一樣可以在任何地方通過LoggerFactory.getLogger獲取一個logger對象荞雏,記錄日志。
那么日志之間的繼承關(guān)系是由什么決定的呢平酿?看看上面的配置文件中root以外的2個logConfig,只有3個配置:日志級別悦陋,name以及appender蜈彼,從直覺上看應(yīng)當(dāng)是name最可能決定了LogConfig的繼承關(guān)系,其實也正是如此:com.foo是com.foo.Bar的父級俺驶;java是java.util的父級幸逆,是java.util.vector的祖先(注意name區(qū)分大小寫)。
理解了這一點暮现,我們就能理清log4j2配置的思路:先配置一個root还绘,讓所有需要使用日志的logger繼承,然后對有特別需要的logger進(jìn)行特殊的配置栖袋,比如我們希望org.springframework
包只記錄error以及warn級別的log拍顷,再比如,我們希望能顯示mybatis執(zhí)行的sql的日志塘幅,都可以進(jìn)行個性化的配置昔案。
appender的配置
appender是LogConfig的重要組成部分,一個LogConfig可以使用多個appender电媳,一個appender也可以被多個LogConfig使用踏揣,appender多種多樣,不同的appender也有不同的屬性和配置匾乓,難以一一闡述捞稿,需要使用時可以直接查看文檔來進(jìn)行個性化配置。不過就filters可以單獨拿出來討論一下。filter有兩個重要屬性onMatch
和onMismatch
娱局≌煤ィ可以有DENY、ACCEPT或NEUTRAL配置,DENY說明不由當(dāng)前appender處理铃辖,ACCEPT說明由當(dāng)前filter處理剩愧,而NEUTRAL說明如果按順序還有其他filter則由其他filter處理,如果當(dāng)前filter已經(jīng)是最后一個filter娇斩,則由當(dāng)前appender處理仁卷。
異步日志
log4j2的官方文檔建議記錄程序行為日志異步日志,效率更高犬第。因為異步日志使用的是無鎖技術(shù)锦积,所以需要引入Disruptor。然后可以通過配置異步的appender或Logger來實現(xiàn)異步日志:
<asyncRoot level="DEBUG">
<appender-ref ref="infoLog" />
<appender-ref ref="Console" />
</asyncRoot>
或
<Async name="Async">
<AppenderRef ref="infoLog"/>
</Async>
動態(tài)修改日志級別
動態(tài)修改日志級別是一個很實用的功能歉嗓,關(guān)于如果動態(tài)修改日志級別丰介,請參考美團(tuán)的一篇文章:日志級別動態(tài)調(diào)整——小工具解決大問題
總結(jié)
以上就是對log4j2的配置的一些總結(jié),更多信息請關(guān)注官方文檔鉴分。