今天在配置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起来~