Log4J2 - assigning file appender filename at runtime

Solution 1:

h/t rgoers The FileAppender doesn't support two dollar signs on the file name as the file is opened when the appender is started. What you are indicating with two dollar signs is that you want - potentially - a different file name for each event.

With a single $ (as in ${sys:logFilename}), the system will look for property "logFilename" in the system properties.

Thus, the log4j2.xml should have:

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

The Java application should set the system property:

System.setProperty("logFilename", filename);

and reconfigure the logger:

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

This produces the desired behavior.

Solution 2:

As of log4j2 version 2.5 here is the simplest way to achieve this:

In your log4j2.xml:

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

In you main MyApp.java file:

public class MyApp {

    Logger log;

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

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

CATCH: You should set logFilename system property before log4j2 is loaded. In this example before calling LogManager.getLogger.