web-dev-qa-db-de.com

Log4J2 - Zuweisung des Dateinamens des Dateianhängers zur Laufzeit

Ich habe eine log4j2.xml-Konfigurationsdatei im Klassenpfad. Einer der Appender ist ein File Appender, und ich möchte den Namen der Zieldatei zur Laufzeit in der Java Anwendung festlegen.

Laut docs sollte ich in der Datei log4j2.xml ein doppeltes "$" und ein Kontextpräfix verwenden können:

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

dabei gibt das Präfix "sys" an, dass der Konfigurator die Eigenschaft "logFilename" in den Systemeigenschaften nachschlägt. Also rufe ich in der Bewerbung (ziemlich früh) auf:

System.setProperty("logFilename", filename);

Ich habe auch die automatische Rekonfiguration für log4j2 in der XML-Datei aktiviert:

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

Leider hat dies keinerlei Auswirkungen und die Protokolldatei wird nie erstellt. Einige der Statusausgaben von log4j2 sind unten aufgeführt:

2013-02-13 15: 36: 37,574 DEBUG Aufruf von createAppender für die Klasse org.Apache.logging.log4j.core.appender.FileAppender für das Element File with params (fileName = "$ {sys: logFilename}", append = "null" , locked = "null", name = "MyFile" ,mediateFlush = "null", suppressExceptions = "null", bufferedIO = "null", PatternLayout (% - 4r% d {jjjj-MM-tt/HH: mm: ss .SSS/zzz} [% t]% -5level% logger {36} -% msg% n), null)

2013-02-13 15: 36: 37,576 DEBUG Starten von FileManager $ {sys: logFilename}

Wie kann ich den Wert von "fileName" im File Appender zur Laufzeit festlegen? Alternativ kann ich einfach einen neuen File Appender hinzufügen der Root-Logger zur Laufzeit? In Log4j 2.0 ist der größte Teil der API zum Ändern der Konfiguration ausgeblendet.

41
user84756

Benutzer Der FileAppender unterstützt keine zwei Dollar-Zeichen für den Dateinamen, da die Datei beim Starten des Appenders geöffnet wird. Was Sie mit zwei Dollarzeichen angeben, ist, dass Sie - möglicherweise - für jedes Ereignis einen anderen Dateinamen wünschen.

Mit einem einzelnen $ (wie in ${sys:logFilename}) sucht das System in den Systemeigenschaften nach der Eigenschaft "logFilename".

Daher sollte die Datei log4j2.xml Folgendes enthalten:

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

Die Java -Anwendung sollte die Systemeigenschaft festlegen:

System.setProperty("logFilename", filename);

und Logger neu konfigurieren:

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

Dies erzeugt das gewünschte Verhalten.

46
user84756

Ab der log4j2-Version 2.5 ist dies am einfachsten zu erreichen:

In deiner log4j2.xml:

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

In dir Haupt MyApp.Java file:

public class MyApp {

    Logger log;

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

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

CATCH: Sie sollten die Systemeigenschaft logFilename festlegen, bevor log4j2 geladen wird. In diesem Beispiel vor dem Aufruf von LogManager.getLogger.

8
Alex Yursha

Ich weiß, dass dieses Thema alt ist, aber die Antworten passten nicht wirklich zu mir. Hier ist eine Funktion, mit der Sie einen vorhandenen Appender zur Laufzeit neu konfigurieren können:

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();
}

Sie können einen Dateinamen, den Namen Ihres Appenders und den Paketnamen angeben, den Sie protokollieren möchten.

Beispiel Logger:

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

Kann wie folgt umkonfiguriert werden:

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