Как настроить Logger Programmatically в log4j2.02?

Я хочу использовать log4j без любого файла конфигурации. То, что я хотел сделать, это что-то вроде:

logger = (Logger) LogManager.getLogger(this.getClass());
String pattern = "[%level] %m%n";
//do something to make this logger output to an local file "/xxx/yyy/zzz.log"

Я нашел этот ответ: Программировать Log8j Loggers Programmatically.

Но в документах Logger#addAppender говорится: Этот метод не открыт через открытый API и используется в основном для модульного тестирования.

Я не уверен, что это правильный способ использовать этот метод в моем коде или есть другое лучшее решение для решения моей проблемы.

Ответ 1

Официальная документация показывает пример: Программное добавление к текущей конфигурации

final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();

Layout layout = PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, null, null,null, null);
Appender appender = FileAppender.createAppender("target/test.log", "false", "false", "File", "true", "false", "false", "4000", layout, null, "false", null, config);
appender.start();
config.addAppender(appender);

AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
AppenderRef[] refs = new AppenderRef[] {ref};
LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", "org.apache.logging.log4j", "true", refs, null, config, null );
loggerConfig.addAppender(appender, null, null);
config.addLogger("org.apache.logging.log4j", loggerConfig);
ctx.updateLoggers();

С этими ограничениями:

  • Если файл конфигурации будет изменен, конфигурация будет перезагружена, и ручные изменения будут потеряны.
  • Модификация текущей конфигурации требует, чтобы все вызываемые методы (addAppender и addLogger) были синхронизированы.

Это решение избегает использования метода из основной реализации org.apache.logging.log4j.core.Logger, и оно позволяет избежать такого скрытого использования:

import org.apache.logging.log4j.Logger;

Logger logger = (Logger) LogManager.getLogger(this.getClass());
((org.apache.logging.log4j.core.Logger) logger).addAppender(...); // Bypassing the public API 

Ответ 2

Если я просто отвечу на ваше требование, я могу предложить три варианта. Я использую первую для своего рода загрузочную конфигурацию Logger; однако я думал, что сначала потребуется вторая. Ваш третий выбор кажется громоздким, так как вам нужно вызвать различные API-интерфейсы log4j для настройки.

Использование Log4j над простой структурой ведения журнала для Java...

  • Создайте файл минимального или стандартного файла log4j.properties в своих ресурсах для файла JAR. Затем объявите некоторые статистические данные...

    private static final  URL LOGGER_CONFIG_URL  = resolveConfigUrl();
       :
    
    private static URL  resolveConfigUrl(){
    
        URL url = LogConfig.class.getResource( LOGGER_CONFIG_NAME );
    
        if( null == url )  // Second chance, try for a file.
        {
            url = FileHelp.resolveUrlNameAsUrlToFile( LOGGER_CONFIG_NAME );
                      //-- Make this function with: url = tmpFile.toURI().toURL()
                      //   Plus appropriate try/catch and error checks.
          }
          return url;
    } 
    
    private static void  configureLogger(){
    
        BasicConfigurator.configure();
        PropertyConfigurator.configure( LOGGER_CONFIG_URL  );
        LOG.info( "Logging config done: " +  LOGGER_CONFIG_NAME );
    }
    
  • Напишите свою конфигурацию в StreamWriter вместо размещения файла в JAR, а затем передайте Stream в конфигуратор журнала в виде StringReader и используйте пример выше (более или менее).

  • Вы можете использовать slf4j API, чтобы выполнить свою конфигурацию журнала, а не напрямую писать в Log4j. В большинстве мест я предпочитаю маршрут SLF4J.

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

Способ, которым я использую # 1, - установить конфигурацию регистратора по умолчанию /bootstrap через файл ресурсов, который сам поместится в файл JAR. Вы можете переконфигурировать вещи "позже", в то время как этот параметр дает минималистскую конфигурацию "стартовый" или "загрузочный". На ранних этапах я обнаружил, что все еще не было зарегистрировано, потому что инициализация регистратора еще не была выполнена во встроенных приложениях. Таким образом, я сохранял простой вариант для начальной загрузки (или по умолчанию) в качестве основного с тех пор. Надеюсь, это поможет.

Ответ 3

С последней версией log4j2 все создают API, такие как

PatternLayout.createLayout, 
FileAppender.createAppender, 
LoggerConfig.createLogger 

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