KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > web > util > Log4jWebConfigurer


1 /*
2  * Copyright 2002-2005 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.web.util;
18
19 import java.io.FileNotFoundException JavaDoc;
20
21 import javax.servlet.ServletContext JavaDoc;
22
23 import org.springframework.util.Log4jConfigurer;
24 import org.springframework.util.ResourceUtils;
25 import org.springframework.util.SystemPropertyUtils;
26
27 /**
28  * Convenience class that performs custom Log4J initialization for web environments,
29  * allowing for log file paths within the web application, with the option to
30  * perform automatic refresh checks (for runtime changes in logging configuration).
31  *
32  * <p><b>WARNING: Assumes an expanded WAR file</b>, both for loading the configuration
33  * file and for writing the log files. If you want to keep your WAR unexpanded or
34  * don't need application-specific log files within the WAR directory, don't use
35  * Log4J setup within the application (thus, don't use Log4jConfigListener or
36  * Log4jConfigServlet). Instead, use a global, VM-wide Log4J setup (for example,
37  * in JBoss) or JDK 1.4's <code>java.util.logging</code> (which is global too).
38  *
39  * <p>Supports three init parameters at the servlet context level (that is,
40  * context-param entries in web.xml):
41  *
42  * <ul>
43  * <li><i>"log4jConfigLocation":</i><br>
44  * Location of the Log4J config file; either a "classpath:" location (e.g.
45  * "classpath:myLog4j.properties"), an absolute file URL (e.g. "file:C:/log4j.properties),
46  * or a plain path relative to the web application root directory (e.g.
47  * "/WEB-INF/log4j.properties"). If not specified, default Log4J initialization will
48  * apply ("log4j.properties" in the class path; see Log4J documentation for details).
49  * <li><i>"log4jRefreshInterval":</i><br>
50  * Interval between config file refresh checks, in milliseconds. If not specified,
51  * no refresh checks will happen, which avoids starting Log4J's watchdog thread.
52  * <li><i>"log4jExposeWebAppRoot":</i><br>
53  * Whether the web app root system property should be exposed, allowing for log
54  * file paths relative to the web application root directory. Default is "true";
55  * specify "false" to suppress expose of the web app root system property. See
56  * below for details on how to use this system property in log file locations.
57  * </ul>
58  *
59  * <p>Note: <code>initLogging</code> should be called before any other Spring activity
60  * (when using Log4J), for proper initialization before any Spring logging attempts.
61  *
62  * <p>Log4J's watchdog thread will asynchronously check whether the timestamp
63  * of the config file has changed, using the given interval between checks.
64  * A refresh interval of 1000 milliseconds (one second), which allows to
65  * do on-demand log level changes with immediate effect, is not unfeasible.
66
67  * <p><b>WARNING:</b> Log4J's watchdog thread does not terminate until VM shutdown;
68  * in particular, it does not terminate on LogManager shutdown. Therefore, it is
69  * recommended to <i>not</i> use config file refreshing in a production J2EE
70  * environment; the watchdog thread would not stop on application shutdown there.
71  *
72  * <p>By default, this configurer automatically sets the web app root system property,
73  * for "${key}" substitutions within log file locations in the Log4J config file,
74  * allowing for log file paths relative to the web application root directory.
75  * The default system property key is "webapp.root", to be used in a Log4J config
76  * file like as follows:
77  *
78  * <p><code>log4j.appender.myfile.File=${webapp.root}/WEB-INF/demo.log</code>
79  *
80  * <p>Alternatively, specify a unique context-param "webAppRootKey" per web application.
81  * For example, with "webAppRootKey = "demo.root":
82  *
83  * <p><code>log4j.appender.myfile.File=${demo.root}/WEB-INF/demo.log</code>
84  *
85  * <p><b>WARNING:</b> Some containers (like Tomcat) do <i>not</i> keep system properties
86  * separate per web app. You have to use unique "webAppRootKey" context-params per web
87  * app then, to avoid clashes. Other containers like Resin do isolate each web app's
88  * system properties: Here you can use the default key (i.e. no "webAppRootKey"
89  * context-param at all) without worrying.
90  *
91  * @author Juergen Hoeller
92  * @since 12.08.2003
93  * @see org.springframework.util.Log4jConfigurer
94  * @see Log4jConfigListener
95  * @see Log4jConfigServlet
96  */

97 public abstract class Log4jWebConfigurer {
98
99     /** Parameter specifying the location of the Log4J config file */
100     public static final String JavaDoc CONFIG_LOCATION_PARAM = "log4jConfigLocation";
101
102     /** Parameter specifying the refresh interval for checking the Log4J config file */
103     public static final String JavaDoc REFRESH_INTERVAL_PARAM = "log4jRefreshInterval";
104
105     /** Parameter specifying whether to expose the web app root system property */
106     public static final String JavaDoc EXPOSE_WEB_APP_ROOT_PARAM = "log4jExposeWebAppRoot";
107
108
109     /**
110      * Initialize Log4J, including setting the web app root system property.
111      * @param servletContext the current ServletContext
112      * @see WebUtils#setWebAppRootSystemProperty
113      */

114     public static void initLogging(ServletContext JavaDoc servletContext) {
115         // Expose the web app root system property.
116
if (exposeWebAppRoot(servletContext)) {
117             WebUtils.setWebAppRootSystemProperty(servletContext);
118         }
119
120         // Only perform custom Log4J initialization in case of a config file.
121
String JavaDoc location = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
122         if (location != null) {
123             // Perform actual Log4J initialization; else rely on Log4J's default initialization.
124
try {
125                 // Return a URL (e.g. "classpath:" or "file:") as-is;
126
// consider a plain file path as relative to the web application root directory.
127
if (!ResourceUtils.isUrl(location)) {
128                     // Resolve system property placeholders before resolving real path.
129
location = SystemPropertyUtils.resolvePlaceholders(location);
130                     location = WebUtils.getRealPath(servletContext, location);
131                 }
132
133                 // Write log message to server log.
134
servletContext.log("Initializing Log4J from [" + location + "]");
135
136                 // Check whether refresh interval was specified.
137
String JavaDoc intervalString = servletContext.getInitParameter(REFRESH_INTERVAL_PARAM);
138                 if (intervalString != null) {
139                     // Initialize with refresh interval, i.e. with Log4J's watchdog thread,
140
// checking the file in the background.
141
try {
142                         long refreshInterval = Long.parseLong(intervalString);
143                         Log4jConfigurer.initLogging(location, refreshInterval);
144                     }
145                     catch (NumberFormatException JavaDoc ex) {
146                         throw new IllegalArgumentException JavaDoc("Invalid 'log4jRefreshInterval' parameter: " + ex.getMessage());
147                     }
148                 }
149                 else {
150                     // Initialize without refresh check, i.e. without Log4J's watchdog thread.
151
Log4jConfigurer.initLogging(location);
152                 }
153             }
154             catch (FileNotFoundException JavaDoc ex) {
155                 throw new IllegalArgumentException JavaDoc("Invalid 'log4jConfigLocation' parameter: " + ex.getMessage());
156             }
157         }
158     }
159
160     /**
161      * Shut down Log4J, properly releasing all file locks
162      * and resetting the web app root system property.
163      * @param servletContext the current ServletContext
164      * @see WebUtils#removeWebAppRootSystemProperty
165      */

166     public static void shutdownLogging(ServletContext JavaDoc servletContext) {
167         servletContext.log("Shutting down Log4J");
168         try {
169             Log4jConfigurer.shutdownLogging();
170         }
171         finally {
172             // Remove the web app root system property.
173
if (exposeWebAppRoot(servletContext)) {
174                 WebUtils.removeWebAppRootSystemProperty(servletContext);
175             }
176         }
177     }
178
179     /**
180      * Return whether to expose the web app root system property,
181      * checking the corresponding ServletContext init parameter.
182      * @see #EXPOSE_WEB_APP_ROOT_PARAM
183      */

184     private static boolean exposeWebAppRoot(ServletContext JavaDoc servletContext) {
185         String JavaDoc exposeWebAppRootParam = servletContext.getInitParameter(EXPOSE_WEB_APP_ROOT_PARAM);
186         return (exposeWebAppRootParam == null || Boolean.valueOf(exposeWebAppRootParam).booleanValue());
187     }
188
189 }
190
Popular Tags