1 /*
2  * Copyright 2002-2008 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.util;
18 
19 import java.io.File;
20 import java.io.FileNotFoundException;
21 import java.net.URL;
22 
23 import org.apache.log4j.LogManager;
24 import org.apache.log4j.PropertyConfigurator;
25 import org.apache.log4j.xml.DOMConfigurator;
26 
27 /**
28  * Convenience class that features simple methods for custom log4j configuration.
29  *
30  * <p>Only needed for non-default log4j initialization, for example with a custom
31  * config location or a refresh interval. By default, log4j will simply read its
32  * configuration from a "log4j.properties" or "log4j.xml" file in the root of
33  * the classpath.
34  *
35  * <p>For web environments, the analogous Log4jWebConfigurer class can be found
36  * in the web package, reading in its configuration from context-params in
37  * <code>web.xml</code>. In a J2EE web application, log4j is usually set up
38  * via Log4jConfigListener or Log4jConfigServlet, delegating to
39  * Log4jWebConfigurer underneath.
40  *
41  * @author Juergen Hoeller
42  * @since 13.03.2003
43  * @see org.springframework.web.util.Log4jWebConfigurer
44  * @see org.springframework.web.util.Log4jConfigListener
45  */
46 public abstract class Log4jConfigurer {
47 
48 	/** Pseudo URL prefix for loading from the class path: "classpath:" */
49 	public static final String CLASSPATH_URL_PREFIX = "classpath:";
50 
51 	/** Extension that indicates a log4j XML config file: ".xml" */
52 	public static final String XML_FILE_EXTENSION = ".xml";
53 
54 
55 	/**
56 	 * Initialize log4j from the given file location, with no config file refreshing.
57 	 * Assumes an XML file in case of a ".xml" file extension, and a properties file
58 	 * otherwise.
59 	 * @param location the location of the config file: either a "classpath:" location
60 	 * (e.g. "classpath:myLog4j.properties"), an absolute file URL
61 	 * (e.g. "file:C:/log4j.properties), or a plain absolute path in the file system
62 	 * (e.g. "C:/log4j.properties")
63 	 * @throws FileNotFoundException if the location specifies an invalid file path
64 	 */
initLogging(String location)65 	public static void initLogging(String location) throws FileNotFoundException {
66 		String resolvedLocation = SystemPropertyUtils.resolvePlaceholders(location);
67 		URL url = ResourceUtils.getURL(resolvedLocation);
68 		if (resolvedLocation.toLowerCase().endsWith(XML_FILE_EXTENSION)) {
69 			DOMConfigurator.configure(url);
70 		}
71 		else {
72 			PropertyConfigurator.configure(url);
73 		}
74 	}
75 
76 	/**
77 	 * Initialize log4j from the given location, with the given refresh interval
78 	 * for the config file. Assumes an XML file in case of a ".xml" file extension,
79 	 * and a properties file otherwise.
80 	 * <p>Log4j's watchdog thread will asynchronously check whether the timestamp
81 	 * of the config file has changed, using the given interval between checks.
82 	 * A refresh interval of 1000 milliseconds (one second), which allows to
83 	 * do on-demand log level changes with immediate effect, is not unfeasible.
84 	 * <p><b>WARNING:</b> Log4j's watchdog thread does not terminate until VM shutdown;
85 	 * in particular, it does not terminate on LogManager shutdown. Therefore, it is
86 	 * recommended to <i>not</i> use config file refreshing in a production J2EE
87 	 * environment; the watchdog thread would not stop on application shutdown there.
88 	 * @param location the location of the config file: either a "classpath:" location
89 	 * (e.g. "classpath:myLog4j.properties"), an absolute file URL
90 	 * (e.g. "file:C:/log4j.properties), or a plain absolute path in the file system
91 	 * (e.g. "C:/log4j.properties")
92 	 * @param refreshInterval interval between config file refresh checks, in milliseconds
93 	 * @throws FileNotFoundException if the location specifies an invalid file path
94 	 */
initLogging(String location, long refreshInterval)95 	public static void initLogging(String location, long refreshInterval) throws FileNotFoundException {
96 		String resolvedLocation = SystemPropertyUtils.resolvePlaceholders(location);
97 		File file = ResourceUtils.getFile(resolvedLocation);
98 		if (!file.exists()) {
99 			throw new FileNotFoundException("Log4j config file [" + resolvedLocation + "] not found");
100 		}
101 		if (resolvedLocation.toLowerCase().endsWith(XML_FILE_EXTENSION)) {
102 			DOMConfigurator.configureAndWatch(file.getAbsolutePath(), refreshInterval);
103 		}
104 		else {
105 			PropertyConfigurator.configureAndWatch(file.getAbsolutePath(), refreshInterval);
106 		}
107 	}
108 
109 	/**
110 	 * Shut down log4j, properly releasing all file locks.
111 	 * <p>This isn't strictly necessary, but recommended for shutting down
112 	 * log4j in a scenario where the host VM stays alive (for example, when
113 	 * shutting down an application in a J2EE environment).
114 	 */
shutdownLogging()115 	public static void shutdownLogging() {
116 		LogManager.shutdown();
117 	}
118 
119 	/**
120 	 * Set the specified system property to the current working directory.
121 	 * <p>This can be used e.g. for test environments, for applications that leverage
122 	 * Log4jWebConfigurer's "webAppRootKey" support in a web environment.
123 	 * @param key system property key to use, as expected in Log4j configuration
124 	 * (for example: "demo.root", used as "${demo.root}/WEB-INF/demo.log")
125 	 * @see org.springframework.web.util.Log4jWebConfigurer
126 	 */
setWorkingDirSystemProperty(String key)127 	public static void setWorkingDirSystemProperty(String key) {
128 		System.setProperty(key, new File("").getAbsolutePath());
129 	}
130 
131 }
132