今天在配置Log4j日志的时候,发现日志重复打印的问题。网上查了很多资料,发现介绍Log4j配置的文章数量不少,但提到这个问题的文章却寥寥,解决了自己的问题以后,赶紧记录一下。

原文地址:http://www.jianshu.com/p/7f0a1121a6df

本文基于log4j 1.2.17版本进行说明

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

一、问题描述

先来看一下日志配置文件:

#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配置信息的文章也都是基于这样一个模板展开的。

使用这套配置,毫无疑问日志是可以正常打印的,但问题就是log4j.appender.info.Threshold指定的级别表示打印等于或者大于这个级别的日志,这样一来当执行下面代码的时候

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一行日志。

上面的结果显然不是我们想要的,因为这样的话相当于info日志中含有所有的日志信息,不但造成冗余,而且也会让warn日志跟error日志显得没有存在的必要。更多的情况下我们希望info日志中只有INFO级别的日志,warn日志中只有WARN级别的日志,同样error日志中也只有ERROR级别的日志。

二、解决办法

这里提供两种解决方案:

  1. 重写RollingFileAppender类中的isAsSevereAsThreshold方法。

默认的isAsSevereAsThreshold方法的实现为:

    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起来~

Log4j各级别日志重复打印的问题的更多相关文章

  1. spring :Log4j各级别日志重复打印

    使用filter进行日志过滤 这个其实是Log4j自带的方案,也是推荐方案,不知道为什么网上的资料却很少提到这点. 把log4j.properties配置文件修改成如下: #root日志 log4j. ...

  2. Log4j各级别日志重复打印

    使用filter进行日志过滤 这个其实是Log4j自带的方案,也是推荐方案,不知道为什么网上的资料却很少提到这点.把log4j.properties配置文件修改成如下: #root日志 log4j.r ...

  3. python3 日志重复打印logger

    在python2中正常的日志,单只直接使用python3,发现日志重复了,其实是handlers多添加的原因, python2代码 ---------------------------------- ...

  4. log4j中存在日志无法打印问题解决

    我在项目中配置双数据中心,原来类包名称前最都是一致的,后来由于项目的需要根据数据来源命名不同的类包名称,这个导致一个问题,sql语句运行无法正常打印出来,提示以下内容: log4j:WARN No a ...

  5. 修复日志,阻止给日志多次添加handlers时候重复打印的问题

    1.解决如果多次添加handlers重复打印的问题.在__add_handlers方法中作出判断. 2.由get_logger_and_add_handlers和get_logger_without_ ...

  6. Log4j基本用法----日志级别

    基本使用方法: Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式.日志信息的优先级从高到低有ERROR.WARN.INFO.DEBUG,分别用来指定这条日志信 ...

  7. Log4j配置的经典总结,打印日志文件,日志存库

        一.介绍 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制 日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务 器.NT的事件记录器.UNIX Sy ...

  8. log4j分级别打印和如何配置多个Logger

    log4j.rootLogger=dubug,info,warn,error 最关键的是log4j.appender.[level].threshold=[level]   这个是日志分级别打印的最关 ...

  9. Log4j 输出的日志中时间比系统时间少了8小时的解决方法,log4j日志文件重复输出

    1. 第一个问题:时间少了8小时 Log4j 输出的日志中,时间比系统时间少了8小时,但是 eclipse 控制台输出的日志的时间却是对的. log4j配置如下: #all logger output ...

随机推荐

  1. 201521123064 《Java程序设计》第12周学习总结

    本次作业参考文件 正则表达式参考资料 1. 本章学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. ① 标准输入输出流(字节流):标准输入流 System.in,标准输出流 ...

  2. 201521123049 《JAVA程序设计》 第12周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2. 书面作业 将Student对象(属性:int id, String name,int age,doubl ...

  3. org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not a

    如果出现了这个错误,看看在使用Hibernate的时候有没有在事务的环境下执行操作!

  4. Java实现MD5加密_字符串加密_文件加密

    Java实现MD5加密,具体代码如下: package com.bstek.tools; import java.io.FileInputStream; import java.io.IOExcept ...

  5. Oracle-SQL-按月统计自助终端交易量

    SQL实现的目标: 基本情况 现金交易情况 转账情况 转账交易情况(明细) 其它业务情况 交易量汇总 日均交易量 交易金额 绩效情况(万元) 支行名 支行号 所属网点 网点号 管理员帐户 管理员 终端 ...

  6. JSP页面格式化数字或时间 基于jstl的

    jsp页面格式化数字或时间 转载自: http://blog.csdn.net/hakunamatata2008/archive/2011/01/21/6156203.aspx Tags fmt:re ...

  7. 一种Webconfig自动化升级方法

    1.方法功能 使用本方法,可以将开发环境最新版本的web.config结构与生产环境环境的config融合,而不用考虑两个config的版本差异值是多少.使用一种标记的方式,在开发环境webconfi ...

  8. PHP垃圾回收机制理解

    使用的是"引用计数"方式进行回收.简单地理解的话,就是每个分配的内存区域都有一个计数器,记录有多少个变量指针指向这片内存.当指向该片内存的指针数量为0,那么该片内存区域就可以被回收 ...

  9. oracle pl/sql 存储过程

    存储过程用于执行特定的操作,当建立存储过程时,既可以指定输入参数(in),也可以指定输出参数(out),通过在过程中使用输入参数,可以将数据传递到执行部分:通过使用输出参数,可以将执行部分的数据传递到 ...

  10. Java中的对象和引用

    <Java编程思想>中有一段关于对象的说法: "按照通俗的说法,每个对象都是某个类(class)的一个实例(instance),这里,'类'就是'类型'的同义词." 简 ...