我在eclipse中创建了一个动态项目并尝试创建logger。我在名为log4j2.xml
的xml文件中编写了log4j2代码。该xml包含
我的xml文件能够在控制台中写入,但它无法执行其他两个功能。可能是什么原因?
任何人都可以解释一下root
代码和logger
代码之间的区别
- 何时在AppenderRef ref
标记下添加root
标记以及何时在logger
标记下添加?
我的xml代码如下:
<?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>
<File name="A1" fileName="c:/Workouts/logs.log" append="false">
<PatternLayout pattern="%t %-5p %c{2} - %m%n" />
</File>
<RollingFile name="ROLLING" fileName="c:/Workouts/logsroll.log"
filePattern="c:/Workouts/logsroll-%i.log">
<PatternLayout pattern="%d %p %c: %m%n" />
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="0.001 MB" />
</Policies>
<DefaultRolloverStrategy max="10" />
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="CONSOLE" />
<AppenderRef ref="ROLLING" />
</Root>
<Logger name="com.test.logforjtwo" level="TRACE">
<AppenderRef ref="A1" />
</Logger>
</Loggers>
</Configuration>
java代码:类:Log4j2Example
package com.test.logforjtwo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4j2Example {
static final Logger logger = LogManager.getLogger(Log4j2Example.class.getName());
public static void main(String[] args) {
logger.trace("Entering Log4j Example.");
Hello hello = new Hello();
if (!hello.callMe()) {
logger.error("Ohh!Failed!");
}
logger.trace("Exiting Log4j Example.");
}
}
代码类:Hello
package com.test.logforjtwo;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Hello {
static final Logger logger = LogManager.getLogger(Hello.class.getName());
public boolean callMe() {
logger.entry();
logger.error("Inside Hello Logger!");
logger.fatal("Inside Hello Logger 2!");
return logger.exit(false);
}
}
在控制台输出
18:19:08.282 [main] ERROR com.test.logforjtwo.Hello - Inside Hello Logger!
18:19:08.283 [main] FATAL com.test.logforjtwo.Hello - Inside Hello Logger 2!
18:19:08.283 [main] ERROR com.test.logforjtwo.Log4j2Example - Ohh!Failed!
答案 0 :(得分:0)
记录器按层次结构组织。记录器“A”是记录器“A.B”的父级。 Root记录器位于层次结构的顶部,它是“A”的父级。在您的情况下,Root是“com.test.logforjtwo”的父级。
Root logger配置用于配置默认情况下日志记录的发生方式 当您需要特殊行为(与根配置不同)时,将使用特定的“Logger”配置,如“com.test.logforjtwo”。
在您的示例中,使用“com.test.logforjtwo”Logger的所有TRACE(和DEBUG,INFO ...)日志将记录到A1,ROLLING和CONSOLE。如果您只希望它转到A1,则应在记录器上使用additivity=false
。
其他类只会将(ERROR,FATAL ...)日志发送到CONSOLE和ROLLING appender。
<强>更新强>
您正在使用基于时间的翻转策略,但filePattern不包含日期转换键%d
。我使用你的配置时实际上出错:
Caused by: java.lang.IllegalStateException: Pattern does not contain a date
所以RollingFile还没有工作。如果将filePattern更改为有效的/tmp/Workouts/logsroll-%d-%i.log
,那么事情就会开始起作用。
正如预期的那样,所有日志都会转到所有appender。所有日志都由com.test.logforjtwo
记录器捕获,因为
TRACE
级别的所有日志,并且不再详细。com.test.logforjtwo
包中,例如com.test.logforjtwo.Hello
,这意味着其层次结构中最近的记录器父级是com.test.logforjtwo
。所以所有内容都由A1
appender记录到文件中。然后,由于记录器默认为additivity=true
,因此日志会传递到RootLogger
,并使用ROLLING
和CONSOLE
进行记录。如果您想看到不同的结果,请尝试更改additivity
,如:
<Logger name="com.test.logforjtwo" level="TRACE" additivity="false">
然后您将看到仅使用A1
,因为记录器不再将日志传递给Root Logger。如果您将Hello
移动到另一个包com.test.other_package
,它将不在com.test.logforjtwo
层次结构中,因此它将直接记录到最近的祖先,即根记录器。
我认为最初,因为您的配置中存在错误(filePattern中没有日期),您只看到默认的记录器配置。