"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><web-app></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 <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 <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><web-app></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 <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 <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>