////
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements. See the NOTICE file distributed with
    this work for additional information regarding copyright ownership.
    The ASF licenses this file to You under the Apache License, Version 2.0
    (the "License"); you may not use this file except in compliance with
    the License. You may obtain a copy of the License at

        https://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
////
= Web Applications
Nick Williams <nickwilliams@apache.org>; Matt Sicker <mattsicker@apache.org>

== 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 link:#Servlet-3.0[Servlet 3.0 or newer] or
link:#Servlet-2.5[Servlet 2.5] web application.

In either case, you'll need to add the `log4j-web` module to your
deployment as detailed in the link:../maven-artifacts.html[Maven, Ivy,
and Gradle Artifacts] manual page.

NOTE: To avoid problems the Log4j shutdown hook will automatically be
disabled when the log4j-web jar is included.

[#Configuration]
== Configuration

Log4j allows the configuration file to be specified in web.xml using the
`log4jConfiguration` context parameter. Log4j will search for
configuration files by:

1.  If a location is provided it will be searched for as a servlet
context resource. For example, if `log4jConfiguration` contains
"logging.xml" then Log4j will look for a file with that name in the root
directory of the web application.
2.  If no location is defined Log4j will search for a file that starts
with "log4j2" in the WEB-INF directory. If more than one file is found,
and if a file that starts with "log4j2-name" is present, where name is
the name of the web application, then it will be used. Otherwise the
first file will be used.
3.  The "normal" search sequence using the classpath and file URLs will
be used to locate the configuration file.

[#Servlet-3.0]
== 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. Thanks to the
https://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html[`ServletContainerInitializer`]
API added to Servlet 3.0, the relevant `Filter` and
`ServletContextListener` classes can be registered dynamically on web
application startup.

NOTE: For performance reasons, containers often ignore
certain JARs known not to contain TLDs or `ServletContainerInitializer`
and do not scan them for web-fragments and initializers. Importantly,
Tomcat 7 <7.0.43 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.43 you will need to change
`catalina.properties` and remove "log4j*.jar" from the `jarsToSkip`
property. You may need to do something similar on other containers if
they skip scanning Log4j JAR files.

=== The Long Story

The Log4j 2 Web JAR file is a web-fragment configured to order before
any other web fragments in your application. It contains a
`ServletContainerInitializer`
(link:../log4j-web/apidocs/org/apache/logging/log4j/web/Log4jServletContainerInitializer
.html[`Log4jServletContainerInitializer`])
that the container automatically discovers and initializes. This adds
the
link:../log4j-web/apidocs/org/apache/logging/log4j/web/Log4jServletContextListener.html[`Log4jServletContextListener`]
and
link:../log4j-web/apidocs/org/apache/logging/log4j/web/Log4jServletFilter.html[`Log4jServletFilter`]
to the `ServletContext`. These classes properly initialize and
deinitialize the Log4j configuration.

For some users, automatically starting Log4j is problematic or
undesirable. You can easily disable this feature using the
`isLog4jAutoInitializationDisabled` context parameter. Simply add it to
your deployment descriptor with the value "true" to disable
auto-initialization. You _must_ define the context parameter in
`web.xml`. If you set in programmatically, it will be too late for Log4j
to detect the setting.

[source,xml]
----
<context-param>
    <param-name>isLog4jAutoInitializationDisabled</param-name>
    <param-value>true</param-value>
</context-param>
----

Once you disable auto-initialization, you must initialize Log4j as you
would a link:#Servlet-2.5[Servlet 2.5 web application]. You must do so
in a way that this initialization happens before any other application
code (such as Spring Framework startup code) executes.

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 link:#ContextParams[Context Parameters] section below. You _must
not_ manually configure the `Log4jServletContextListener` or
`Log4jServletFilter` in your deployment descriptor (`web.xml`) or in
another initializer or listener in a Servlet 3.0 or newer application
_unless you disable auto-initialization_ with
`isLog4jAutoInitializationDisabled`. Doing so will result in startup
errors and unspecified erroneous behavior.

[#Servlet-2.5]
== Servlet 2.5 Web Applications

A Servlet 2.5 web application is any `<web-app>` whose `version`
attribute has a value of "2.5." 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." Note that Log4j 2 does not support Servlet
2.4 and older web applications.

If you are using Log4j in a Servlet 2.5 web application, or if you have
disabled auto-initialization with the
`isLog4jAutoInitializationDisabled` context parameter, you _must_
configure the
link:../log4j-web/apidocs/org/apache/logging/log4j/web/Log4jServletContextListener.html[`Log4jServletContextListener`]
and
link:../log4j-web/apidocs/org/apache/logging/log4j/web/Log4jServletFilter.html[`Log4jServletFilter`]
in the deployment descriptor or programmatically. The filter should
match all requests of any type. The listener should be the very first
listener defined in your application, and the filter should be the very
first filter defined and mapped in your application. This is easily
accomplished using the following `web.xml` code:

[source,xml]
----
<listener>
    <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>

<filter>
    <filter-name>log4jServletFilter</filter-name>
    <filter-class>org.apache.logging.log4j.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>
    <dispatcher>ASYNC</dispatcher><!-- Servlet 3.0 w/ disabled auto-initialization only; not supported in 2.5 -->
</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 link:#ContextParams[Context Parameters] section below.

[#ContextParams]
== Context Parameters

By default, Log4j 2 uses the `ServletContext`'s
https://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#getServletContextName()[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
link:../log4j-core/apidocs/org/apache/logging/log4j/core/selector/JndiContextSelector.html[`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 or `display-name` must be specified in `web.xml`; 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 file; however, this parameter is
not required.

If `isLog4jContextSelectorNamed` is not `true`, `log4jConfiguration` may
optionally be specified and must be a valid URI or path to a
configuration file or start with "classpath:" to denote a configuration
file that can be found on the classpath. Without this parameter, Log4j
will use the standard mechanisms for locating the configuration file.

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"

[source,xml]
----
<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"

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

=== Use the `JndiContextSelector`

[source,xml]
----
<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".

[#WebLookup]
== Using Web Application Information During the Configuration

You may want to use information about the web application during
configuration. For example, you could embed the web application's
context path in the name of a Rolling File Appender. See WebLookup in
link:./lookups.html#WebLookup[Lookups] for more information.

[#JspLogging]
== JavaServer Pages Logging

You may use Log4j 2 within JSPs just as you would within any other Java
code. Simple obtain a `Logger` and call its methods to log events.
However, this requires you to use Java code within your JSPs, and some
development teams rightly are not comfortable with doing this. If you
have a dedicated user interface development team that is not familiar
with using Java, you may even have Java code disabled in your JSPs.

For this reason, Log4j 2 provides a JSP Tag Library that enables you to
log events without using any Java code. To read more about using this
tag library, link:../log4j-taglib/index.html[read the Log4j Tag Library
documentation.]

NOTE: As noted above, containers often ignore certain
JARs known not to contain TLDs and do not scan them for TLD files.
Importantly, Tomcat 7 <7.0.43 ignores all JAR files named log4j*.jar,
which prevents the JSP tag library from being automatically discovered.
This does not affect Tomcat 6.x and has been fixed in Tomcat 7.0.43,
Tomcat 8, and later. In Tomcat 7 <7.0.43 you will need to change
`catalina.properties` and remove "log4j*.jar" from the `jarsToSkip`
property. You may need to do something similar on other containers if
they skip scanning Log4j JAR files.

[#Async]
== Asynchronous Requests and Threads

The handling of asynchronous requests is tricky, and regardless of
Servlet container version or configuration Log4j cannot handle
everything automatically. When standard requests, forwards, includes,
and error resources are processed, the `Log4jServletFilter` binds the
`LoggerContext` to the thread handling the request. After request
processing completes, the filter unbinds the `LoggerContext` from the
thread.

Similarly, when an internal request is dispatched using a
`javax.servlet.AsyncContext`, the `Log4jServletFilter` also binds the
`LoggerContext` to the thread handling the request and unbinds it when
request processing completes. However, this only happens for requests
_dispatched_ through the `AsyncContext`. There are other asynchronous
activities that can take place other than internal dispatched requests.

For example, after starting an `AsyncContext` you could start up a
separate thread to process the request in the background, possibly
writing the response with the `ServletOutputStream`. Filters cannot
intercept the execution of this thread. Filters also cannot intercept
threads that you start in the background during non-asynchronous
requests. This is true whether you use a brand new thread or a thread
borrowed from a thread pool. So what can you do for these special
threads?

You may not need to do anything. If you didn't use the
`isLog4jContextSelectorNamed` context parameter, there is no need to
bind the `LoggerContext` to the thread. Log4j can safely locate the
`LoggerContext` on its own. In these cases, the filter provides only
very modest performance gains, and only when creating new `Logger` instances.
However, if you _did_ specify the `isLog4jContextSelectorNamed` context
parameter with the value "true", you will need to manually bind the
`LoggerContext` to asynchronous threads. Otherwise, Log4j will not be
able to locate it.

Thankfully, Log4j provides a simple mechanism for binding the
`LoggerContext` to asynchronous threads in these special circumstances.
The simplest way to do this is to wrap the `Runnable` instance that is
passed to the `AsyncContext.start()` method.

[source,java]
----
import java.io.IOException;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.web.WebLoggerContextUtils;

public class TestAsyncServlet extends HttpServlet {

    @Override
    protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
        final AsyncContext asyncContext = req.startAsync();
        asyncContext.start(WebLoggerContextUtils.wrapExecutionContext(this.getServletContext(), new Runnable() {
            @Override
            public void run() {
                final Logger logger = LogManager.getLogger(TestAsyncServlet.class);
                logger.info("Hello, servlet!");
            }
        }));
    }

    @Override
    protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
        final AsyncContext asyncContext = req.startAsync();
        asyncContext.start(new Runnable() {
            @Override
            public void run() {
                final Log4jWebSupport webSupport =
                    WebLoggerContextUtils.getWebLifeCycle(TestAsyncServlet.this.getServletContext());
                webSupport.setLoggerContext();
                // do stuff
                webSupport.clearLoggerContext();
            }
        });
    }
}
----

This can be slightly more convenient when using Java 1.8 and lambda
functions as demonstrated below.

[source,java]
----
import java.io.IOException;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.web.WebLoggerContextUtils;

public class TestAsyncServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        final AsyncContext asyncContext = req.startAsync();
        asyncContext.start(WebLoggerContextUtils.wrapExecutionContext(this.getServletContext(), () -> {
            final Logger logger = LogManager.getLogger(TestAsyncServlet.class);
            logger.info("Hello, servlet!");
        }));
    }
}
----

Alternatively, you can obtain the
link:../log4j-web/apidocs/org/apache/logging/log4j/web/Log4jWebLifeCycle.html[`Log4jWebLifeCycle`]
instance from the `ServletContext` attributes, call its
`setLoggerContext` method as the very first line of code in your
asynchronous thread, and call its `clearLoggerContext` method as the
very last line of code in your asynchronous thread. The following code
demonstrates this. It uses the container thread pool to execute
asynchronous request processing, passing an anonymous inner `Runnable`
to the `start` method.

[source,java]
----
import java.io.IOException;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.web.Log4jWebLifeCycle;
import org.apache.logging.log4j.web.WebLoggerContextUtils;

public class TestAsyncServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         final AsyncContext asyncContext = req.startAsync();
        asyncContext.start(new Runnable() {
            @Override
            public void run() {
                final Log4jWebLifeCycle webLifeCycle =
                    WebLoggerContextUtils.getWebLifeCycle(TestAsyncServlet.this.getServletContext());
                webLifeCycle.setLoggerContext();
                try {
                    final Logger logger = LogManager.getLogger(TestAsyncServlet.class);
                    logger.info("Hello, servlet!");
                } finally {
                    webLifeCycle.clearLoggerContext();
                }
            }
        });
   }
}
----

Note that you _must_ call `clearLoggerContext` once your thread is
finished processing. Failing to do so will result in memory leaks. If
using a thread pool, it can even disrupt the logging of other web
applications in your container. For that reason, the example here shows
clearing the context in a `finally` block, which will always execute.

== Using the Servlet Appender

Log4j provides a Servlet Appender that uses the servlet context as the
log target. For example:

[source,xml]
----
<Configuration status="WARN" name="ServletTest">

    <Appenders>
        <Servlet name="Servlet">
            <PatternLayout pattern="%m%n%ex{none}"/>
        </Servlet>
    </Appenders>

    <Loggers>
        <Root level="debug">
            <AppenderRef ref="Servlet"/>
        </Root>
    </Loggers>

</Configuration>
----

To avoid double logging of exceptions to the servlet context, you must
use `%ex{none}` in your `PatternLayout` as shown in the example. The
exception will be omitted from the message text but it is passed to the
servlet context as the actual `Throwable` object.
