title: Configure log4j2 programmatically using ConfigurationFactory
body: <p>I'm trying to configure and set up Log4j2 only through using <a href="http://logging.apache.org/log4j/2.x/log4j-core/apidocs/org/apache/logging/log4j/core/config/ConfigurationFactory.html" rel="noreferrer"><code>ConfigurationFactory</code></a> and <a href="http://logging.apache.org/log4j/2.x/manual/extending.html" rel="noreferrer">this</a> reference. The code I'm using is as follows:</p>
  
  <pre><code>public class LoggingConfiguration {
  
      public static final String PATTERN_LAYOUT = "[%d] [%t] [%-5level] - %msg (%logger{1}:%L) %n%throwable";
      public static final String LOG_FILE_NAME = "app.log";
      public static final String LOG_FILE_NAME_PATTERN = LOG_FILE_NAME + "-yyyy.MM.dd";
  
      static {
          ConfigurationFactory.setConfigurationFactory(new Log4j2ConfigurationFactory());
      }
  
      /**
       * Just to make JVM visit this class to initialize the static parts.
       */
      public static void configure() {
      }
  
      @Plugin(category = "ConfigurationFactory", name = "Log4j2ConfigurationFactory")
      @Order(0)
      public static class Log4j2ConfigurationFactory extends ConfigurationFactory {
  
          @Override
          protected String[] getSupportedTypes() {
              return null;
          }
  
          @Override
          public Configuration getConfiguration(ConfigurationSource source) {
              return new Log4j2Configuration();
          }
  
          @Override
          public Configuration getConfiguration(String name, URI configLocation) {
              return new Log4j2Configuration();
          }
  
      }
  
      private static class Log4j2Configuration extends DefaultConfiguration {
  
          public Log4j2Configuration() {
              setName("app-log4j2");
              String root = System.getProperty("APP_ROOT", "/tmp");
              if (!root.endsWith("/")) {
                  root += "/";
              }
                              // MARKER
              Layout&lt;? extends Serializable&gt; layout = PatternLayout.createLayout(PATTERN_LAYOUT, null, null, null, null);
  
              String oneDay = TimeUnit.DAYS.toMillis(1) + "";
              String oneMB = (1024 * 1024) + "";
              final TimeBasedTriggeringPolicy timeBasedTriggeringPolicy = TimeBasedTriggeringPolicy.createPolicy(oneDay,
                      "true");
              final SizeBasedTriggeringPolicy sizeBasedTriggeringPolicy = SizeBasedTriggeringPolicy.createPolicy(oneMB);
              final CompositeTriggeringPolicy policy = CompositeTriggeringPolicy.createPolicy(timeBasedTriggeringPolicy,
                      sizeBasedTriggeringPolicy);
              final DefaultRolloverStrategy strategy = DefaultRolloverStrategy.createStrategy("7", "1", null,
                      Deflater.DEFAULT_COMPRESSION + "", this);
              Appender appender = RollingFileAppender.createAppender(root + LOG_FILE_NAME, LOG_FILE_NAME_PATTERN, "true",
                      "app-log-file-appender", "true", "true", policy, strategy, layout, null, null, null, null, null);
              addAppender(appender);
              getRootLogger().addAppender(appender, Level.INFO, null);
          }
      }
  
  }
  </code></pre>
  
  <p>Note that</p>
  
  <ul>
  <li>it extends <code>BaseConfiguration</code> that already configures console by default</li>
  <li>it tries to add a rolling file appender to the root logger</li>
  </ul>
  
  <p>I get the following exception:</p>
  
  <pre><code>Exception in thread "main" java.lang.IllegalStateException: Pattern does not contain a date
      at org.apache.logging.log4j.core.appender.rolling.PatternProcessor.getNextTime(PatternProcessor.java:91)
      at org.apache.logging.log4j.core.appender.rolling.TimeBasedTriggeringPolicy.initialize(TimeBasedTriggeringPolicy.java:49)
      at org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy.initialize(CompositeTriggeringPolicy.java:43)
      at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.&lt;init&gt;(RollingFileManager.java:58)
      at org.apache.logging.log4j.core.appender.rolling.RollingFileManager$RollingFileManagerFactory.createManager(RollingFileManager.java:297)
      at org.apache.logging.log4j.core.appender.rolling.RollingFileManager$RollingFileManagerFactory.createManager(RollingFileManager.java:267)
      at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:71)
      at org.apache.logging.log4j.core.appender.OutputStreamManager.getManager(OutputStreamManager.java:65)
      at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.getFileManager(RollingFileManager.java:78)
      at org.apache.logging.log4j.core.appender.RollingFileAppender.createAppender(RollingFileAppender.java:175)
      at com.narmnevis.papyrus.LoggingConfiguration$Log4j2Configuration.&lt;init&gt;(LoggingConfiguration.java:79)
      at com.narmnevis.papyrus.LoggingConfiguration$Log4j2ConfigurationFactory.getConfiguration(LoggingConfiguration.java:55)
      at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:377)
      at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:149)
      at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:85)
      at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:34)
      at org.apache.logging.log4j.LogManager.getContext(LogManager.java:200)
      at org.slf4j.helpers.Log4jLoggerFactory$PrivateManager.getContext(Log4jLoggerFactory.java:104)
      at org.slf4j.helpers.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:90)
      at org.slf4j.helpers.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:46)
      at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:270)
      at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:281)
      at com.narmnevis.papyrus.Main.&lt;init&gt;(Main.java:12)
      at com.narmnevis.papyrus.Main.main(Main.java:21)
  </code></pre>
  
  <p>If I comment out the code after <code>MARKER</code> in above code, it works but it seems that I'm missing something to configure a rolling file appender. What should I do to fix this?</p>