"Fossies" - the Fresh Open Source Software Archive

Member "apache-log4j-2.12.4-src/src/site/xdoc/manual/webapp.xml" (20 Dec 2021, 26003 Bytes) of package /linux/misc/apache-log4j-2.12.4-src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) XML source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "webapp.xml": 2.18.0_vs_2.19.0.

    1 <?xml version="1.0"?>
    2 <!--
    3     Licensed to the Apache Software Foundation (ASF) under one or more
    4     contributor license agreements.  See the NOTICE file distributed with
    5     this work for additional information regarding copyright ownership.
    6     The ASF licenses this file to You under the Apache License, Version 2.0
    7     (the "License"); you may not use this file except in compliance with
    8     the License.  You may obtain a copy of the License at
    9 
   10          http://www.apache.org/licenses/LICENSE-2.0
   11 
   12     Unless required by applicable law or agreed to in writing, software
   13     distributed under the License is distributed on an "AS IS" BASIS,
   14     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15     See the License for the specific language governing permissions and
   16     limitations under the License.
   17 -->
   18 
   19 <document xmlns="http://maven.apache.org/XDOC/2.0"
   20           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   21           xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
   22   <properties>
   23     <title>Log4j 2 Web Applications</title>
   24     <author email="nickwilliams@apache.org">Nick Williams</author>
   25     <author email="mattsicker@apache.org">Matt Sicker</author>
   26   </properties>
   27 
   28   <body>
   29     <section name="Using Log4j 2 in Web Applications">
   30       <p>
   31         You must take particular care when using Log4j or any other logging framework within a Java EE web application.
   32         It's important for logging resources to be properly cleaned up (database connections closed, files closed, etc.)
   33         when the container shuts down or the web application is undeployed. Because of the nature of class loaders
   34         within web applications, Log4j resources cannot be cleaned up through normal means. Log4j must be "started" when
   35         the web application deploys and "shut down" when the web application undeploys. How this works varies depending
   36         on whether your application is a <a href="#Servlet-3.0">Servlet 3.0 or newer</a> or
   37         <a href="#Servlet-2.5">Servlet 2.5</a> web application.
   38       </p>
   39       <p>
   40         In either case, you'll need to add the <code>log4j-web</code> module to your deployment as detailed in the
   41         <a href="../maven-artifacts.html">Maven, Ivy, and Gradle Artifacts</a> manual page.
   42       </p>
   43       <p class="big-red">
   44         <i class="icon-exclamation-sign"/>
   45         To avoid problems the Log4j shutdown hook will automatically be disabled when the log4j-web jar is included.
   46       </p>
   47       <a name="Configuration"/>
   48       <subsection name="Configuration">
   49         <p>
   50           Log4j allows the configuration file to be specified in web.xml using the <code>log4jConfiguration</code>
   51           context parameter. Log4j will search for configuration files by:
   52         </p>
   53         <ol>
   54           <li>
   55             If a location is provided it will be searched for as a servlet context resource. For example, if
   56             <code>log4jConfiguration</code> contains "logging.xml" then Log4j will look for a file with that
   57             name in the root directory of the web application.
   58           </li>
   59           <li>
   60             If no location is defined Log4j will search for a file that starts with "log4j2" in the WEB-INF directory.
   61             If more than one file is found, and if a file that starts with "log4j2-<var>name</var>" is present, where
   62             <var>name</var> is the name of the web application, then it will be used. Otherwise the first file will be
   63             used.
   64           </li>
   65           <li>
   66             The "normal" search sequence using the classpath and file URLs will be used to locate the configuration file.
   67           </li>
   68         </ol>
   69       </subsection>
   70       <subsection name="Servlet 3.0 and Newer Web Applications">
   71         <a name="Servlet-3.0" />
   72         <p>
   73           A Servlet 3.0 or newer web application is any <code>&lt;web-app&gt;</code> whose <code>version</code>
   74           attribute has a value of "3.0" or higher. Of course, the application must also be running in a compatible
   75           web container. Some examples are: Tomcat 7.0 and higher, GlassFish 3.0 and higher, JBoss 7.0 and higher,
   76           Oracle WebLogic 12c and higher, and IBM WebSphere 8.0 and higher.
   77         </p>
   78         <h4>The Short Story</h4>
   79         <p>
   80           Log4j 2 "just works" in Servlet 3.0 and newer web applications. It is capable of automatically starting when
   81           the application deploys and shutting down when the application undeploys. Thanks to the
   82           <a class="javadoc" href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html">ServletContainerInitializer</a>
   83           API added to Servlet 3.0, the relevant <code>Filter</code> and <code>ServletContextListener</code> classes
   84           can be registered dynamically on web application startup.
   85         </p>
   86         <p>
   87           <strong class="text-warning"><i class="icon-exclamation-sign"/> Important Note!</strong>
   88           For performance reasons, containers often ignore certain JARs known not to
   89           contain TLDs or <code>ServletContainerInitializer</code>s and do not scan them for web-fragments and
   90           initializers. Importantly, Tomcat 7 &lt;7.0.43 ignores all JAR files named log4j*.jar, which prevents this
   91           feature from working. This has been fixed in Tomcat 7.0.43, Tomcat 8, and later. In Tomcat 7 &lt;7.0.43 you
   92           will need to change <code>catalina.properties</code> and remove "log4j*.jar" from the <code>jarsToSkip</code>
   93           property. You may need to do something similar on other containers if they skip scanning Log4j JAR files.
   94         </p>
   95         <h4>The Long Story</h4>
   96         <p>
   97           The Log4j 2 Web JAR file is a web-fragment configured to order before any other web fragments in your
   98           application. It contains a <code>ServletContainerInitializer</code>
   99           (<a class="javadoc" href="../log4j-web/apidocs/org/apache/logging/log4j/web/Log4jServletContainerInitializer.html"
  100             >Log4jServletContainerInitializer</a>) that the container automatically discovers and initializes. This adds
  101           the <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/web/Log4jServletContextListener.html"
  102             >Log4jServletContextListener</a> and
  103           <a class="javadoc" href="../log4j-web/apidocs/org/apache/logging/log4j/web/Log4jServletFilter.html"
  104             >Log4jServletFilter</a> to the <code>ServletContext</code>. These classes properly initialize
  105           and deinitialize the Log4j configuration.
  106         </p>
  107         <p>
  108           For some users, automatically starting Log4j is problematic or undesirable. You can easily disable this
  109           feature using the <code>isLog4jAutoInitializationDisabled</code> context parameter. Simply add it to your
  110           deployment descriptor with the value "true" to disable auto-initialization. You <em>must</em> define the
  111           context parameter in <code>web.xml</code>. If you set in programmatically, it will be too late for Log4j
  112           to detect the setting.
  113         </p>
  114           <pre class="prettyprint linenums"><![CDATA[    <context-param>
  115         <param-name>isLog4jAutoInitializationDisabled</param-name>
  116         <param-value>true</param-value>
  117     </context-param>]]></pre>
  118         <p>
  119           Once you disable auto-initialization, you must initialize Log4j as you would a
  120           <a href="#Servlet-2.5">Servlet 2.5 web application</a>. You must do so in a way that this initialization
  121           happens before any other application code (such as Spring Framework startup code) executes.
  122         </p>
  123         <p>
  124           You can customize the behavior of the listener and filter using the <code>log4jContextName</code>,
  125           <code>log4jConfiguration</code>, and/or <code>isLog4jContextSelectorNamed</code> context parameters. Read more
  126           about this in the <a href="#ContextParams">Context Parameters</a> section below. You <em>must not</em>
  127           manually configure the <code>Log4jServletContextListener</code> or <code>Log4jServletFilter</code> in your
  128           deployment descriptor (<code>web.xml</code>) or in another initializer or listener in a Servlet 3.0 or newer
  129           application <em>unless you disable auto-initialization</em> with
  130           <code>isLog4jAutoInitializationDisabled</code>. Doing so will result in startup errors and unspecified
  131           erroneous behavior.
  132         </p>
  133       </subsection>
  134       <subsection name="Servlet 2.5 Web Applications">
  135         <a name="Servlet-2.5" />
  136         <p>
  137           A Servlet 2.5 web application is any <code>&lt;web-app&gt;</code> whose <code>version</code> attribute has a
  138           value of "2.5." The <code>version</code> attribute is the only thing that matters; even if the web application
  139           is running in a Servlet 3.0 or newer container, it is a Servlet 2.5 web application if the
  140           <code>version</code> attribute is "2.5." Note that Log4j 2 does not support Servlet 2.4 and older web
  141           applications.
  142         </p>
  143         <p>
  144           If you are using Log4j in a Servlet 2.5 web application, or if you have disabled auto-initialization with
  145           the <code>isLog4jAutoInitializationDisabled</code> context parameter, you <em>must</em> configure the
  146           <a class="javadoc" href="../log4j-web/apidocs/org/apache/logging/log4j/web/Log4jServletContextListener.html"
  147             >Log4jServletContextListener</a> and
  148           <a class="javadoc" href="../log4j-web/apidocs/org/apache/logging/log4j/web/Log4jServletFilter.html"
  149             >Log4jServletFilter</a> in the deployment descriptor or programmatically. The filter should match all
  150           requests of any type. The listener should be the very first listener defined in your application, and the
  151           filter should be the very first filter defined and mapped in your application. This is easily accomplished
  152           using the following <code>web.xml</code> code:
  153         </p>
  154           <pre class="prettyprint linenums"><![CDATA[    <listener>
  155         <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
  156     </listener>
  157 
  158     <filter>
  159         <filter-name>log4jServletFilter</filter-name>
  160         <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
  161     </filter>
  162     <filter-mapping>
  163         <filter-name>log4jServletFilter</filter-name>
  164         <url-pattern>/*</url-pattern>
  165         <dispatcher>REQUEST</dispatcher>
  166         <dispatcher>FORWARD</dispatcher>
  167         <dispatcher>INCLUDE</dispatcher>
  168         <dispatcher>ERROR</dispatcher>
  169         <dispatcher>ASYNC</dispatcher><!-- Servlet 3.0 w/ disabled auto-initialization only; not supported in 2.5 -->
  170     </filter-mapping>]]></pre>
  171         <p>
  172           You can customize the behavior of the listener and filter using the <code>log4jContextName</code>,
  173           <code>log4jConfiguration</code>, and/or <code>isLog4jContextSelectorNamed</code> context parameters. Read more
  174           about this in the <a href="#ContextParams">Context Parameters</a> section below.
  175         </p>
  176       </subsection>
  177       <subsection name="Context Parameters">
  178         <a name="ContextParams" />
  179         <p>
  180           By default, Log4j 2 uses the <code>ServletContext</code>'s
  181           <a href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#getServletContextName()">context name</a>
  182           as the <code>LoggerContext</code> name and uses the standard pattern for locating the Log4j configuration
  183           file. There are three context parameters that you can use to control this behavior. The first,
  184           <code>isLog4jContextSelectorNamed</code>, specifies whether the context should be selected using the
  185           <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/selector/JndiContextSelector.html"
  186             >JndiContextSelector</a>. If <code>isLog4jContextSelectorNamed</code> is not specified or is anything other
  187           than <code>true</code>, it is assumed to be <code>false</code>.
  188         </p>
  189         <p>
  190           If <code>isLog4jContextSelectorNamed</code> is <code>true</code>, <code>log4jContextName</code> must be
  191           specified or <code>display-name</code> must be specified in <code>web.xml</code>; otherwise, the application
  192           will fail to start with an exception. <code>log4jConfiguration</code>
  193           <em>should</em> also be specified in this case, and must be a valid URI for the configuration file; however,
  194           this parameter is not required.
  195         </p>
  196         <p>
  197           If <code>isLog4jContextSelectorNamed</code> is not <code>true</code>, <code>log4jConfiguration</code> may
  198           optionally be specified and must be a valid URI or path to a configuration file or start with "classpath:" to
  199           denote a configuration file that can be found on the classpath. Without this parameter, Log4j will use the
  200           standard mechanisms for locating the configuration file.
  201         </p>
  202         <p>
  203           When specifying these context parameters, you must specify them in the deployment descriptor
  204           (<code>web.xml</code>) even in a Servlet 3.0 or never application. If you add them to the
  205           <code>ServletContext</code> within a listener, Log4j will initialize before the context parameters are
  206           available and they will have no effect. Here are some sample uses of these context parameters.
  207         </p>
  208         <h4>Set the Logging Context Name to "myApplication"</h4>
  209         <pre class="prettyprint linenums"><![CDATA[    <context-param>
  210         <param-name>log4jContextName</param-name>
  211         <param-value>myApplication</param-value>
  212     </context-param>]]></pre>
  213         <h4>Set the Configuration Path/File/URI to "/etc/myApp/myLogging.xml"</h4>
  214         <pre class="prettyprint linenums"><![CDATA[    <context-param>
  215         <param-name>log4jConfiguration</param-name>
  216         <param-value>file:///etc/myApp/myLogging.xml</param-value>
  217     </context-param>]]></pre>
  218         <h4>Use the <code>JndiContextSelector</code></h4>
  219         <pre class="prettyprint linenums"><![CDATA[    <context-param>
  220         <param-name>isLog4jContextSelectorNamed</param-name>
  221         <param-value>true</param-value>
  222     </context-param>
  223     <context-param>
  224         <param-name>log4jContextName</param-name>
  225         <param-value>appWithJndiSelector</param-value>
  226     </context-param>
  227     <context-param>
  228         <param-name>log4jConfiguration</param-name>
  229         <param-value>file:///D:/conf/myLogging.xml</param-value>
  230     </context-param>]]></pre>
  231         <p>
  232           Note that in this case you must also set the "Log4jContextSelector" system property to
  233           "<kbd>org.apache.logging.log4j.core.selector.JndiContextSelector</kbd>".
  234         </p>
  235       </subsection>
  236       <subsection name="Using Web Application Information During the Configuration">
  237         <a name="WebLookup" />
  238         <p>
  239           You may want to use information about the web application during configuration. For example, you could embed
  240           the web application's context path in the name of a Rolling File Appender. See WebLookup in
  241           <a href="./lookups.html#WebLookup">Lookups</a> for more information.
  242         </p>
  243       </subsection>
  244       <subsection name="JavaServer Pages Logging">
  245         <a name="JspLogging" />
  246         <p>
  247           You may use Log4j 2 within JSPs just as you would within any other Java code. Simple obtain a
  248           <code>Logger</code> and call its methods to log events. However, this requires you to use Java code within
  249           your JSPs, and some development teams rightly are not comfortable with doing this. If you have a dedicated
  250           user interface development team that is not familiar with using Java, you may even have Java code disabled in
  251           your JSPs.
  252         </p>
  253         <p>
  254           For this reason, Log4j 2 provides a JSP Tag Library that enables you to log events without using any Java
  255           code. To read more about using this tag library, <a href="../log4j-taglib/index.html">read the Log4j Tag
  256           Library documentation.</a>
  257         </p>
  258         <p>
  259           <strong class="text-warning"><i class="icon-exclamation-sign"/> Important Note!</strong>
  260           As noted above, containers often ignore certain JARs known not to
  261           contain TLDs and do not scan them for TLD files. Importantly, Tomcat 7 &lt;7.0.43 ignores all JAR files named
  262           log4j*.jar, which prevents the JSP tag library from being automatically discovered. This does not affect
  263           Tomcat 6.x and has been fixed in Tomcat 7.0.43, Tomcat 8, and later. In Tomcat 7 &lt;7.0.43 you
  264           will need to change <code>catalina.properties</code> and remove "log4j*.jar" from the <code>jarsToSkip</code>
  265           property. You may need to do something similar on other containers if they skip scanning Log4j JAR files.
  266         </p>
  267       </subsection>
  268       <subsection name="Asynchronous Requests and Threads">
  269         <a name="Async" />
  270         <p>
  271           The handling of asynchronous requests is tricky, and regardless of Servlet container version or configuration
  272           Log4j cannot handle everything automatically. When standard requests, forwards, includes, and error resources
  273           are processed, the <code>Log4jServletFilter</code> binds the <code>LoggerContext</code> to the thread handling
  274           the request. After request processing completes, the filter unbinds the <code>LoggerContext</code> from the
  275           thread.
  276         </p>
  277         <p>
  278           Similarly, when an internal request is dispatched using a <code>javax.servlet.AsyncContext</code>, the
  279           <code>Log4jServletFilter</code> also binds the <code>LoggerContext</code> to the thread handling the request
  280           and unbinds it when request processing completes. However, this only happens for requests <em>dispatched</em>
  281           through the <code>AsyncContext</code>. There are other asynchronous activities that can take place other than
  282           internal dispatched requests.
  283         </p>
  284         <p>
  285           For example, after starting an <code>AsyncContext</code> you could start up a separate thread to process the
  286           request in the background, possibly writing the response with the <code>ServletOutputStream</code>. Filters
  287           cannot intercept the execution of this thread. Filters also cannot intercept threads that you start in
  288           the background during non-asynchronous requests. This is true whether you use a brand new thread or a thread
  289           borrowed from a thread pool. So what can you do for these special threads?
  290         </p>
  291         <p>
  292           You may not need to do anything. If you didn't use the <code>isLog4jContextSelectorNamed</code> context
  293           parameter, there is no need to bind the <code>LoggerContext</code> to the thread. Log4j can safely locate the
  294           <code>LoggerContext</code> on its own. In these cases, the filter provides only very modest performance
  295           gains, and only when creating new <code>Logger</code>s. However, if you <em>did</em> specify the
  296           <code>isLog4jContextSelectorNamed</code> context parameter with the value "true", you will need to manually
  297           bind the <code>LoggerContext</code> to asynchronous threads. Otherwise, Log4j will not be able to locate it.
  298         </p>
  299         <p>
  300           Thankfully, Log4j provides a simple mechanism for binding the <code>LoggerContext</code> to asynchronous
  301           threads in these special circumstances. The simplest way to do this is to wrap the <code>Runnable</code>
  302           instance that is passed to the <code>AsyncContext.start()</code> method.
  303         </p>
  304         <pre class="prettyprint linenums"><![CDATA[
  305 import java.io.IOException;
  306 import javax.servlet.AsyncContext;
  307 import javax.servlet.ServletException;
  308 import javax.servlet.http.HttpServlet;
  309 import javax.servlet.http.HttpServletRequest;
  310 import javax.servlet.http.HttpServletResponse;
  311 
  312 import org.apache.logging.log4j.LogManager;
  313 import org.apache.logging.log4j.Logger;
  314 import org.apache.logging.log4j.web.WebLoggerContextUtils;
  315 
  316 public class TestAsyncServlet extends HttpServlet {
  317 
  318     @Override
  319     protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
  320         final AsyncContext asyncContext = req.startAsync();
  321         asyncContext.start(WebLoggerContextUtils.wrapExecutionContext(this.getServletContext(), new Runnable() {
  322             @Override
  323             public void run() {
  324                 final Logger logger = LogManager.getLogger(TestAsyncServlet.class);
  325                 logger.info("Hello, servlet!");
  326             }
  327         }));
  328     }
  329 
  330     @Override
  331     protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
  332         final AsyncContext asyncContext = req.startAsync();
  333         asyncContext.start(new Runnable() {
  334             @Override
  335             public void run() {
  336                 final Log4jWebSupport webSupport =
  337                     WebLoggerContextUtils.getWebLifeCycle(TestAsyncServlet.this.getServletContext());
  338                 webSupport.setLoggerContext();
  339                 // do stuff
  340                 webSupport.clearLoggerContext();
  341             }
  342         });
  343     }
  344 }
  345         ]]></pre>
  346         <p>
  347           This can be slightly more convenient when using Java 1.8 and lambda functions as demonstrated below.
  348         </p>
  349         <pre class="prettyprint linenums"><![CDATA[
  350 import java.io.IOException;
  351 import javax.servlet.AsyncContext;
  352 import javax.servlet.ServletException;
  353 import javax.servlet.http.HttpServlet;
  354 import javax.servlet.http.HttpServletRequest;
  355 import javax.servlet.http.HttpServletResponse;
  356 
  357 import org.apache.logging.log4j.LogManager;
  358 import org.apache.logging.log4j.Logger;
  359 import org.apache.logging.log4j.web.WebLoggerContextUtils;
  360 
  361 public class TestAsyncServlet extends HttpServlet {
  362     @Override
  363     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  364         final AsyncContext asyncContext = req.startAsync();
  365         asyncContext.start(WebLoggerContextUtils.wrapExecutionContext(this.getServletContext(), () -> {
  366             final Logger logger = LogManager.getLogger(TestAsyncServlet.class);
  367             logger.info("Hello, servlet!");
  368         }));
  369     }
  370 }
  371         ]]></pre>
  372         <p>
  373           Alternatively, you can obtain the
  374           <a class="javadoc" href="../log4j-web/apidocs/org/apache/logging/log4j/web/Log4jWebLifeCycle.html">Log4jWebLifeCycle</a>
  375           instance from the <code>ServletContext</code> attributes, call its <code>setLoggerContext</code> method as
  376           the very first line of code in your asynchronous thread, and call its <code>clearLoggerContext</code> method
  377           as the very last line of code in your asynchronous thread. The following code demonstrates this. It uses the
  378           container thread pool to execute asynchronous request processing, passing an anonymous inner
  379           <code>Runnable</code> to the <code>start</code> method.
  380         </p>
  381         <pre class="prettyprint linenums"><![CDATA[
  382 import java.io.IOException;
  383 import javax.servlet.AsyncContext;
  384 import javax.servlet.ServletException;
  385 import javax.servlet.http.HttpServlet;
  386 import javax.servlet.http.HttpServletRequest;
  387 import javax.servlet.http.HttpServletResponse;
  388 
  389 import org.apache.logging.log4j.LogManager;
  390 import org.apache.logging.log4j.Logger;
  391 import org.apache.logging.log4j.web.Log4jWebLifeCycle;
  392 import org.apache.logging.log4j.web.WebLoggerContextUtils;
  393 
  394 public class TestAsyncServlet extends HttpServlet {
  395     @Override
  396     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  397          final AsyncContext asyncContext = req.startAsync();
  398         asyncContext.start(new Runnable() {
  399             @Override
  400             public void run() {
  401                 final Log4jWebLifeCycle webLifeCycle =
  402                     WebLoggerContextUtils.getWebLifeCycle(TestAsyncServlet.this.getServletContext());
  403                 webLifeCycle.setLoggerContext();
  404                 try {
  405                     final Logger logger = LogManager.getLogger(TestAsyncServlet.class);
  406                     logger.info("Hello, servlet!");
  407                 } finally {
  408                     webLifeCycle.clearLoggerContext();
  409                 }
  410             }
  411         });
  412    }
  413 }
  414         ]]></pre>
  415         <p>
  416           Note that you <em>must</em> call <code>clearLoggerContext</code> once your thread is finished
  417           processing. Failing to do so will result in memory leaks. If using a thread pool, it can even disrupt the
  418           logging of other web applications in your container. For that reason, the example here shows clearing the
  419           context in a <code>finally</code> block, which will always execute.
  420         </p>
  421       </subsection>
  422       <subsection name="Using the Servlet Appender">
  423         <p>
  424           Log4j provides a Servlet Appender that uses the servlet context as the log target. For example:
  425         </p>
  426         <pre class="prettyprint linenums"><![CDATA[
  427 <Configuration status="WARN" name="ServletTest">
  428 
  429     <Appenders>
  430         <Servlet name="Servlet">
  431             <PatternLayout pattern="%m%n%ex{none}"/>
  432         </Servlet>
  433     </Appenders>
  434 
  435     <Loggers>
  436         <Root level="debug">
  437             <AppenderRef ref="Servlet"/>
  438         </Root>
  439     </Loggers>
  440 
  441 </Configuration>]]></pre>
  442         <p>
  443           To avoid double logging of exceptions to the servlet context, you must use <code>%ex{none}</code> in your 
  444           <code>PatternLayout</code> as shown in the example. The exception will be omitted from the message text but 
  445           it is passed to the servlet context as the actual Throwable object. 
  446         </p>
  447       </subsection>
  448     </section>
  449   </body>
  450 
  451 </document>