Программно создайте Log4j 2.x FileAppender

Я хочу перейти с Log4j 1.2 на 2.4. Поскольку я запускаю несколько экземпляров своей программы на одних и тех же машинах, я хочу включить идентификатор (называемый clientId в следующем коде) в файл журнала. Поэтому я использовал способ Log4j 1.2 для программной настройки FileAppender:

int clientId = ?// gets set before

FileAppender fa = new FileAppender();
fa.setName("FileLogger");
fa.setFile("logs/client_" + clientId + ".log");
fa.setLayout(new PatternLayout("%d %-5p %c{1} %m%n"));
fa.setThreshold(Level.INFO);
fa.setAppend(true);
fa.activateOptions();
Logger.getRootLogger().addAppender(fa);

Мне не удалось добиться чего-то подобного с Log4j 2.0, поскольку они убрали возможность напрямую изменять эти свойства. Вместо этого я попытался использовать CustomConfigurationFactory, как описано в https://logging.apache.org/log4j/2.x/manual/customconfig.html#Example Но я не понимаю, как мне это использовать? В документации указано

Это приведет к автоматическому подключению конфигурации к Log4j при создании LoggerContext.

Я пробовал что-то вроде:

LoggerContext context = (LoggerContext) LogManager.getContext(false);
context.getConfiguration(CustomConfigurationFactory.getInstance());

но это не работает.


person mohlerm    schedule 23.10.2015    source источник
comment
Вы уверены, что изменили его до создания LoggerContext? Возможно, вам придется как-то сообщить об этом для повторной инициализации.   -  person Jiri Tousek    schedule 23.10.2015


Ответы (1)


Я узнал это сам. Я изменил Factory, чтобы использовать FileAppender:

    builder.setConfigurationName(name);
    builder.setStatusLevel(Level.INFO);
    builder.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.NEUTRAL).
            addAttribute("level", Level.INFO));
    AppenderComponentBuilder appenderBuilder = builder.newAppender("file", "FILE").
            addAttribute("fileName", "log/client_"+Config.CLIENTID+".log");
    appenderBuilder.add(builder.newLayout("PatternLayout").
            addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
    appenderBuilder.add(builder.newFilter("MarkerFilter", Filter.Result.DENY,
            Filter.Result.NEUTRAL).addAttribute("marker", "FLOW"));
    builder.add(appenderBuilder);
    builder.add(builder.newLogger("org.apache.logging.log4j", Level.INFO).
            add(builder.newAppenderRef("file")).
            addAttribute("additivity", false));
    builder.add(builder.newRootLogger(Level.INFO).add(builder.newAppenderRef("file")));
    return builder.build();

А затем используйте:

ConfigurationFactory.setConfigurationFactory(new CustomConfigurationFactory());
Logger log = LogManager.getLogger(Main.class.getName());

чтобы получить новый регистратор

person mohlerm    schedule 23.10.2015
comment
Если вам нужно динамически поддерживать несколько клиентов, вы также можете просто использовать для этого RoutingAppender. Если вам нужно поддерживать только одного клиента, вы можете просто указать ${sys:clientId} в имени файла. Тогда вам не нужно было бы писать код. - person rgoers; 24.10.2015