帮助我理解 log4j 附加程序相对于优先级的可加性

wxk*_*vin 0 log4j

我很困惑为什么 INFO 语句会进入控制台。这是一般设置:

<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
    <param name="Target" value="System.out"/>
    <param name="Threshold" value="DEBUG"/>
    <layout .../>
</appender>

<appender name="REST_LOG" class="org.apache.log4j.DailyRollingFileAppender">
    <param name="File" value="/logs/rest.log" />
    <param name="Threshold" value="INFO" />
    ....
</appender>

<category name="xyz.web">
    <priority value="WARN" />
    <appender-ref ref="CONSOLE" />
</category>

<category name="xyz.web.rest">
    <priority value="INFO" />
    <appender-ref ref="REST_LOG" />
</category>
Run Code Online (Sandbox Code Playgroud)

所以我希望 INFO 和上面的语句只对 REST_LOG 和 WARN 语句执行,并且上面的语句转到 REST_LOG 和 CONSOLE。我看到的是 REST_LOG 中来自 xyz.web.rest 的 INFO 语句,正如预期的那样,但也在 CONSOLE 中看到来自 xyz.web.rest 的 INFO 语句,这是我没有预料到的。

有人可以解释一下发生了什么事吗?

Joe*_*don 5

您应该在记录器上将可加性设置为 false xyz.web.rest

如果没有可加性,您将在控制台中看到两次INFO使用记录器记录的所有消息,因为记录器继承了根记录器和记录器的附加程序。xyz.web.restxyz.web

请参阅Log4j 文档的Appenders 和布局部分

命名层次结构
如果一个记录器的名称后跟一个点是后代记录器名称的前缀,则称该记录器是另一个记录器的祖先。如果记录器与后代记录器之间没有祖先,则称该记录器是子记录器的父记录器。

例如,名为“com.foo”的记录器是名为“com.foo.Bar”的记录器的父级。类似地,“java”是“java.util”的父级,也是“java.util.Vector”的祖先。大多数开发人员应该熟悉这种命名方案。

根记录器位于记录器层次结构的顶部。它在两个方面是特殊的:

  1. 它始终存在,
  2. 无法通过名称检索它。

追加器和布局

给定记录器的每个启用的记录请求都将转发到该记录器中的所有附加程序以及层次结构中更高的附加程序。例如,如果将控制台附加程序添加到根记录器,则所有启用的日志记录请求至少将打印在控制台上。

如果另外将文件追加器添加到记录器(例如 C),则对 C 和 C 的子级启用的日志记录请求将打印在文件和控制台上。通过将可加性标志设置为 false,可以覆盖此默认行为,以便附加程序累积不再是可加性的。