title: How to catch errors during log4j2 initialization?
body: <p>We don't consider our app running properly if <code>log4j2</code> isn't configured properly as specified in the config file. How do i reliably detect whether errors have occurred during <code>log4j2</code> initialization and been printed on the console from java? There are (at least) two sources of bad configuration:</p>
  
  <ol>
  <li>The configuration file is entirely missing (or invalid?)</li>
  <li>The configuration file is valid, but has a problem during <code>setConfiguration()</code>.</li>
  </ol>
  
  <p>This question is about the second point. It looks like <code>log4j2</code> internally does <code>try{...} catch(e) { LOGGER.error("bla bla", e) }</code> during initialization making it impossible to detect such problems.</p>
  
  <p>Errors printed to the console that no human is ever going to see is <em>bad</em>. We'd rather have our app crash!</p>
  
  <p>I'm surprised that I can't find a way to programmatically ask <code>log4j2</code>: "Did I get the configuration I asked for?". Is there something I have overlooked? E.g. some way to detect whether <em>anything</em> has been logged yet?</p>
  
  <h1>Background</h1>
  
  <p>Here is the console output we're seeing. Yes, there is permission denied to <code>/path/to/file</code> - how do I detect that?</p>
  
  <pre><code>2015-10-15 17:43:50,539 main ERROR FileManager (/path/to/file) java.io.FileNotFoundException: /path/to/file (Permission denied)
  2015-10-15 17:43:50,541 main ERROR Unable to invoke factory method in class class org.apache.logging.log4j.core.appender.FileAppender for element File. java.lang.reflect.InvocationTargetException
          at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
          at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
          at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
          at java.lang.reflect.Method.invoke(Method.java:497)
          at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:136)
          at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:794)
          at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:734)
          at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:726)
          at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:383)
          at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:161)
          at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:173)
          at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:422)
          at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:494)
          at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:510)
          at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:199)
          at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:146)
          at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:41)
          at org.apache.logging.log4j.LogManager.getContext(LogManager.java:177)
          at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:447)
          at (our first call to org.apache.logging.log4j.LogManager.getLogger())
  </code></pre>
  
  <p>Looking in the code for <code>LoggerContext.reconfigure()</code>, I see:</p>
  
  <pre><code>private void reconfigure(final URI configURI) {
      &lt;snip&gt;
      final Configuration instance = ConfigurationFactory.getInstance().getConfiguration(name, configURI, cl);
      setConfiguration(instance);
      &lt;snip&gt;
  }
  </code></pre>
  
  <p>And during the call of <code>setConfiguration()</code>, there is this in <code>org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build</code>:</p>
  
  <pre><code>    try {
          &lt;snip&gt;
          final Object plugin = factory.invoke(null, params);
          &lt;snip&gt;
          return plugin;
      } catch (final Exception e) {
          LOGGER.error("Unable to invoke factory method in class {} for element {}.", this.clazz, this.node.getName(),
              e);
          return null;
      }
  </code></pre>
  
  <p>So the problem was not with <code>getConfiguration()</code> from the <code>ConfigurationFactory</code>, but with the subsequent <code>setConfiguration()</code>, and there seems to be no way to detect that there was a problem... :-(</p>
  
  <h2>About the first point: The configuration file is entirely missing (or invalid?)</h2>
  
  <p>We're setting <code>-Dlog4j.configurationFile=&lt;file&gt;</code> on the java command line, and there are already <a href="https://stackoverflow.com/questions/32250527/how-to-detect-missing-log4j2-config">several</a> posts on how to detect if <code>&lt;file&gt;</code> is missing. <a href="https://stackoverflow.com/questions/30583836/how-to-check-if-log4j2-has-been-configured-or-not">One of which</a> suggests to <code>-Dlog4j.configurationFactory</code> with our own <code>ConfigurationFactory</code>.  But no amount of fiddling with our own <code>ConfigurationFactory</code> is going to help during <code>setConfiguration()</code> to detect the second point ("2." above) as far as I can reason.</p>
  
  <p>We're running log4j2 version 2.4 on openjdk 8 on debian stable/jessie.</p>