我正在使用 Tomcat 6 并尝试将 JUL 切换到 Log4j2 (2.0 beta 3)。然而,由于它是一个相当新的项目,文档非常稀少,在线资源也不多。
我想要什么
- 调试级别以上的所有事件都应转到磁盘上的文件。
- 错误应该转到
syserr
. - 从信息到警告的所有内容都应该转到
sysout
. - Marked审核日志应跳过所有这些并转到磁盘上的不同文件。
我尝试过的
这是我的第一次尝试 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
再次忽略警告并重复错误(如预期)。
我做错了什么?
Under the fold:其余的 Tomcat 可以使用 JULI,我只需要 Log4j2 用于我的应用程序。
最佳答案
如果您设置配置 status="debug",您将看到很多关于配置过程中发生的事情的 log4j2 内部日志语句。这可能有助于解决配置问题。
我通常设置配置 status="warn",这样我只会在出现问题时收到通知。
关于记录器名称、记录器和它们的 java 类之间的关系,也许这有帮助: http://logging.apache.org/log4j/2.x/manual/architecture.html
关于why warning被忽略的问题,有这个logger config:
<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,一种方法可能是在 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 并且(如果级别是信息、警告、错误或致命)也将发送到控制台输出。
关于java - Tomcat 中的 Log4j2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13668004/