2013-02-13 4 views
28

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

Согласно 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: 37574 DEBUG Вызов createAppender на классе org.apache.logging.log4j.core.appender.FileAppender для элемента Файл с Params (имя_файла = "$ {sys: logFilename}", append = "null", lock = "null", name = "MyFile", instantFlush = "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 для изменения конфигурации скрыта.

+0

Делает SO поиска. Он уже ответил: http://stackoverflow.com/questions/10699358/log4j-creating-modifying-appenders-at-runtime-log-file-recreated-and-not-appe – mightyrick

+7

Это Log4j 2.0, поэтому API очень отличается от Log4j 1.2, и многие из методов предыдущих ответов не отображаются. – user84756

ответ

30

ч/т 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(); 

Это приводит к желаемому поведению.

+1

Я не уверен, что это связано с тем, что API изменился, но для меня это не сработало. То, что я должен был сделать, чтобы заставить это работать, было сделать '$ {sys: logFilename}' – rm5248

+0

Вы правы - это была опечатка в исходном ответе. Исправлено сейчас. Благодаря! – user84756

+1

Используя версию '2.0-beta9' и один' '', это создаст два файла: один с правильным именем, но пустым содержимым, а один со всем выходом журнала с буквой '$ {sys: logFilename} .log'. – amoe

7

начиная с версии 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.

+1

Это не работает, оно просто создает файл '$ {sys/logFilename}' – Akshay

+0

Это работало для меня в автономном приложении командной строки. У вас могут возникнуть проблемы, потому что какой-то другой код, который вы зависеть, инициализирует log4j2 раньше, чем вы думаете. Не могли бы вы описать среду, в которой вы это пробовали? Это веб-приложение или инструмент командной строки? –

+0

+1 за предупреждение! Это уловка. Я пытался это сделать, но всегда получал второй пустой файл '$ {sys/logFilename}'. – Chris

6

Я знаю, что эта тема старая, но ответы мне не очень понравились. Вот функция, которая позволяет перенастроить существующий 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(); 
} 

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

Пример Logger:

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

Можно перенастроить вызов, как это:

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

Это отличный ответ! – FrustratedWithFormsDesigner

+0

Это работает для названного appender и пакета, но останавливает все остальные приложения. Вы видели эту проблему и знаете, как обойти ее, случайно? – biggvsdiccvs

+0

Я оставил бы спецификацию leve.INFO в строке 'loggerConfig.addAppender (appender, Level.INFO, null);', поскольку это сделает невозможным запись событий DEBUG или TRACE через этот appender, даже если вы измените log loglogger. – mitchnull