【问题标题】:Why is Log4j rootLogger not filtering log events according to event level?为什么 Log4j rootLogger 不根据事件级别过滤日志事件?
【发布时间】:2010-06-11 14:39:28
【问题描述】:

为什么我的应用程序中的Log4j rootLogger 没有根据级别过滤日志事件?在我的log4j.properties 中,我有几个记录器:

log4j.rootLogger=info,stdout
log4j.logger.com.name.myapp=debug,myapp
log4j.logger.org.castor=debug,castor
log4j.logger.org.exolab.castor=debug,castor
log4j.logger.org.hibernate=debug,hibernate
log4j.logger.org.springframework=debug,spring

每个记录器都在DEBUG 及更高级别接收并记录大量日志事件,这是我所期望和希望的。然而,rootLogger 尽管设置为INFO 级别,但也会显示所有这些事件,包括DEBUG 事件,这不是我所期望的,也不是我想要的。相反,我希望它过滤DEBUG 事件,但只显示INFO 和更高级别的事件(WARNERRORFATAL),这也是我想要的。为什么 rootLogger 会显示所有事件?

【问题讨论】:

  • 您已经为 com.name.myapp,org.castor,org.hibernate,org.springframework 提供了调试级别,所以对于这些 pkg,它会打印调试信息吗?
  • 是的,这些级别打印调试事件。但是,rootLogger 打印所有事件,但我希望它只打印信息事件。
  • 然后将级别更改为信息。
  • 根记录器的阈值级别已经设置为INFO。这就是我的观点。根记录器也接受调试事件。为什么?
  • 正如我在下面的回答中所讨论的,stackoverflow.com/questions/2453010/… 解释了为什么根记录器会捕获所有其他记录器的事件。

标签: java logging log4j


【解决方案1】:

请参阅answer 和类似的question,了解 Log4j 中的记录器链接:

Log4j 链接的工作方式有点 反直觉(至少对我而言)。如果 请求级别等于或高于 最具体的阈值 匹配记录器,它被接受。一次 请求被接受,它得到 由完整的链条处理 祖先不管他们 阈值!

这意味着无论您将根记录器的阈值设置到什么级别,它都将始终接受并输出任何其他记录器接受的日志事件,除非您禁用该子记录器的链接或显式设置其阈值追加到更高级别。

因此,在这种情况下,有两种方法可以防止根记录器从其他记录器捕获事件。第一种是禁用日志事件链接的更有选择性的方法:

log4j.additivity.com.name.myapp=false
log4j.additivity.org.castor=false
log4j.additivity.org.exolab.castor=false
log4j.additivity.org.hibernate=false
log4j.additivity.org.springframework=false

第二种方式更简单,但限制性更强,因为它会抑制控制台上低于INFODEBUGTRACE)的所有事件:

log4j.appender.stdout.Threshold=info

【讨论】:

    【解决方案2】:

    查看intro 中描述的继承。如果您在包级别指定级别,它将不会继承根记录器的级别。您在指定的包中使用调试,而不是信息。指定级别会覆盖已继承的任何内容。

    如果您想继承根记录器的级别,请去掉记录器配置中的级别规范。

    【讨论】:

    • 我不希望包继承根记录器级别。我希望根记录器省略调试事件并仅向控制台显示信息及以上信息。
    • @Derek Mahar 查看logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/…。使用 %c 查看您的关卡实际在做什么。通过这种方式,您应该能够更好地追踪正在发生的事情。
    【解决方案3】:

    要检索 rootlogger,您是否使用Logger.getRootLogger()?如果没有,您可能没有获得真正的根记录器。如果是这样,请确保在调试时stdout 的阈值不是; appenders 的阈值会覆盖记录器级别的阈值。

    【讨论】:

    • appender 的默认优先级是多少?是ALL吗?
    • 对不起,我的意思是 Threshold。您在下面找到的答案是正确的。
    • 您的答案是正确的,但正如我在回答 (stackoverflow.com/questions/3023690/…) 中提到的,两种可能的解决方案之一是将 appender stdout 的阈值设置为 INFO
    猜你喜欢
    • 2011-01-28
    • 1970-01-01
    • 2012-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    相关资源
    最近更新 更多