为什么 Log4j2 不允许多次重新配置包记录器

Why Log4j2 does not allow to reconfigure package logger more than once

我在我的应用程序中使用 Log4j2。我们需要提供一种工具来在运行时重新配置日志记录以帮助应用程序调试。例如,我们应该能够在运行时添加新的包级记录器、class 级记录器等。我在这里提出的问题陈述是针对包级记录器配置的。请检查以下代码:

LogConfigurer.java

public class LogConfigurer {
  public static void addPackageLogger(final String packageName, final Level level) {
    final LoggerContext context = (LoggerContext) LogManager.getContext(false);
    final Configuration configuration = context.getConfiguration();

    final Appender appender = configuration.getAppender("RollingRandomAccessFile");
    final LoggerConfig loggerConfig = new LoggerConfig(packageName, level, false);
    loggerConfig.addAppender(appender, level, null);
    configuration.addLogger(packageName, loggerConfig);
    context.updateLoggers();
  }
}

PackageLoggingMock.java(样本class)

public class PackageLoggingMock {
  // Logger
  private final static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(PackageLoggingMock.class);

  public void mockMethod(final String msg) {
    logger.debug("[PackageLoggingMock] Debug statement...{}", msg);
    logger.info("[PackageLoggingMock] Info statement...{}", msg);
    logger.warn("[PackageLoggingMock] Warn statement...{}", msg);
    logger.error("[PackageLoggingMock] Error statement...{}", msg);
  }
}

PackageLoggingDemo.java

public class PackageLoggingDemo {
  public static void main(final String[] args) {
    final PackageLoggingMock mock = new PackageLoggingMock();

    // Running with default settings provided in log4j2.xml
    mock.mockMethod("BEFORE");

    // Reset log level of package "com.logging.demo" to DEBUG
    try {
      LogConfigurer.addPackageLogger("com.logging.demo", Level.DEBUG);
    } catch (final Exception e) {
      e.printStackTrace();
    }

    // After resetting to DEBUG level
    mock.mockMethod("AFTER SETTING TO DEBUG");

    // Reset log level of package "com.logging.demo" to INFO
    try {
      LogConfigurer.addPackageLogger("com.logging.demo", Level.INFO);
    } catch (final Exception e) {
      e.printStackTrace();
    }

    // After resetting to DEBUG level
    mock.mockMethod("AFTER SETTING TO INFO");
  }
}

输出

[PackageLoggingMock] Error statement...BEFORE
[PackageLoggingMock] Debug statement...AFTER SETTING TO DEBUG
[PackageLoggingMock] Info statement...AFTER SETTING TO DEBUG
[PackageLoggingMock] Warn statement...AFTER SETTING TO DEBUG
[PackageLoggingMock] Error statement...AFTER SETTING TO DEBUG
[PackageLoggingMock] Debug statement...AFTER SETTING TO INFO
[PackageLoggingMock] Info statement...AFTER SETTING TO INFO
[PackageLoggingMock] Warn statement...AFTER SETTING TO INFO
[PackageLoggingMock] Error statement...AFTER SETTING TO INFO

即使级别已重新配置为 INFO,它仍会打印 DEBUG 语句。

我无法理解这种行为;是否符合预期?

作为一种变通方法,在第一次重新配置后(级别 DEBUG),我尝试将记录器重置为具有原始配置,然后以编程方式应用 INFO 级别并且它起作用了。

有没有办法在不重置日志的情况下多次配置日志级别?

您只是在添加。要进行更改,您必须删除该包的旧配置并添加新配置。

根据这个提示,OP 使用了

configuration.removeLogger(packageName);
configuration.addLogger(packageName, loggerConfig);

解决问题。