Журналы Log4j2 не указывают на исправление файла журнала - PullRequest
0 голосов
/ 16 июня 2020

Я столкнулся с проблемой при программной настройке журналов log4j2.

См. Приведенный ниже код. Я создаю 2 объекта класса App3 и хочу создать 2 файла журнала отладки (файл журнала для каждого объекта App3), после чего каждый объект должен иметь возможность вести журнал для соответствующего файл журнала.

Но мой код записывает все журналы во второй файл журнала после создания второго журнала. Может ли кто-нибудь помочь в этом.

Вывод программы

Имя файла: app3_logger1.log_debug.log

2020-06-16 16:19:31,100 DEBUG app3_logger1.log [main] Hello from Log4j 2app3_logger1

Имя файла : app3_logger2.log_debug.log

2020-06-16 16:19:31,211 DEBUG app3_logger2.log [main] Hello from Log4j 2app3_logger2
2020-06-16 16:19:31,216 DEBUG app3_logger2.log [main] Hello from Log4j 2app3_logger2
2020-06-16 16:19:31,216 DEBUG app3_logger1.log [main] Hello from Log4j 2app3_logger1
2020-06-16 16:19:31,216 DEBUG app3_logger1.log [main] Hello from Log4j 2app3_logger1
2020-06-16 16:19:31,217 DEBUG app3_logger2.log [main] Hello from Log4j 2app3_logger2

Java Класс - вам просто нужно добавить зависимости log4j2 для компиляции

public class App3 {

public Logger logger;

public static void main(String[] args) {
    App3 app1 = new App3();
    app1.initializeYourLogger("app3_logger1.log", "%d %p %c [%t] %m%n");
    app1.testProg("app3_logger1");
    App3 app2 = new App3();
    app2.initializeYourLogger("app3_logger2.log", "%d %p %c [%t] %m%n");
    app2.testProg("app3_logger2");

    app2.testProg("app3_logger2");
    app1.testProg("app3_logger1");
    app1.testProg("app3_logger1");
    app2.testProg("app3_logger2");

}

public void testProg(String s) {
    logger.debug("Hello from Log4j 2" + s);
}

public void initializeYourLogger(String fileName, String pattern) {
    this.logger = LogManager.getLogger(fileName);
    ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();

    builder.setStatusLevel(Level.DEBUG);
    builder.setConfigurationName(fileName);

    AppenderComponentBuilder componentBuilder = builder.newAppender("log", "File");
    componentBuilder.add(builder.newLayout("PatternLayout").addAttribute("pattern", pattern));
    RootLoggerComponentBuilder rootLogger = builder.newRootLogger(Level.DEBUG);

    LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout").addAttribute("pattern", pattern);
    ComponentBuilder triggeringPolicy = builder.newComponent("Policies")
            .addComponent(builder.newComponent("SizeBasedTriggeringPolicy").addAttribute("size", "10MB"));

    componentBuilder = builder.newAppender("LogToRollingErrorFile", "RollingFile")
            .add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.DENY)
                    .addAttribute("level", Level.ERROR))
            .addAttribute("fileName", fileName + "_error.log")
            .addAttribute("filePattern", fileName + "-%d{MM-dd-yy-HH-mm-ss}_error.log").add(layoutBuilder)
            .addComponent(triggeringPolicy);
    builder.add(componentBuilder);

    componentBuilder = builder.newAppender("LogToRollingDebugFile", "RollingFile")
            .add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.DENY)
                    .addAttribute("level", Level.DEBUG))
            .addAttribute("fileName", fileName + "_debug.log")
            .addAttribute("filePattern", fileName + "-%d{MM-dd-yy-HH-mm-ss}_debug.log").add(layoutBuilder)
            .addComponent(triggeringPolicy);
    builder.add(componentBuilder);

    AppenderRefComponentBuilder rollingError = rootLogger.getBuilder().newAppenderRef("LogToRollingErrorFile");
    AppenderRefComponentBuilder rollingDebug = rootLogger.getBuilder().newAppenderRef("LogToRollingDebugFile");
    rootLogger.add(rollingError);
    rootLogger.add(rollingDebug);
    builder.add(rootLogger);
    Configurator.reconfigure(builder.build());
}

} ​​

Это именно то, что я хочу сделать в более старой версии log4j, я все еще борюсь с log4j2,

    private void initLogger(String serviceName, String instance) throws IOException {
    String loggerName = serviceName+"_"+instance;
    this.logger = Logger.getLogger(loggerName);
    this.logger.removeAllAppenders();

    PatternLayout layout = new PatternLayout();
    layout.setConversionPattern("%d: %m%n");

    String loggingFolder = this.properties.getLoggingFolder();
    String debugFileName = loggingFolder+"/"+loggerName+"_debug.log";
    String errorFileName = loggingFolder+"/"+loggerName+"_error.log";

    RollingFileAppender debugAppender = new RollingFileAppender(layout, debugFileName, true);
    debugAppender.setThreshold(Level.DEBUG);
    debugAppender.setMaxFileSize("10000000");
    debugAppender.setMaxBackupIndex(49);
    logger.addAppender(debugAppender);

    RollingFileAppender errorAppender = new RollingFileAppender(layout, errorFileName, true);
    errorAppender.setThreshold(Level.ERROR);
    errorAppender.setMaxFileSize("10000000");
    errorAppender.setMaxBackupIndex(49);
    logger.addAppender(debugAppender);
}

Ответы [ 2 ]

1 голос
/ 17 июня 2020

На самом деле, я совершенно уверен, что ваш Регистратор обновляется правильно. Проблема в том, что оба экземпляра приложения будут использовать одну и ту же конфигурацию ведения журнала.

Если вы посмотрите на архитектуру Log4j , вы увидите, что регистраторы и конфигурация привязаны к LoggerContext. По умолчанию Log4j использует ClassLoaderContextSelector, что означает, что каждый ClassLoader может иметь свой собственный LoggerContext. В вашем примере приложения есть только один ClassLoader, поэтому будет только один LoggerContext и, следовательно, только одна конфигурация.

Итак, когда вы перенастраивали во второй раз, вы просто заменили предыдущую конфигурацию на новую. Поскольку регистратор root обрабатывает все события журнала, он перенаправляет события от обоих регистраторов, которые вы создали, в файл, созданный во второй конфигурации.

Если вы хотите, чтобы журналы заканчивались в двух разных файлах, создайте конфигурацию с обоими файлами и выясните, как направить их в нужный файл, используя имена регистраторов или фильтры.

0 голосов
/ 17 июня 2020

Согласно наблюдению, ваш регистратор обновляется с помощью последней инициализации, поэтому после app2.initializeYourLogger() ваш объект уровня logger объект обновлен с конфигурацией App2.

Вам необходимо вернуть объект регистратора из initializeYourLogger() а также создать отдельный объект Logger.

...