3

我正在使用 Tomcat 6 并尝试将 JUL 切换到 Log4j2 (2.0 beta 3)。但是,由于它是一个相当新的项目,文档非常稀少,在线资源还不是很多。

我想要的是

  1. 调试级别以上的所有事件都应转到磁盘上的文件。
  2. 错误应该去syserr
  3. 从信息到警告的所有内容都应该转到sysout.
  4. 标记的审计日志应该跳过所有这些并转到磁盘上的不同文件。

我试过的

这是我的第一次尝试log4j2.xml文件:

我应该写configuration status什么?关于它的一些文档在哪里?

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="info">
<appenders>
    <Console name="Console-err" target="SYSTEM_ERR">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <Console name="Console-out" target="SYSTEM_OUT">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <File name="MyFile" fileName="app.log">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
</appenders>
<loggers>
    <logger name="com.ecm" level="error" additivity="false">
        <appender-ref ref="Console-err" />
        <appender-ref ref="MyFile" />
    </logger>
    <root level="info">
        <appender-ref ref="Console-out" />
        <appender-ref ref="MyFile" />
    </root>
</loggers>
</configuration>

记录器名称与 Java 类及其记录器有何关系?

示例代码:

package com.ecm.backend;

public final class Foo {
   private static final Logger LOG = LogManager.getLogger(Foo.class);

   public static void bar() {
     LOG.error("this is error");
     LOG.warn("this is warning");
   }
}

当我运行它时,我在控制台和日志文件中得到它:

10:22:49.385 [http-8080-3] ERROR com.ecm.backend.Foo - this is error

为什么忽略警告?

如果我删除additivity="false",我得到:

10:26:51.388 [http-8080-1] ERROR com.ecm.backend.Foo - this is error
10:26:51.388 [http-8080-1] ERROR com.ecm.backend.Foo - this is error

再次忽略警告并重复错误(如预期的那样)。

我究竟做错了什么?


在折叠下:Tomcat 的其余部分可以使用 JULI,我只想要 Log4j2 用于我的应用程序。

4

1 回答 1

4

如果您设置配置状态=“调试”,您将看到很多关于配置过程中发生的事情的 log4j2-internal 日志语句。这可能有助于解决配置问题。

我通常设置配置状态=“警告”,所以只有在出现问题时才会收到通知。

关于记录器名称、记录器及其 java 类之间的关系,也许这会有所帮助: http: //logging.apache.org/log4j/2.x/manual/architecture.html

关于为什么忽略警告的问题,有这个记录器配置:

<logger name="com.ecm" level="error" additivity="false">

还有一个像这样的记录器:

Logger LOG = LogManager.getLogger(com.ecm.backend.Foo.class);

记录器配置“com.ecm”将处理来自 LOG 记录器的所有调用,但实际上只会记录“错误”级别或更高(致命)的调用。其他级别的日志事件(警告、信息、调试和跟踪)被过滤掉,因为它们的级别太低。

可加性的工作方式是首先命名记录器配置(在本例中为“com.ecm”)决定是否应该过滤掉事件。然后,如果 additivity="true"(默认值),则将事件传递给父记录器(在本例中为根记录器)。因为“警告”级别的事件已经被“com.ecm”记录器配置过滤掉了,所以它永远不会到达根记录器。

不确定您要实现什么,但是如果您想将不同的事件级别发送到不同的附加程序,一种方法可能是在 appender-refs 上设置级别,而不是在记录器上:

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="info">
<appenders>
    <Console name="Console-err" target="SYSTEM_ERR">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <Console name="Console-out" target="SYSTEM_OUT">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
    <File name="MyFile" fileName="app.log">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
</appenders>
<loggers>
    <logger name="com.ecm" additivity="false">
        <appender-ref ref="Console-err" level="error" />
        <appender-ref ref="MyFile" level="debug" />
    </logger>
    <root>
        <appender-ref ref="Console-out" level="info" />
        <appender-ref ref="MyFile" level="debug" />
    </root>
</loggers>
</configuration>

这会将 LOG 记录器的输出发送到 MyFile 和(如果级别是错误或致命的)也发送到 Console-err。

不在“com.ecm”包中的记录器的输出将被发送到 MyFile,并且(如果级别是 info、warn、error 或 fatal)也发送到 Console-out。

于 2013-05-14T13:52:49.373 回答