Подтвердить что ты не робот

Log4J2 - назначение имени файла файла appender во время выполнения

У меня есть файл конфигурации log4j2.xml в пути к классу. Один из добавлений - это приложение для файлов, и я хотел бы установить имя целевого файла во время выполнения приложения Java.

В соответствии с docs я должен использовать двойной файл $и префикс контекста в файле log4j2.xml:

<appenders>
    <File name="MyFile" fileName="$${sys:logFilename}">
        <PatternLayout pattern="%-4r %d{${datestamp}} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
</appenders>

где префикс "sys" указывает, что Конфигуратор будет искать свойство "logFilename" в свойствах системы. Поэтому в приложении я вызываю (скорее рано):

System.setProperty("logFilename", filename);

Я также включил автоматическую реконфигурирование для log4j2 в XML файле:

<configuration status="debug" monitorInterval="5">>

К сожалению, это не имеет никакого эффекта, и файл журнала никогда не создается. Ниже приведено состояние выхода log4j2:

2013-02-13 15: 36: 37 574 DEBUG Вызов createAppender в классе org.apache.logging.log4j.core.appender.FileAppender для элемента Файл с параметрами (fileName = "$ {sys: logFilename}", append = "null" , lock = "null" , name= "MyFile", немедленноеFlush = "null" , suppressExceptions = "null" , bufferedIO = "null" , PatternLayout (% - 4r% d {yyyy-MM-dd/HH: mm: ss.SSS/zzz} [% t]% -5level% logger {36} -% msg% n), null)

2013-02-13 15: 36: 37 576 DEBUG Запуск FileManager ${sys: logFilename}

Как я могу установить значение "имя_файла" в File Appender во время выполнения? В качестве альтернативы, как я могу просто добавить новый File Appender в корневой журнал во время выполнения? В Log4j 2.0 большая часть API для изменения конфигурации скрыта.

4b9b3361

Ответ 1

h/t rgoers FileAppender не поддерживает два знака доллара в имени файла, поскольку файл открывается при запуске appender. То, что вы указываете двумя знаками доллара, - это то, что вы хотите - потенциально - другое имя файла для каждого события.

С единственным $(как в ${sys:logFilename}) система будет искать свойство "logFilename" в свойствах системы.

Таким образом, log4j2.xml должен иметь:

<appenders>
    <File name="MyFile" fileName="${sys:logFilename}">
        <PatternLayout pattern="%-4r %d{${datestamp}} [%t] %-5level %logger{36} - %msg%n"/>
    </File>
</appenders>

Приложение Java должно установить системное свойство:

System.setProperty("logFilename", filename);

и перенастроить регистратор:

org.apache.logging.log4j.core.LoggerContext ctx =
    (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
ctx.reconfigure();

Это создает желаемое поведение.

Ответ 2

Как и для версии log4j2 2,5, это самый простой способ добиться этого:

В log4j2.xml:

<Appenders>
   <File name="MyFile" filename="${sys:logFilename}">
   ...

В главном MyApp.java файле:

public class MyApp {

    Logger log;

    static {
          System.setProperty("logFilename", ...);
          log = LogManager.getLogger();
    }

    public static void main(String... args) {...}
}

CATCH: Вы должны установить системное свойство logFilename перед загрузкой log4j2. В этом примере перед вызовом LogManager.getLogger.

Ответ 3

Я знаю, что эта тема старая, но ответы мне не очень понравились. Вот функция, которая позволяет вам перенастроить существующий Appender во время выполнения:

static void updateLogger(String file_name, String appender_name, String package_name){
LoggerContext context = (LoggerContext) LogManager.getContext(false);
    Configuration configuration = context.getConfiguration();
    Layout<? extends Serializable> old_layout = configuration.getAppender(appender_name).getLayout();

    //delete old appender/logger
    configuration.getAppender(appender_name).stop();
    configuration.removeLogger(package_name);

    //create new appender/logger
    LoggerConfig loggerConfig = new LoggerConfig(package_name, Level.INFO, false);
    FileAppender appender = FileAppender.createAppender(file_name, "false", "false", appender_name, "true", "true", "true",
            "8192", old_layout, null, "false", "", configuration);
    appender.start();
    loggerConfig.addAppender(appender, Level.INFO, null);
    configuration.addLogger(package_name, loggerConfig);

    context.updateLoggers();
}

Вы можете указать имя файла, имя вашего приложения и имя пакета, которое вы хотите зарегистрировать.

Пример регистратора:

<File name="fileWriter_api" fileName="${LOG_DIR}/api.log" append="false">
  <PatternLayout pattern="${PATTERN}"/>
</File>

Можно перенастроить вызов следующим образом:

updateLogger("log/api_new.log", "fileWriter_api", "my.package");