有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Log4J2(2.5)中的java可加性

根据位于http://logging.apache.org/log4j/2.x/manual/configuration.html的Log4J2手册,使用

...
      <Loggers>
        <Logger name="com.foo.Bar" level="trace">
          <AppenderRef ref="Console"/>
        </Logger>
        <Root level="error">
          <AppenderRef ref="Console"/>
        </Root>
      </Loggers>
...

记录一份声明,比如

Logger barLogger = LogManager.getLogger(Bar.class);
barLogger.info("A simple info message");

应该产生产出

"A simple info message"

然而,我收到了两次信息,即

"A simple info message"

"A simple info message"

想知道为什么?我知道,不为条形记录器指定additivity="false"也会将消息传播到根记录器。然而,在这种情况下,根记录器的日志级别设置为error,当我阅读手册时,不应再次记录该消息(该消息仅被记录为“info”)

有什么提示吗

更新: 我看到了@rgoers的第一个答案,这似乎是合理的。然而,在我看来,http://logging.apache.org/log4j/2.x/manual/configuration.html的文档似乎仍然过时或不正确。根据文件,该计划

public class MyApp {
 
    // Define a static logger variable so that it references the
    // Logger instance named "MyApp".
    private static final Logger logger = LogManager.getLogger(MyApp.class);
 
    public static void main(final String... args) {
 
        // Set up a simple configuration that logs on the console.
 
        logger.trace("Entering application.");
        Bar bar = new Bar();
        if (!bar.doIt()) {
            logger.error("Didn't do it.");
        }
        logger.trace("Exiting application.");
    }
}
 
public class Bar {
  static final Logger logger = LogManager.getLogger(Bar.class.getName());
 
  public boolean doIt() {
    logger.entry();
    logger.error("Did it again!");
    return logger.exit(false);
  }
}

使用log4J2配置

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Logger name="com.foo.Bar" level="trace">
      <AppenderRef ref="Console"/>
    </Logger>
    <Root level="error">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

应产生以下输出

17:13:01.540 [main] TRACE com.foo.Bar - entry
17:13:01.540 [main] TRACE com.foo.Bar - entry
17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
17:13:01.540 [main] TRACE com.foo.Bar - exit (false)
17:13:01.540 [main] TRACE com.foo.Bar - exit (false)
17:13:01.540 [main] ERROR MyApp - Didn't do it.

然而,运行这个我得到了

00:45:49.951 [main] TRACE com.foo.Bar - entry
00:45:49.951 [main] TRACE com.foo.Bar - entry
00:45:49.951 [main] ERROR com.foo.Bar - Did it again!
00:45:49.951 [main] ERROR com.foo.Bar - Did it again!
00:45:49.951 [main] TRACE com.foo.Bar - exit with(false)
00:45:49.951 [main] TRACE com.foo.Bar - exit with(false)
00:45:49.951 [main] ERROR com.foo.MyApp - Didn't do it.

也就是说,“又做了一次!”记录两次,而不是文档中提到的仅记录一次


共 (1) 个答案

  1. # 1 楼答案

    只有第一个匹配记录器的日志级别用于接受或拒绝日志事件。一旦它被接受,它将被传递给所有的父日志记录者,不管他们指定了什么级别。我认为文件对此非常清楚,但也许不是