Log4j:多个记录器、级别和附加器

Log4j:多个记录器、级别和附加器,log4j,Log4j,在使用log4j写入多个日志文件时,我遇到了重复日志消息的问题 目前,我正在尝试在我的foo.log文件中记录名为foobar的特定记录器的INFO级别数据(及以上),然后在bar.log文件中记录所有记录器的WARN级别日志消息(及以上) 因此,重复的日志消息被写入foo.log文件(每行记录两次),经过快速研究,我发现解决这个问题的建议是将log4j.additivity.foobar=false添加到我的属性文件中 问题在于,尽管它会停止重复的行,但来自foobar记录器的WARN消息从未

在使用log4j写入多个日志文件时,我遇到了重复日志消息的问题

目前,我正在尝试在我的
foo.log
文件中记录名为foobar的特定记录器的
INFO
级别数据(及以上),然后在
bar.log
文件中记录所有记录器的
WARN
级别日志消息(及以上)

因此,重复的日志消息被写入
foo.log
文件(每行记录两次),经过快速研究,我发现解决这个问题的建议是将
log4j.additivity.foobar=false
添加到我的属性文件中

问题在于,尽管它会停止重复的行,但来自foobar记录器的
WARN
消息从未写入
bar.log
文件

我的log4j属性文件如下:

log4j.rootLogger = WARN, FOO, BAR
log4j.logger.foobar = INFO, FOO
log4j.additivity.foobar = false

log4j.appender.FOO = org.apache.log4j.RollingFileAppender
log4j.appender.FOO.layout = org.apache.log4j.PatternLayout
log4j.appender.FOO.layout.ConversionPattern = %d{ISO8601} %-5p %c ~ %m%n
log4j.appender.FOO.File = foo.log

log4j.appender.BAR = org.apache.log4j.RollingFileAppender
log4j.appender.BAR.layout = org.apache.log4j.PatternLayout
log4j.appender.BAR.layout.ConversionPattern = %d{ISO8601} %-5p %c ~ %m%n
log4j.appender.BAR.File = bar.log
log4j.rootLogger = WARN, FOO, BAR
log4j.logger.foobar = INFO

log4j.appender.FOO = org.apache.log4j.RollingFileAppender
log4j.appender.FOO.layout = org.apache.log4j.PatternLayout
log4j.appender.FOO.layout.ConversionPattern = %d{ISO8601} %-5p %c ~ %m%n
log4j.appender.FOO.File = foo.log
log4j.appender.FOO.Threshold = INFO

log4j.appender.BAR = org.apache.log4j.RollingFileAppender
log4j.appender.BAR.layout = org.apache.log4j.PatternLayout
log4j.appender.BAR.layout.ConversionPattern = %d{ISO8601} %-5p %c ~ %m%n
log4j.appender.BAR.File = bar.log
log4j.appender.BAR.Threshold = WARN
是否有人知道我如何将日志消息写入两个日志文件(就像我开始设置
additivity
属性之前那样),并且仍然可以防止重复的日志消息


请注意,这是问题的简化摘要。在真实场景中,有多个记录器和两个以上的日志文件

此问题可以分两部分解决

1。防止重复日志消息

日志消息被写入了两次,因为我们在rootLoggerlog4j.logger.foobar类别中都列出了FOOappender。因此,我们必须删除appender,只在category中定义日志记录级别:

log4j.rootLogger = WARN, FOO, BAR
log4j.logger.foobar = INFO
这意味着来自log4j.logger.foobarINFO级别消息将向上传播到rootLogger中的appender中的所有记录器,但只会写入每个日志文件一次

2。防止信息级消息写入bar.log

由于log4j.logger.foobar类别的所有信息级日志消息都被rootLogger中的附加程序继承,因此我们需要停止
BAR
附加程序来记录INFO级别的消息

我们可以通过在追加器本身上设置阈值属性来实现这一点:

log4j.appender.BAR.Threshold = WARN
这将防止INFO级别语句记录在bar.log文件中,因为它只接受WARN及以上级别

因此完整的log4j属性文件如下所示:

log4j.rootLogger = WARN, FOO, BAR
log4j.logger.foobar = INFO, FOO
log4j.additivity.foobar = false

log4j.appender.FOO = org.apache.log4j.RollingFileAppender
log4j.appender.FOO.layout = org.apache.log4j.PatternLayout
log4j.appender.FOO.layout.ConversionPattern = %d{ISO8601} %-5p %c ~ %m%n
log4j.appender.FOO.File = foo.log

log4j.appender.BAR = org.apache.log4j.RollingFileAppender
log4j.appender.BAR.layout = org.apache.log4j.PatternLayout
log4j.appender.BAR.layout.ConversionPattern = %d{ISO8601} %-5p %c ~ %m%n
log4j.appender.BAR.File = bar.log
log4j.rootLogger = WARN, FOO, BAR
log4j.logger.foobar = INFO

log4j.appender.FOO = org.apache.log4j.RollingFileAppender
log4j.appender.FOO.layout = org.apache.log4j.PatternLayout
log4j.appender.FOO.layout.ConversionPattern = %d{ISO8601} %-5p %c ~ %m%n
log4j.appender.FOO.File = foo.log
log4j.appender.FOO.Threshold = INFO

log4j.appender.BAR = org.apache.log4j.RollingFileAppender
log4j.appender.BAR.layout = org.apache.log4j.PatternLayout
log4j.appender.BAR.layout.ConversionPattern = %d{ISO8601} %-5p %c ~ %m%n
log4j.appender.BAR.File = bar.log
log4j.appender.BAR.Threshold = WARN

这一切都很好,但这不是我们要问的。伐木工人如何区分这一点?最初的问题是,只有
foobar
转到foo,包括foobar在内的所有日志记录者都转到bart。问题要求解决方案,其中
foobar
日志记录者的所有
INFO
消息转到
foo.log
文件,所有日志记录者的所有
WARN
消息转到
bar.log
文件(而且每个日志消息只在相应的文件中写入一次)。不,所有日志记录者,不仅仅是
foobar
都会被发送到
bar.log
。根据问题:“目前,我正在尝试在我的foo.log文件中记录名为
foobar
的特定记录器的
INFO
级别数据,然后在bar.log文件中记录所有记录器的所有
WARN
级别日志消息。“我看不出我们在这里说的有什么不同-除了在你的第一句话中,你不承认只有所有记录者的
WARN
级别消息被发送到
bar.log
(但你在我原始问题的复制粘贴摘录中这样做了)是的,在解决方案中,所有记录器都会转到
foo.log
,问题只要求只有foobar被记录到
foo.log
。基本上,如果
barfoo
记录器有
WARN
消息,它不应该转到foobar