Log4j 2 configuration depending on environment

In a recent project, we used Log4j 2 as a backend for slf4j. Logging is configured differently for the local application start than for production. To do this, we used to have one configuration per environment and a piece of code in a servlet listener doing the configuration for Log4j 1.2:

URL loggerFile = this.getClass().getClassLoader()
   .getResource("log4j-dev.xml");
DOMConfigurator.configure(loggerFile);

Log4j 2 has a reconfiguration feature that monitors a file and reloads the configuration if the file changes. So you can dynamically change appenders or log levels while your application runs (without losing log messages). Dynamically specifying which logger config should be used isn’t as easy as setting up configuration reloading….

To correctly set up Log4j 2 for web applications, there is a log4j-web artifact that does the magic. To specify the logger config, you can simply add this to your web.xml:

<context-param>
    <param-name>log4jConfiguration</param-name>
    <param-value>WEB-INF/classes/log4j2.xml</param-value>
</context-param>

If using a Servlet 3 compatible servlet container, Log4j 2 will automatically be set up on startup by using a ServletContainerInitializer provided by the log4j-web artifact. If you would like to dynamically specify the configuration file to be used, you have to first deactivate the initializer by adding this to your web.xml:

<context-param>
    <param-name>isLog4jAutoInitializationDisabled</param-name>
    <param-value>true</param-value>
</context-param>

To implement the logic to specify the config file you have to add the following to your servlet listener:

private Log4jServletContextListener listener = 
                    new Log4jServletContextListener();

@Override
public void contextInitialized(ServletContextEvent event) {
    String loggerPath = "WEB-INF/classes/log4j2-dev.xml";
    event.getServletContext().setInitParameter(
                   Log4jWebSupport.LOG4J_CONFIG_LOCATION, 
                   loggerPath);
    listener.contextInitialized(event);
}

@Override
public void contextDestroyed(ServletContextEvent event) {
    listener.contextDestroyed(event);
}

One last thing: Be aware that your servlet listener should be the first one in your web.xml so that no logging is done before the logger is correctly set up.

Short URL for this post: http://wp.me/p4nxik-2n6
This entry was posted in Did you know? and tagged , , , . Bookmark the permalink.

3 Responses to Log4j 2 configuration depending on environment

  1. Thanks. This was a big help.

  2. TheGoogleSearch says:

    specific logs for multiple war having one ear .How to configure the same using log4j2.xml as i am not able to find any much help in this.i have 5 wars having one ear and when i configure the logs all war logs are printing to only one log file which got loaded first by the class loader.i want my log file to be separate out for each war in single ear.any help would be appreciated

Leave a Reply