log4j使用比较简单,但是有许多需要注意的事项,这些事情不清楚经常会有日志出不来的问题,本文列举了常见的一些问题,阅读本文需要有一些log4j的使用经验。
1.log4j下载,本文使用了slf4j作为接口,log4j作为实现类,maven配置
org.slf4j
slf4j-log4j12
1.6.4
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可以记录日志。
log4j logger,Threshold,additivity细节注意