1. 程式人生 > >log4j的logger繼承性

log4j的logger繼承性

最近在做專案的時候,需要給多個包定義不同的log策略,比如在包com.test.a下的log記錄到檔案file1.log中,包com.test.b下的log記錄到檔案file2.log中,其他的log記錄到file0.log中。最初是如下定義的:

log4j.rootLogger=error, stdout, file0

# appender 1:stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %5p [%t] - %m%n

# appender 2:file 0
log4j.appender.file0=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file0.layout=org.apache.log4j.PatternLayout
log4j.appender.file0.DatePattern='.'yyyy-MM-dd
log4j.appender.file0.file=D:/log/file0.log
log4j.appender.file0.layout.ConversionPattern=%d %5p [%t] - %m%n

# appender 3:file2
log4j.appender.file1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file1.layout=org.apache.log4j.PatternLayout
log4j.appender.file1.DatePattern='.'yyyy-MM-dd
log4j.appender.file1.file=D:/log/file1.log
log4j.appender.file1.layout.ConversionPattern=%d %5p [%t] - %m%n

# appender 4:file3
log4j.appender.file2=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file2.layout=org.apache.log4j.PatternLayout
log4j.appender.file2.layout.ConversionPattern=%d %5p [%t] - %m%n
log4j.appender.file2.file=D:/log/file2.log
log4j.appender.file2.layout.ConversionPattern=%d %5p [%t] - %m%n

log4j.logger.com.test.a=info, stdout, file1

log4j.logger.com.test.b=info, stdout, file2

這樣定義之後會發現file1.log,file2.log可以正常記錄日誌,但是在file0.log中也記錄了file1.log,file2.log中的日誌。就是說記錄重複了。

以上問題的關鍵是log4j的logger是繼承性的,子logger會疊加式地繼承父logger的所有appender。

比如:
log4j.logger.com.test = info, stdout
log4j.logger.com.test.a = info, stdout
結果會導致test.a下的所有日誌會在stdout輸出兩次。

解決方案有以下兩種:
1.不定義全域性log4j.rootLogger,給不同包的logger指定不同的appender。
2.給子logger定義additive屬性的標識,預設是true,是繼承父logger的。只要定義成為false就可以了。
比如上面的問題只要按照以下定義就可以了:
log4j.logger.com.test.a=info, stdout, file1
log4j.additivity.com.test.a=false
log4j.logger.com.test.b=info, stdout, file2
log4j.additivity.com.test.b=false