为什么Log4j rootLogger没有根据事件级别过滤日志事件?

为什么我的应用程序中的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及以上级别的大量日志事件,这是我期望和期望的。 然而,尽管设置为级别INFOrootLogger也会显示所有这些事件,包括DEBUG事件,这不是我期望的,也不是我想要的。 相反,我希望它过滤DEBUG事件,但只显示INFO级别和更高级别( WARNERRORFATAL )的事件,这也是我想要的。 为什么rootLogger显示所有事件?

有关Log4j中记录器链接的类似问题,请参阅此答案 :

Log4j链接的工作方式有点反直觉(至少对我来说)。 如果请求级别等于或高于最具体的匹配记录器的阈值,则接受该级别。 一旦请求被接受,它将由完整的祖先链处理,无论其阈值如何!

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

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

 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 

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

查看介绍中描述的inheritance。 如果在包级别指定级别,则不会inheritance根记录器的级别。 您在指定的包中使用debug,而不是info。 指定级别会覆盖已inheritance的内容。

如果要inheritance根记录器的级别,请删除记录器配置中的级别规范。