我有一个log4j2.xml,它定义了我的项目所需的基本appender,但是在某些情况下我需要在运行时添加新的appender,其中log4j状态应该是可能的(https://logging.apache.org/log4j/2.0/manual/architecture.html在Appender下的addLoggerAppender方法应该:" ... Appender将附加到它,然后所有记录器将被通知更新他们的LoggerConfig参考。")。但是,它似乎不起作用(或者我错过了一步)。
我正在运行Log4j2 2.6版本,我的log4j2.xml只定义了级别调试的root-logger,并且有三个appender(一个用于stdout,一个用于stderr和一个RollingFile)。在不尝试更改日志记录配置的情况下,一切正常。
以下是我尝试添加appender的一些代码:
public static void addFileAppender(String logPath, String name, Level level){
LoggerContext ctx = (LoggerContext) LogManager.getContext(true);
Configuration config = ctx.getConfiguration();
Layout<?> layout = PatternLayout.createLayout(
PatternLayout.SIMPLE_CONVERSION_PATTERN,
null,
config,
null,
null,false, false, null, null);
Appender fileAppender = FileAppender.createAppender(logPath, "false", "false", name, "true",
"false", "true", null, layout, null, "false", null, config);
fileAppender.start();
config.addLoggerAppender((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger(), fileAppender);
ctx.updateLoggers();
}
public static void addOutputStreamAppender(OutputStream appendTo, String name, Level level){
LoggerContext ctx = (LoggerContext) LogManager.getContext();
Configuration config = ctx.getConfiguration();
Appender streamAppender = OutputStreamAppender.createAppender(null, null, appendTo, name, true, false);
streamAppender.start();
config.addLoggerAppender((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger(), streamAppender);
ctx.updateLoggers(config);
}
试图找到问题我写了一些简单的代码来检查root-logger的appender:
public void printRootAppenders() {
LoggerContext loggerContext = (LoggerContext) LogManager.getContext();
Configuration configuration = loggerContext.getConfiguration();
// Get the Root Logger and check the appenders
LoggerConfig rootLoggerConfig = configuration.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
Map<String, Appender> appenders = rootLoggerConfig.getAppenders();
for(Entry<String, Appender> app: appenders.entrySet()){
System.out.println("Appender {" + app.getKey() + "} : {" + app.getValue().getLayout().toString()+ "}");
}
}
在添加新的appender之前简单地调用printRootAppenders会给出这个输出:
Appender {STDERR} : {%d{HH:mm:ss} [%-5p] - %m%n}
Appender {STDOUT} : {%m%n}
Appender {LogFile} : {%d{yyyy-MM-dd HH:mm:ss} %-5p %c [%t] - %m%n}
在调用两个add-methods之后,addFileAppender的名称为&#34; ExtraLogFile&#34;和addOutputStreamAppender,名称为&#34; ByteArray&#34;我得到(预期)输出:
Appender {STDERR} : {%d{HH:mm:ss} [%-5p] - %m%n}
Appender {ByteArray} : {%m%n}
Appender {ExtraLogFile} : {%d [%t] %p %c - %m%n}
Appender {STDOUT} : {%m%n}
Appender {LogFile} : {%d{yyyy-MM-dd HH:mm:ss} %-5p %c [%t] - %m%n}
此外,有趣的是ExtraLogFile实际上是正确创建的(正确的位置,名称等),但即使我记录应该结束的事件,它也是空的。日志事件在xml文件中定义的默认appender中正确打印。我连接另一个appender的ByteArrayOutputStream也是空的。
希望我错过了一些明显的东西,但我真的无法弄明白。