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 для изменения конфигурации скрыта.
Ответы
Ответ 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");