Log4j2 在运行时添加记录器——这段代码有什么问题?
Log4j2 add logger at runtime - what's wrong with this code?
在将项目从 log4j 迁移到 log4j2 时,我遇到了这样一种情况:必须在运行时添加将事件记录到单独文件(我们称之为 uu.log
)的记录器 - 所有其他记录器都配置在属性文件。下面的代码几乎完成了这项工作——即 uu.log
包含来自所有现有记录器的事件,而不仅仅是来自新记录器的事件。到目前为止,这是我尝试过的:如何修复下面的代码以最简单的方式达到所需的状态?
public class MultipleLoggersExample {
public static void main(String[] args) throws InterruptedException {
// this logger is configured in properties file and is logging to own file
Logger aud = LogManager.getLogger("aud");
// class B is logging to separate file (logger also defined in properties)
B b = new B();
// below classes should log to common file NormalLog.log defined in properties
C c = new C();
D d = new D();
E e = new E();
addLoggerAtRuntime();
// this logger needs to log only its OWN messages to uu.log file
Logger runtimeLogger = LogManager.getLogger("my runtime logger");
int counter = 2;
while(true) {
if(counter % 2 == 0){
aud.info("message from \"aud\" logger no. "+ (counter-1));
} else{
b.logger.info("message from class B no. " + (counter-1));
}
c.logger.info("message from class C");
e.logger.info("message from class E");
if(counter % 4 == 0) {
runtimeLogger.info("message from logger added at runtime");
}
counter++;
Thread.sleep(5_000);
}
}
private static void addLoggerAtRuntime() {
final String fileName = "C:\Users\Damian\Desktop\uu.log";
LoggerContext lc = (LoggerContext) LogManager.getContext(false);
RollingFileAppender rfa = RollingFileAppender.newBuilder()
.withName("my runtime logger").withAppend(true)
.withFileName(fileName)
.withLayout(PatternLayout.newBuilder().withPattern("%-5p %d [%t] %C{2} - %m%n").build())
.withPolicy(TimeBasedTriggeringPolicy.newBuilder().withModulate(true).withInterval(2).build())
.withFilePattern(fileName + "." + "%d{yyyy-MM-dd-HH-mm}")
.setConfiguration(lc.getConfiguration()).build();
rfa.start();
lc.getConfiguration().addAppender(rfa);
lc.getRootLogger().addAppender(lc.getConfiguration().getAppender(rfa.getName()));
lc.updateLoggers();
}
}
Appender 名称与记录器名称没有关系,因此:
.withName("my runtime logger")
毫无意义。你还不如用"My appender"
什么的。
问题是这样的:
lc.getRootLogger().addAppender(
您正在将 Appender 添加到根记录器,所有其他记录器都继承自该根记录器,因此当然所有记录器都在使用它。尝试将 Appender 添加到您的记录器中:
lc.getLogger("my runtime logger").addAppender(
在将项目从 log4j 迁移到 log4j2 时,我遇到了这样一种情况:必须在运行时添加将事件记录到单独文件(我们称之为 uu.log
)的记录器 - 所有其他记录器都配置在属性文件。下面的代码几乎完成了这项工作——即 uu.log
包含来自所有现有记录器的事件,而不仅仅是来自新记录器的事件。到目前为止,这是我尝试过的:如何修复下面的代码以最简单的方式达到所需的状态?
public class MultipleLoggersExample {
public static void main(String[] args) throws InterruptedException {
// this logger is configured in properties file and is logging to own file
Logger aud = LogManager.getLogger("aud");
// class B is logging to separate file (logger also defined in properties)
B b = new B();
// below classes should log to common file NormalLog.log defined in properties
C c = new C();
D d = new D();
E e = new E();
addLoggerAtRuntime();
// this logger needs to log only its OWN messages to uu.log file
Logger runtimeLogger = LogManager.getLogger("my runtime logger");
int counter = 2;
while(true) {
if(counter % 2 == 0){
aud.info("message from \"aud\" logger no. "+ (counter-1));
} else{
b.logger.info("message from class B no. " + (counter-1));
}
c.logger.info("message from class C");
e.logger.info("message from class E");
if(counter % 4 == 0) {
runtimeLogger.info("message from logger added at runtime");
}
counter++;
Thread.sleep(5_000);
}
}
private static void addLoggerAtRuntime() {
final String fileName = "C:\Users\Damian\Desktop\uu.log";
LoggerContext lc = (LoggerContext) LogManager.getContext(false);
RollingFileAppender rfa = RollingFileAppender.newBuilder()
.withName("my runtime logger").withAppend(true)
.withFileName(fileName)
.withLayout(PatternLayout.newBuilder().withPattern("%-5p %d [%t] %C{2} - %m%n").build())
.withPolicy(TimeBasedTriggeringPolicy.newBuilder().withModulate(true).withInterval(2).build())
.withFilePattern(fileName + "." + "%d{yyyy-MM-dd-HH-mm}")
.setConfiguration(lc.getConfiguration()).build();
rfa.start();
lc.getConfiguration().addAppender(rfa);
lc.getRootLogger().addAppender(lc.getConfiguration().getAppender(rfa.getName()));
lc.updateLoggers();
}
}
Appender 名称与记录器名称没有关系,因此:
.withName("my runtime logger")
毫无意义。你还不如用"My appender"
什么的。
问题是这样的:
lc.getRootLogger().addAppender(
您正在将 Appender 添加到根记录器,所有其他记录器都继承自该根记录器,因此当然所有记录器都在使用它。尝试将 Appender 添加到您的记录器中:
lc.getLogger("my runtime logger").addAppender(