log4j logger,Threshold,additivity细节注意

来源:互联网 发布:什么软件团购最便宜 编辑:程序博客网 时间:2024/05/22 23:09

log4j使用比较简单,但是有许多需要注意的事项,这些事情不清楚经常会有日志出不来的问题,本文列举了常见的一些问题,阅读本文需要有一些log4j的使用经验。

1.log4j下载,本文使用了slf4j作为接口,log4j作为实现类,maven配置

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>

2.根目录的配置

log4j.rootLogger=debug, A1 ,R
这个意思是日志的根日志的级别为debug,具体的日志的A1,R。什么是根日志呢?根日志就是所有的日志的父类,如果在代码中写入了没有配置的日志,这个时候就会找到根日志,如果输出的级别大于根日志的级别就会输出到根日志中,相当于根日志是默认的日志。

上面跟日志定义了两个输出源A1和R,这里需要对A1和R进行配置

A1的配置


log4j.appender.A1 = org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File = d:/abc/test.log
log4j.appender.A1.Append = true
log4j.appender.A1.DatePattern=yyyy-ww
log4j.appender.A1.Threshold = info 
log4j.appender.A1.layout = org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern =%5p %10d{yyyy-MM-dd HH:mm:ss} {%l} %m%n

对于以上配置不明白的可以google,这里要说的Threshold的配置,这里threshold的配置是info,但是rootlogger是debug。

代码:

Logger logger = LoggerFactory.getLogger("A1");
logger.debug("D");

logger.info("E");

这里只会输出info的日志,不会输出debug的日志,原因是rootLogger虽然定义了级别是debug,但是threshold的级别是info,info>debug所以只会输出info的日志,如果将rootlogger和A1的级别颠倒过来呢。

log4j.rootLogger=info, A1

    log4j.appender.A1.Threshold = debug


logger.debug("D");

logger.info("E");

这里只会输出info的日志,不会输出debug的日志,通过代码可以得到的结论是logger和threshold两者取中间日志级别大的.

除了rootlogger自己需要定义一个日志需要如何定义呢?

模仿A1写了一个B,如下:

log4j.appender.B= org.apache.log4j.DailyRollingFileAppender
log4j.additivity.C=false
log4j.appender.B.File = d:/abc/B.log
log4j.appender.B.Append = true
log4j.appender.B.DatePattern=yyyy-ww
log4j.appender.B.Threshold = INFO 
log4j.appender.B.layout = org.apache.log4j.PatternLayout
log4j.appender.B.layout.ConversionPattern =%5p %10d{yyyy-MM-dd HH:mm:ss} {%c:%l} %m%n

代码中使用Logger logger = LoggerFactory.getLogger("B")会输出日志么?答案是否定的。

因为只定了日志B但是没有定义在代码中的使用,需要加上以下配置:

log4j.logger.C=debug,B

这里定义了代码使用的配置,问题来了,我们在代码中使用的是C还是B。

答案是C,log4j.logger.name定义了代码中需要使用的名字,这里名字是C,日志级别是debug,appender的名字B,因为这里定义了appender的名字是B所以需要配置B的appender的配置。

配置好了,代码中这样使用Logger logger = LoggerFactory.getLogger("C");


日志C相当于新配置的日志,他的父日志就是我们开始说的rootlogger,也就是A1和R。在log4j中子日志输出,父日志也会相应的输出代码:

Logger logger = LoggerFactory.getLogger("C");

logger.debug("D");

logger.info("E");

在C的日志中debug的日志和info的日志都输出了,但是在A1的日志中只有info的日志,为什么呢?因为A1的threshold级别是info>debug所以只会输出info的信息。

如果A1没有设置自己的日志级别,但是log4j.rootLogger配置的日志级别高于C的级别会输出么,如下

log4j.rootLogger=error,A1

log4j.logger.C=debug,B

Logger logger = LoggerFactory.getLogger("C");

logger.debug("D");

logger.info("E");

rootlogger级别error大于C的级别debug,但是在A1的日志中debug和info的信息都输出了,这一块是相对难理解的,我的理解是如果rootlogger的实现日志中没有配置日志级别,即使rootlogger配置了日志级别对子日志的输出也没有限制全部输出。这一块需要记住。如果实现日志配置了threshold,则输出比实现日志级别大的日志。

如果子类不想让父类输出怎么办?需要一下配置:

 log4j.additivity.C=false

这样父类不管日志级别都不会输出了。

在log4j中rootlogger不配置也是可以的,不会报错,但是配置rootlogger是一个好的习惯,代码中如果出现了没有配置的日志,至少还有rootlogger可以记录日志。



0 0