Apache logging services logo Apache log4j logo

Using Log4j 2 in Web Applications

You must take particular care when using Log4j or any other logging framework within a Java EE web application. It's important for logging resources to be properly cleaned up (database connections closed, files closed, etc.) when the container shuts down or the web application is undeployed. Because of the nature of class loaders within web applications, Log4j resources cannot be cleaned up through normal means. Log4j must be "started" when the web application deploys and "shut down" when the web application undeploys. How this works varies depending on whether your application is a Servlet 3.0 or newer or Servlet 2.5 web application.

Servlet 3.0 and Newer Web Applications

A Servlet 3.0 or newer web application is any <web-app> whose version attribute has a value of "3.0" or higher. Of course, the application must also be running in a compatible web container. Some examples are: Tomcat 7.0 and higher, GlassFish 3.0 and higher, JBoss 7.0 and higher, Oracle WebLogic 12c and higher, and IBM WebSphere 8.0 and higher.

The Short Story
Log4j 2 "just works" in Servlet 3.0 and newer web applications. It is capable of automatically starting when the application deploys and shutting down when the application undeploys.

Important Note! For performance reasons, containers often ignore certain JARs and do not scan them for web-fragments and ServletContainerInitializers. For example, Tomcat 7 <7.0.42 ignores all JAR files named log4j*.jar, which prevents this feature from working. This has been fixed in Tomcat 7.0.43, Tomcat 8, and later. In Tomcat 7 <7.0.42 you will need to change catalina.properties and remove "log4j*.jar" from the jarsToSkip property.

The Long Story
The Log4j 2 Core JAR file is a web-fragment configured to order before any other web fragments in your application. It contains a ServletContainerInitializer (Log4jServletContainerInitializer) that the container automatically discovers and initializes. This adds the Log4jServletContextListener and Log4jServletFilter to the ServletContext. These classes properly initialize and deinitialize the Log4j configuration.

You can customize the behavior of the listener and filter using the log4jContextName, log4jConfiguration, and/or isLog4jContextSelectorNamed context parameters. Read more about this in the Context Parameters section below.

Servlet 2.5 Web Applications

A Servlet 2.5 web application is any <web-app> whose version attribute has a value of "2.5." Note that Log4j 2 does not support Servlet 2.4 and older web applications. The version attribute is the only thing that matters; even if the web application is running in a Servlet 3.0 or newer container, it is a Servlet 2.5 web application if the version attribute is "2.5."

If you are using Log4j in a Servlet 2.5 web application, you must configure the Log4jServletContextListener and Log4jServletFilter in the deployment descriptor. The filter should match all requests of any type. The listener should be the very first listener defined in the deployment descriptor, and the filter should be the very first filter defined and mapped in the deployment descriptor. This is easily accomplished using the following web.xml code:

    <listener>
        <listener-class>org.apache.logging.log4j.core.web.Log4jServletContextListener</listener-class>
    </listener>

    <filter>
        <filter-name>log4jServletFilter</filter-name>
        <filter-class>org.apache.logging.log4j.core.web.Log4jServletFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>log4jServletFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
        <dispatcher>INCLUDE</dispatcher>
        <dispatcher>ERROR</dispatcher>
    </filter-mapping>

You can customize the behavior of the listener and filter using the log4jContextName, log4jConfiguration, and/or isLog4jContextSelectorNamed context parameters. Read more about this in the Context Parameters section below.

Context Parameters

By default, Log4j 2 uses the ServletContext's context name as the LoggerContext name and uses the standard pattern for locating the Log4j configuration file. There are three context parameters that you can use to control this behavior. The first, isLog4jContextSelectorNamed, specifies whether the context should be selected using the JNDIContextSelector. If isLog4jContextSelectorNamed is not specified or is anything other than true, it is assumed to be false.

If isLog4jContextSelectorNamed is true, log4jContextName must be specified; otherwise, the application will fail to start with an exception. log4jConfiguration should also be specified in this case, and must be a valid URI for the configuration; however, this parameter is not required.

If isLog4jContextSelectorNamed is not true, log4jConfiguration may be a valid URI or a path to a file, or it may start with "classpath:" to denote a file that can be found on the classpath.

When specifying these context parameters, you must specify them in the deployment descriptor (web.xml) even in a Servlet 3.0 or never application. If you add them to the ServletContext within a listener, Log4j will initialize before the context parameters are available and they will have no effect. Here are some sample uses of these context parameters.

Set the Logging Context Name to "myApplication"

    <context-param>
        <param-name>log4jContextName</param-name>
        <param-value>myApplication</param-value>
    </context-param>

Set the Configuration Path/File/URI to "/etc/myApp/myLogging.xml"

    <context-param>
        <param-name>log4jConfiguration</param-name>
        <param-value>file:///etc/myApp/myLogging.xml</param-value>
    </context-param>

Use the JNDIContextSelector

    <context-param>
        <param-name>isLog4jContextSelectorNamed</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
        <param-name>log4jContextName</param-name>
        <param-value>appWithJndiSelector</param-value>
    </context-param>
    <context-param>
        <param-name>log4jConfiguration</param-name>
        <param-value>file://D:\conf\myLogging.xml</param-value>
    </context-param>
Note that in this case you must also set the "Log4jContextSelector" system property to "org.apache.logging.log4j.core.selector.JNDIContextSelector."