title: How to replace the default log4j2 configuration programmatically?
body: <p>Today I have a problem to reconfigure the log4j2 configuration correctly. To explain the problem I created a sample application that matches nearly our productive code. The sample project structure is shown in the following picture:</p>
  
  <p><a href="https://i.stack.imgur.com/LnOcv.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/LnOcv.png" alt="enter image description here"></a></p>
  
  <p>For developer purpose we want to start the main application with a wrapper class to configure some parameter like logging configuration or system properties which should not be placed in the productive code. Therefore the productive log4j2 configuration should be replaced by the developer one to set the log level more specific and avoid a file appending of the log entries. Following is the code for the productive main class:</p>
  
  <pre><code>package logging.log4j2;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  public class MainApp {
  
      private final Log LOG = LogFactory.getLog(MainApp.class);
      private final String[] commandLineArgs;
  
      public static void main(String[] args) {
          MainApp app = new MainApp(args);
          app.start();
      }
  
      protected MainApp(String[] args) {
          commandLineArgs = args;
      }
  
      public void start() {
          LOG.info("Starting MainApp application ...");
  
          // ... do main application stuff here
          LOG.debug("This is only for DEBUG mode.");
      }
  }
  </code></pre>
  
  <p>Now the code for the developer wrapper main class:</p>
  
  <pre><code>package logging.log4j2;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  import java.net.URL;
  
  public class DevWrapperMainApp extends MainApp {
  
      private static final Log LOG = LogFactory.getLog(DevWrapperMainApp.class);
      public static final String PROP_LOG4J_CONFIGURATION_FILE = "log4j.configurationFile";
  
      protected DevWrapperMainApp(String[] args) {
          super(args);
      }
  
      public static void main(String[] args) {
          preconfigureDevMode();
          DevWrapperMainApp devApp = new DevWrapperMainApp(args);
          devApp.start();
      }
  
      private static void preconfigureDevMode() {
          LOG.debug("Preconfigure application for deveoper mode ...");
          String log4j2ConfigFilePath =    System.getProperty(PROP_LOG4J_CONFIGURATION_FILE);
          if(log4j2ConfigFilePath == null || log4j2ConfigFilePath.isEmpty()) {
              URL configResource = DevWrapperMainApp.class.getResource("/dev-log4j2.xml");
              if(configResource != null) {
                  System.setProperty(PROP_LOG4J_CONFIGURATION_FILE, configResource.toExternalForm());
              } else {
                  LOG.error("Set log4j2 configuration file property failed. Resource file could not be detected correctly.");
              }
          }
      }
  }
  </code></pre>
  
  <p>The logging of the productive application is configured by the <em>log4j2.xml</em>:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;Configuration name="productiveConfig" status="WARN" monitorInterval="5"&gt;
      &lt;properties&gt;
          &lt;property name="log.pattern.layout"&gt;%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n&lt;/property&gt;
      &lt;/properties&gt;
  
      &lt;Appenders&gt;
          &lt;Console name="Console" target="SYSTEM_OUT"&gt;
              &lt;PatternLayout pattern="${sys:log.pattern.layout}"/&gt;
          &lt;/Console&gt;
      &lt;/Appenders&gt;
      &lt;Loggers&gt;
          &lt;Root level="INFO"&gt;
              &lt;AppenderRef ref="Console"/&gt;
          &lt;/Root&gt;
      &lt;/Loggers&gt;
  &lt;/Configuration&gt;
  </code></pre>
  
  <p>For the sample app there is no file appender but the logging level and the name of the configuration is different from the following <em>dev-log4j2.xml</em>:</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;Configuration name="developerConfig" status="DEBUG" monitorInterval="5"&gt;
      &lt;properties&gt;
          &lt;property name="log.pattern.layout"&gt;DEV-MODE: %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n&lt;/property&gt;
      &lt;/properties&gt;
  
      &lt;Appenders&gt;
          &lt;Console name="Console" target="SYSTEM_OUT"&gt;
              &lt;PatternLayout pattern="${sys:log.pattern.layout}"/&gt;
          &lt;/Console&gt;
      &lt;/Appenders&gt;
      &lt;Loggers&gt;
          &lt;Root level="DEBUG"&gt;
              &lt;AppenderRef ref="Console"/&gt;
          &lt;/Root&gt;
      &lt;/Loggers&gt;
  &lt;/Configuration&gt;
  </code></pre>
  
  <p>By running the <em>DevWrapperMainApp</em> class I get the following output:</p>
  
  <pre><code>"C:\Program Files\Java\jdk1.8.0_66\bin\java" ...
  11:40:14.553 [main] INFO  logging.log4j2.MainApp - Starting MainApp application ...
  
  Process finished with exit code 0
  </code></pre>
  
  <p>In addition to the <em>INFO</em> logging I expected the output of the <em>DEBUG</em> logging as well. Therefore the log configuration seems not to be reconfigured by override the system property at that moment. Maybe it is to late and log4j2 is allready configured by the productive configuration file? How can I change the whole configuration at the startup time of my application? The documentation says:</p>
  
  <blockquote>
    <p>However, should any logging be attempted before Configurator.initialize() is called then the default configuration will be used for those log events. (Part: <a href="https://logging.apache.org/log4j/2.x/manual/customconfig.html" rel="nofollow noreferrer">Reconfigure Log4j Using ConfigurationBuilder with the Configurator</a></p>
  </blockquote>
  
  <p>Maybe somebody has a hint for me to go in the right direction? I also know the possibility to create a <em>log4j2-test.xml</em> for the developing purpose but a want to avoid this and also to set the system property. The code should be known where to find the configuration file.</p>
  
  <p>Thanks in advance.</p>
  
  <p>Hardie</p>