title: Configuring log4j under WebSphere Application Server
body: <p>We have a bunch of applications being deployed on Webshere Application Server (WAS). Somewhere on the class path we have a very basic log4j.properties with that looks similar to below:</p>
  
  <pre><code>log4j.rootLogger=ERROR, FILE, CONSOLE
  
  # 
  # CONSOLE appender is a ConsoleAppender
  #
  log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
  log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
  log4j.appender.CONSOLE.layout.ConversionPattern=%X{component} [%-5p] %c - %m%n
  
  # 
  # FILE appender is a FileAppender
  #
  log4j.appender.FILE=org.apache.log4j.RollingFileAppender
  log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
  log4j.appender.FILE.layout.ConversionPattern=##%d{dd-MM-yyyy HH:mm:ss,SSS} %X{component} [%-5p] %c - %m%n
  
  #
  # MyApp Debug Levels.
  #
  log4j.logger.com.my.company.my.app=INFO
  </code></pre>
  
  <p>Note the missing <code>log4j.appender.FILE.File</code> File from our log4j.properties, This is configured art WAS level via <code>Application Servers -&gt; MyServer -&gt; Logging and tracing -&gt; JVM Logs</code> with the file name set as below:</p>
  
  <pre><code>${SERVER_LOG_ROOT}/SystemOut.log
  </code></pre>
  
  <p>Changing the debug level works fine e.g. adding to the log4j.properties the following line will result in getting debug entries for <code>MySpecialClass</code> in the logs.</p>
  
  <pre><code>log4j.logger.com.my.company.my.app.MySpecialClass=DEBUG
  </code></pre>
  
  <p>That makes me conclude that my properties file is considered.</p>
  
  <p>However we recently received a request that in addition to the normal log entries to output some special log entries (application error related logs) to a separate file. My initial thought was to add one more rolling file appender and leave that do the work. To my surprise it did not work, everything related to that appender was just ignored.</p>
  
  <p>Then I thought this may be because the log file is configured in WAS and everything goes there regardless of what we put in the log4j.properties and I said it looks a bit odd to have multiple apps writing to the same log file. However I did not want to spend too much time on this and because the special log entries were the <code>error</code> ones I just said lets just use the existing WAS feature of having a separate file for System.Err logs: <code>Application Servers -&gt; MyServer -&gt; Logging and tracing -&gt; JVM Logs</code>:</p>
  
  <pre><code>${SERVER_LOG_ROOT}/SystemErr.log
  </code></pre>
  
  <p>To achieve this I created my own <code>com.my.company.my.app.CustomPatternLayout</code> and implemented this very basic format method:</p>
  
  <pre><code>public String format(LoggingEvent event) {
      String log = patternLayout.format(event);
      Level logLevel = event.getLevel();
      if (Level.ERROR.equals(logLevel) || Level.WARN.equals(logLevel)
              || log.contains("Exception") || log.contains("PEM_LOGGER_SEV3")) {
          System.err.println(log);
      }
      return log;
  }
  </code></pre>
  
  <p>I also replaced the file appender in log4j.properties to use my custom pattern layout</p>
  
  <pre><code>log4j.appender.FILE.layout.com.my.company.my.app.CustomPatternLayout
  </code></pre>
  
  <p>Again nothing happened in my logs and the expected log entries never got written to the SystemErr.log. More than this I set some debug breakpoints and my code never gets executed. However if I remove my custom class from the class path i got some ClassNotFoundException log4j entries in the SystemErr.out which is a sign my configuration is read.</p>
  
  <p>With no many ideas left the last thing I tried was to create a file called <code>org.apache.commons.logging.LogFactory</code> and have its  content like below:</p>
  
  <pre><code>org.apache.commons.logging.impl.Log4jFactoryImpl
  </code></pre>
  
  <p>Our applications are running with a <code>parent first</code> class loading policy and we cannot change this.</p>
  
  <p>This last attempt did not work either. Now I am out of ideas and can only help someone may bring some light in what am I missing.</p>
  
  <p>Thank you in advance for your inputs.</p>
  
  <p><strong>UPDATE:</strong>
  Actually I was wrong. If log4j is used to produce log entries then the <code>CustomPatternLayout</code> is used. It was only when the log entry was written by WAS that I could not my custom pattern being used. I think this is because WAS will use JDK <code>java.util.logging.Logger</code>. So my question would change to:
  Is there a relatively easy way of intercepting WAS calls to writing log entries and apply a logic similar to the one I put in my custom pattern.</p>
  
  <p>Thanks again for your inputs.</p>