web-dev-qa-db-ja.com

Log4J2-実行時にファイルアペンダーファイル名を割り当てる

クラスパスにlog4j2.xml構成ファイルがあります。アペンダーの1つはファイルアペンダーであり、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」プレフィックスは、Configuratorがシステムプロパティのプロパティ「logFilename」を検索することを示します。そのため、アプリケーションでは、(かなり早い段階で)呼び出します。

System.setProperty("logFilename", filename);

また、xmlファイルでlog4j2の自動再構成をオンにしました。

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

残念ながら、これはまったく効果がなく、ログファイルは作成されません。 log4j2ステータス出力の一部は次のとおりです。

2013-02-13 15:36:37,574 DEBUG params(fileName = "$ {sys:logFilename}"、append = "null"の要素Fileのクラスorg.Apache.logging.log4j.core.appender.FileAppenderでcreateAppenderを呼び出す、locking = "null"、name = "MyFile"、immediateFlush = "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デバッグFileManager $ {sys:logFilename}を開始しています

File Appenderの「fileName」の値を実行時に設定するにはどうすればよいですか?または、単に新しいFile Appenderを追加する方法実行時のルートロガー? Log4j 2.0では、構成を変更するためのほとんどのAPIは非表示になっています。

41
user84756

h/t rgoersアペンダーの起動時にファイルが開かれるため、FileAppenderはファイル名の2つのドル記号をサポートしません。あなたが2つのドル記号で示しているのは、あなたが望むことです-潜在的に-イベントごとに異なるファイル名。

単一の$で(${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();

これにより、目的の動作が生成されます。

46
user84756

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: log4j2をロードする前に、logFilenameシステムプロパティを設定する必要があります。この例では、LogManager.getLoggerを呼び出す前に。

8
Alex Yursha

私はこのトピックが古いことを知っていますが、答えは本当に私には合いませんでした。実行時に既存の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");
8