001/*
002 * Copyright 2002-2014 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.util;
018
019import java.io.File;
020import java.io.FileNotFoundException;
021import java.net.URL;
022
023import org.apache.log4j.LogManager;
024import org.apache.log4j.PropertyConfigurator;
025import org.apache.log4j.xml.DOMConfigurator;
026
027/**
028 * Convenience class that features simple methods for custom log4j configuration.
029 *
030 * <p>Only needed for non-default log4j initialization, for example with a custom
031 * config location or a refresh interval. By default, log4j will simply read its
032 * configuration from a "log4j.properties" or "log4j.xml" file in the root of
033 * the classpath.
034 *
035 * <p>For web environments, the analogous Log4jWebConfigurer class can be found
036 * in the web package, reading in its configuration from context-params in
037 * {@code web.xml}. In a J2EE web application, log4j is usually set up
038 * via Log4jConfigListener, delegating to Log4jWebConfigurer underneath.
039 *
040 * @author Juergen Hoeller
041 * @since 13.03.2003
042 * @see org.springframework.web.util.Log4jWebConfigurer
043 * @see org.springframework.web.util.Log4jConfigListener
044 * @deprecated as of Spring 4.2.1, in favor of Apache Log4j 2
045 * (following Apache's EOL declaration for log4j 1.x)
046 */
047@Deprecated
048public abstract class Log4jConfigurer {
049
050        /** Pseudo URL prefix for loading from the class path: "classpath:" */
051        public static final String CLASSPATH_URL_PREFIX = "classpath:";
052
053        /** Extension that indicates a log4j XML config file: ".xml" */
054        public static final String XML_FILE_EXTENSION = ".xml";
055
056
057        /**
058         * Initialize log4j from the given file location, with no config file refreshing.
059         * Assumes an XML file in case of a ".xml" file extension, and a properties file
060         * otherwise.
061         * @param location the location of the config file: either a "classpath:" location
062         * (e.g. "classpath:myLog4j.properties"), an absolute file URL
063         * (e.g. "file:C:/log4j.properties), or a plain absolute path in the file system
064         * (e.g. "C:/log4j.properties")
065         * @throws FileNotFoundException if the location specifies an invalid file path
066         */
067        public static void initLogging(String location) throws FileNotFoundException {
068                String resolvedLocation = SystemPropertyUtils.resolvePlaceholders(location);
069                URL url = ResourceUtils.getURL(resolvedLocation);
070                if (ResourceUtils.URL_PROTOCOL_FILE.equals(url.getProtocol()) && !ResourceUtils.getFile(url).exists()) {
071                        throw new FileNotFoundException("Log4j config file [" + resolvedLocation + "] not found");
072                }
073
074                if (resolvedLocation.toLowerCase().endsWith(XML_FILE_EXTENSION)) {
075                        DOMConfigurator.configure(url);
076                }
077                else {
078                        PropertyConfigurator.configure(url);
079                }
080        }
081
082        /**
083         * Initialize log4j from the given location, with the given refresh interval
084         * for the config file. Assumes an XML file in case of a ".xml" file extension,
085         * and a properties file otherwise.
086         * <p>Log4j's watchdog thread will asynchronously check whether the timestamp
087         * of the config file has changed, using the given interval between checks.
088         * A refresh interval of 1000 milliseconds (one second), which allows to
089         * do on-demand log level changes with immediate effect, is not unfeasible.
090         * <p><b>WARNING:</b> Log4j's watchdog thread does not terminate until VM shutdown;
091         * in particular, it does not terminate on LogManager shutdown. Therefore, it is
092         * recommended to <i>not</i> use config file refreshing in a production J2EE
093         * environment; the watchdog thread would not stop on application shutdown there.
094         * @param location the location of the config file: either a "classpath:" location
095         * (e.g. "classpath:myLog4j.properties"), an absolute file URL
096         * (e.g. "file:C:/log4j.properties), or a plain absolute path in the file system
097         * (e.g. "C:/log4j.properties")
098         * @param refreshInterval interval between config file refresh checks, in milliseconds
099         * @throws FileNotFoundException if the location specifies an invalid file path
100         */
101        public static void initLogging(String location, long refreshInterval) throws FileNotFoundException {
102                String resolvedLocation = SystemPropertyUtils.resolvePlaceholders(location);
103                File file = ResourceUtils.getFile(resolvedLocation);
104                if (!file.exists()) {
105                        throw new FileNotFoundException("Log4j config file [" + resolvedLocation + "] not found");
106                }
107
108                if (resolvedLocation.toLowerCase().endsWith(XML_FILE_EXTENSION)) {
109                        DOMConfigurator.configureAndWatch(file.getAbsolutePath(), refreshInterval);
110                }
111                else {
112                        PropertyConfigurator.configureAndWatch(file.getAbsolutePath(), refreshInterval);
113                }
114        }
115
116        /**
117         * Shut down log4j, properly releasing all file locks.
118         * <p>This isn't strictly necessary, but recommended for shutting down
119         * log4j in a scenario where the host VM stays alive (for example, when
120         * shutting down an application in a J2EE environment).
121         */
122        public static void shutdownLogging() {
123                LogManager.shutdown();
124        }
125
126        /**
127         * Set the specified system property to the current working directory.
128         * <p>This can be used e.g. for test environments, for applications that leverage
129         * Log4jWebConfigurer's "webAppRootKey" support in a web environment.
130         * @param key system property key to use, as expected in Log4j configuration
131         * (for example: "demo.root", used as "${demo.root}/WEB-INF/demo.log")
132         * @see org.springframework.web.util.Log4jWebConfigurer
133         */
134        public static void setWorkingDirSystemProperty(String key) {
135                System.setProperty(key, new File("").getAbsolutePath());
136        }
137
138}