我是log4j的新手。我的log4j配置未将日志写入控制台,因为到文件的日志运行正常。尽管参考了以前的文章,但我无法解决此问题。 我有两个追加程序-一个用于控制台,另一个用于文件。我打算将错误和致命写入文件,因此使用级别=错误。我打算将所有日志写入控制台,因此对控制台使用level = TRACE。 我的代码仅包含一个名为“ parallel”的程序包,具有一个名为ClassA的类,该类具有记录所有类型日志的一种方法。
如果我在Root标记中同时指定了控制台和文件附加器,则可以满足我的期望。如果我将文件附加器移到Root之外,并在Logger标记下提及,那么只有文件附加器起作用,而控制台附加器不起作用。是否必须将所有附加程序置于Root标签下?
package parallel;
public class ClassA {
private final Logger log = LogManager.getLogger(ClassA.class);
@Test
public void testLogs() {
log.info("info");
log.debug("debug");
log.warn("warn");
log.error("error");
log.fatal("fatal");
log.trace("trace");
}
}
<Configuration status="INFO">
<Properties>
<Property name="basePath" value="./logs" />
</Properties>
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout>
<Pattern>
[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
</Pattern>
</PatternLayout>
</Console>
<File name="fileLogger" fileName="${basePath}/error.log">
<PatternLayout>
<Pattern>
[%-5level] %d{yyyy-MM-dd HH:mm:ss} [%t] %c{1} - %msg%n
</Pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root name="parallel">
<AppenderRef ref="console" level="trace" />
</Root>
<Logger name="parallel" level="warn" additivity="false">
<AppenderRef ref="fileLogger" />
</Logger>
</Loggers>
答案 0 :(得分:1)
据我了解,您的目标是完成以下各项:
我打算将error和FATAL写入文件,因此使用level = ERROR。一世 打算将所有日志写入控制台,因此将level = TRACE用于 控制台。
在确定将在代码中实现的内容之前,请先阅读整个答案。
您 可以 可以通过如下配置记录器来做到这一点:
<Loggers>
<Root>
<AppenderRef ref="console"/>
</Root>
<Logger name="parallel" level="ALL" additivity="true">
<AppenderRef ref="fileLogger" level="ERROR"/>
</Logger>
</Loggers>
日志事件将由每个记录器接受,具体取决于记录器名称和事件级别。例如,如果您调用log.error(...)
,则会生成一个ERROR
级事件。如果log
是通过LogManager.getLogger(ClassA.class)
获得的,则log4j将在其配置中搜索名为“ parallel.ClassA”的记录器。如果找不到这样的记录器,它将up the hierarchy转到不太具体的记录器-“ parallel”。如果该记录器不存在,它将转到根记录器。
一旦识别出记录器,log4j必须确定该记录器是否接受了事件。这基于记录器的级别设置。由于“并行”记录器的级别设置为ALL
,因此它将接受任何级别的事件。
记录器接受事件后,其附加程序也必须接受事件。与“并行”记录器的文件附加程序关联的级别为ERROR
,因此此附加程序将仅接受ERROR
和FATAL
级别的事件。
由于“并行”记录器在接受事件时可加性为true
,因此也会将该事件也传递给appenders of all of its parent loggers(除非其中一个通过指定可加性{{1}来打破链条) }-有关详细信息,请参见log4j2 architecture page。因此,“并行”接受的任何事件都将进入与根记录程序关联的控制台附加程序。
此方法有一个问题,因为如果日志事件以ERROR或FATAL级别到达根记录程序,则不会将其写入您的日志文件。日志将“泄漏”到控制台。如果您不小心编写了错误的代码,或者在添加一些新代码后不小心忘记更新配置文件,则会发生这种情况。
下面是一些示例代码来说明问题:
false
使用答案开头的配置的上述控制台输出是:
package parallel;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ClassA {
private static final Logger log = LogManager.getLogger(ClassA.class);
public static void main(String[] args) {
log.info("info");
log.debug("debug");
log.warn("warn");
log.error("error");
log.fatal("fatal");
log.trace("trace");
// See the mistake here?
// The wrong logger name was used in the code,
// now the error event goes to the root logger!
final Logger log2 = LogManager.getLogger("foo");
log2.error("Woops an error!");
}
}
错误日志文件仅显示:
[INFO ] 2019-05-05 12:48:31.410 [main] ClassA - info
[DEBUG] 2019-05-05 12:48:31.411 [main] ClassA - debug
[WARN ] 2019-05-05 12:48:31.411 [main] ClassA - warn
[ERROR] 2019-05-05 12:48:31.411 [main] ClassA - error
[FATAL] 2019-05-05 12:48:31.412 [main] ClassA - fatal
[TRACE] 2019-05-05 12:48:31.412 [main] ClassA - trace
[ERROR] 2019-05-05 12:48:31.413 [main] foo - Woops an error!
最简单的解决方法是将所有附加程序移至根记录器,如下所示:
[ERROR] 2019-05-05 12:48:31 [main] ClassA - error
[FATAL] 2019-05-05 12:48:31 [main] ClassA - fatal
现在,所有事件都被root记录程序和控制台附加程序接受,但文件附加程序仅接受ERROR和FATAL事件。现在,即使使用错误的代码,日志事件也将转到正确的位置。
控制台输出:
<Loggers>
<Root level="ALL">
<AppenderRef ref="console"/>
<AppenderRef ref="fileLogger" level="ERROR"/>
</Root>
</Loggers>
错误日志文件:
[INFO ] 2019-05-05 12:59:32.419 [main] ClassA - info
[DEBUG] 2019-05-05 12:59:32.421 [main] ClassA - debug
[WARN ] 2019-05-05 12:59:32.421 [main] ClassA - warn
[ERROR] 2019-05-05 12:59:32.421 [main] ClassA - error
[FATAL] 2019-05-05 12:59:32.421 [main] ClassA - fatal
[TRACE] 2019-05-05 12:59:32.421 [main] ClassA - trace
[ERROR] 2019-05-05 12:59:32.422 [main] foo - Woops an error!
其他可能有用的链接:
https://stackoverflow.com/a/51567436/3284624
希望对您有所帮助!
答案 1 :(得分:0)
部分解决..... 我在Logger标记中添加了Additivity =“ true”,这使日志同时在控制台和文件中打印。但是,错误的日志级别已同时应用于控制台和文件。我的实际要求是控制台具有TRACE,文件具有ERROR级别。 我无法从log4j2官方文档中了解“可加性”的概念。任何可以解释这个概念的人都会有很大帮助。