[英]Configure FileAppender after Log4j2 Initialization
我在为log4j2
记录器配置新的FileAppender
遇到问题。 问题是我只知道我应该在应用程序启动后附加我的日志的文件的路径,所以我尝试按照这里的这些说明在log4j2
初始化后修改原始配置。
我已经阅读了很多关于堆栈溢出类似问题的答案,但其中大部分是针对早期的log4j
版本,并且无法工作,因为他们现在已经将面向配置的插件实现到 log4j 本身中。
应用程序成功创建了日志文件,但不会向其中写入任何内容。 我故意将该测试日志消息放在ERROR
级别,以便我可以验证它与日志级别阈值或其他内容无关。
我对 log4j2 配置有点陌生,此时感觉有点迷茫。
我的log4j2.xml
文件(非常基本的)如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Properties>
<Property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${PATTERN}"/>
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>
此外,这是应该添加新FileAppender
:
public static void initLogFile(String path, Level level) {
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
Layout layout = PatternLayout.createDefaultLayout(config);
Appender appender = FileAppender.createAppender(path, "false", "true",
"RollingFile", "true", "false", "false", "8000", null, null,
"false", null, config);
appender.start();
config.addAppender(appender);
AppenderRef ref = AppenderRef.createAppenderRef("RollingFile", null,
null);
AppenderRef[] refs = new AppenderRef[] { ref };
LoggerConfig loggerConfig = LoggerConfig.createLogger("false", level,
"org.apache.logging.log4j", "true", refs, null, config, null);
loggerConfig.addAppender(appender, null, null);
config.addLogger("org.apache.logging.log4j", loggerConfig);
ctx.updateLoggers();
System.out.println("Logger initialized");
}
还有我的Main
方法,它做的第一件事就是尝试更改记录器配置以写入我想要的文件:
static final Logger log = LogManager.getLogger(Main.class.getName());
public static void main( String[] args )
{
// Init
System.out.println("Initializing logger");
Utils.initLogFile("C:/Users/Jorge/Desktop/logtest/test.log", Level.DEBUG);
log.error("test error message");
...
}
你的意思是你只知道应用程序启动后的路径? 无论如何,您应该始终能够使用查找来确定文件路径。 如果路径被指定为应用程序的参数之一,您应该能够使用主参数查找。
需要明确的是,您的配置应该类似于:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Properties>
<Property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${PATTERN}"/>
</Console>
<File name="file" fileName="${main:--logFile}">
<PatternLayout pattern="${PATTERN}"/>
</File>
</Appenders>
<Loggers>
<Logger name="org.apache.logging.log4j" level="${main:--level}">
<AppenderRef ref="file"/>
</Logger>
<Root level="debug">
<AppenderRef ref="Console" />
</Root>
</Loggers>
请注意,我已经配置了一个文件附加程序。 您的示例代码正在创建一个文件附加程序,但出于某种原因将其命名为“RollingFile”。
我接受这个答案,因为它与问题的标题严格相关。 如果您正在查看这篇文章以寻求帮助,您应该花点时间阅读 @rgoers 的回答,因为它可能正是您要找的。
所以这就是我最终做到的。 将现有的空新记录器配置到我的log4j2.xml
文件中(因为我不想在运行时创建一个新记录器),我将在运行时修改它。
我的原始代码的问题是记录器的名称。 如果您查看原始帖子,我正在创建一个名为“org.apache.logging.log4j”的新 appender。
在我的主类上,当我检索我要记录的记录器时,我正在获取我的主类所在的包的默认记录器 ( com.jorge.myapp.business
)。 因此,这个记录器接收了所有的日志请求,而我创建的新的( org.apache.logging.log4j
)没有接收到任何请求。 这就是为什么它不会将任何内容记录到我输入的文件中,因为所有记录请求都转到其他记录器( com.jorge.myapp.business
)。
我希望这对某人有所帮助,解释起来有点混乱......下面是关于我的类和配置文件的更多信息:
修改配置文件log4j2.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Properties>
<Property name="PATTERN">%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${PATTERN}"/>
</Console>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
</Root>
<Logger name="com.jorge.myapp.business" level="debug">
</Logger>
</Loggers>
</Configuration>
这是初始化方法,它从 xml 文件中检索当前的log4j2
配置并修改现有的记录器,添加一个新的文件附加程序。
public static void initLogFile(String path, Level level){
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
Layout layout = PatternLayout.createLayout(Constants.LOG_PATTERN, null, config, null, null, false, false, null, null);
Appender appender = FileAppender.createAppender(path, "true", "true", "File", "true",
"false", "false", null, layout, null, "false", null, config);
appender.start();
config.addAppender(appender);
AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
AppenderRef[] refs = new AppenderRef[] {ref};
LoggerConfig loggerConfig = config.getLoggerConfig("com.jorge.myapp.business");
loggerConfig.addAppender(appender, null, null);
ctx.updateLoggers();
}
我使用的一些常量( Constants.java
类):
public static final String LOG_PATTERN = "%d{yyyy-MM-dd HH:mm:ss} [%-5level] MyApp - %msg%n";
正如@rgoers 指出的那样,可以在此处找到有关 Log4j2 如何在“幕后”实际工作的更多信息。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.