Log4j各級別日誌重複打印的問題

今天在配置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、解決辦法
這裏提供兩種解決方案:日誌

  1. 重寫RollingFileAppender類中的isAsSevereAsThreshold方法。

默認的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便可。

  1. 使用filter進行日誌過濾

這個實際上是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起來~

相關文章
相關標籤/搜索