今天在配置Log4j日誌的時候,發現日誌重複打印的問題。網上查了不少資料,發現介紹Log4j配置的文章數量很多,但提到這個問題的文章卻寥寥,解決了本身的問題之後,趕忙記錄一下。程序員
原文地址:www.jianshu.com/p/7f0a1121a…apache
本文基於log4j 1.2.17版本進行說明bash
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>複製代碼
####1、問題描述
先來看一下日誌配置文件:app
#root日誌
log4j.rootLogger=INFO,stdout,info,warn,error
#控制檯日誌
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %-5p %c{1}:%L - %m%n
#info級別日誌
log4j.appender.info=org.apache.log4j.RollingFileAppender
log4j.appender.info.Threshold=INFO
log4j.appender.info.File=/home/info.log
log4j.appender.info.MaxFileSize=200MB
log4j.appender.info.MaxBackupIndex=5
log4j.appender.info.layout=org.apache.log4j.PatternLayout
log4j.appender.info.layout.ConversionPattern=%d %-5p %l - %m%n
#warn級別日誌
log4j.appender.warn=org.apache.log4j.RollingFileAppender
log4j.appender.warn.Threshold=WARN
log4j.appender.warn.File=/home/warn.log
log4j.appender.warn.MaxFileSize=200MB
log4j.appender.warn.MaxBackupIndex=5
log4j.appender.warn.layout=org.apache.log4j.PatternLayout
log4j.appender.warn.layout.ConversionPattern=%d %-5p %l - %m%n
#error級別日誌
log4j.appender.error=org.apache.log4j.RollingFileAppender
log4j.appender.error.Threshold=ERROR
log4j.appender.error.File=/home/error.log
log4j.appender.error.MaxFileSize=200MB
log4j.appender.error.MaxBackupIndex=5
log4j.appender.error.layout=org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern=%d %-5p %l - %m%n複製代碼
上面這個log4j.properties配置文件是個很是常規的文件,網上大多數講解Log4j配置信息的文章也都是基於這樣一個模板展開的。ide
使用這套配置,毫無疑問日誌是能夠正常打印的,但問題就是log4j.appender.info.Threshold指定的級別表示打印等於或者大於這個級別的日誌,這樣一來當執行下面代碼的時候ui
Logger LOG = LoggerFactory.getLogger(Test.class);
LOG.info("info");
LOG.warn("warn");
LOG.error("error");複製代碼
咱們看到的現象是:
/home/info.log文件中會打印info,warn,error三行日誌;
/home/warn.log文件中會打印warn,error兩行;
/home/error.log文件中只會打印error一行日誌。this
上面的結果顯然不是咱們想要的,由於這樣的話至關於info日誌中含有全部的日誌信息,不但形成冗餘,並且也會讓warn日誌跟error日誌顯得沒有存在的必要。更多的狀況下咱們但願info日誌中只有INFO級別的日誌,warn日誌中只有WARN級別的日誌,一樣error日誌中也只有ERROR級別的日誌。spa
####2、解決辦法
這裏提供兩種解決方案:日誌
默認的isAsSevereAsThreshold方法的實現爲:code
public boolean isAsSevereAsThreshold(Priority priority) {
return this.threshold == null || priority.isGreaterOrEqual(this.threshold);
}複製代碼
若是沒有設置threshold屬性則所有打印,不然打印大於等於threshold屬性的日誌。
咱們繼承該類並重寫此方法,以下:
public class MyLog4jAppender extends RollingFileAppender {
@Override
public boolean isAsSevereAsThreshold(Priority priority) {
return priority != null && this.getThreshold() != null
&& priority.isGreaterOrEqual(this.getThreshold())
&& this.getThreshold().isGreaterOrEqual(priority);
}
}複製代碼
並在log4j.properties文件中修改log4j.appender.info=com.xxx.MyLog4jAppender便可。
這個實際上是Log4j自帶的方案,也是推薦方案,不知道爲何網上的資料卻不多提到這點。
把log4j.properties配置文件修改爲以下:
#root日誌
log4j.rootLogger=INFO,stdout,info,warn,error
#控制檯日誌
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %-5p %c{1}:%L - %m%n
#info級別日誌
log4j.appender.info=org.apache.log4j.RollingFileAppender
log4j.appender.info.Threshold=INFO
log4j.appender.info.File=/home/info.log
log4j.appender.info.MaxFileSize=200MB
log4j.appender.info.MaxBackupIndex=5
log4j.appender.info.layout=org.apache.log4j.PatternLayout
log4j.appender.info.layout.ConversionPattern=%d %-5p %l - %m%n
log4j.appender.info.filter.infoFilter = org.apache.log4j.varia.LevelRangeFilter
log4j.appender.info.filter.infoFilter.LevelMin=INFO
log4j.appender.info.filter.infoFilter.LevelMax=INFO
#warn級別日誌
log4j.appender.warn=org.apache.log4j.RollingFileAppender
log4j.appender.warn.Threshold=WARN
log4j.appender.warn.File=/home/warn.log
log4j.appender.warn.MaxFileSize=200MB
log4j.appender.warn.MaxBackupIndex=5
log4j.appender.warn.layout=org.apache.log4j.PatternLayout
log4j.appender.warn.layout.ConversionPattern=%d %-5p %l - %m%n
log4j.appender.warn.filter.infoFilter = org.apache.log4j.varia.LevelRangeFilter
log4j.appender.warn.filter.infoFilter.LevelMin=WARN
log4j.appender.warn.filter.infoFilter.LevelMax=WARN
#error級別日誌
log4j.appender.error=org.apache.log4j.RollingFileAppender
log4j.appender.error.Threshold=ERROR
log4j.appender.error.File=/home/error.log
log4j.appender.error.MaxFileSize=200MB
log4j.appender.error.MaxBackupIndex=5
log4j.appender.error.layout=org.apache.log4j.PatternLayout
log4j.appender.error.layout.ConversionPattern=%d %-5p %l - %m%n
log4j.appender.error.filter.infoFilter = org.apache.log4j.varia.LevelRangeFilter
log4j.appender.error.filter.infoFilter.LevelMin=ERROR
log4j.appender.error.filter.infoFilter.LevelMax=ERROR複製代碼
經過以上配置模板便可解決各級別日誌重複打印的問題。
今天是1024程序員節,兄弟們high起來~