1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.log4j;
19
20 import org.apache.log4j.spi.LoggerRepository;
21 import org.apache.log4j.spi.LoggerFactory;
22 import org.apache.log4j.spi.RepositorySelector;
23 import org.apache.log4j.spi.DefaultRepositorySelector;
24 import org.apache.log4j.spi.RootLogger;
25 import org.apache.log4j.spi.NOPLoggerRepository;
26 import org.apache.log4j.helpers.Loader;
27 import org.apache.log4j.helpers.OptionConverter;
28 import org.apache.log4j.helpers.LogLog;
29
30 import java.net.URL;
31 import java.net.MalformedURLException;
32
33
34 import java.util.Enumeration;
35
36 /**
37 * Use the <code>LogManager</code> class to retreive {@link Logger}
38 * instances or to operate on the current {@link
39 * LoggerRepository}. When the <code>LogManager</code> class is loaded
40 * into memory the default initalzation procedure is inititated. The
41 * default intialization procedure</a> is described in the <a
42 * href="../../../../manual.html#defaultInit">short log4j manual</a>.
43 *
44 * @author Ceki Gülcü */
45 public class LogManager {
46
47 /**
48 * @deprecated This variable is for internal use only. It will
49 * become package protected in future versions.
50 * */
51 static public final String DEFAULT_CONFIGURATION_FILE = "log4j.properties";
52
53 static final String DEFAULT_XML_CONFIGURATION_FILE = "log4j.xml";
54
55 /**
56 * @deprecated This variable is for internal use only. It will
57 * become private in future versions.
58 * */
59 static final public String DEFAULT_CONFIGURATION_KEY="log4j.configuration";
60
61 /**
62 * @deprecated This variable is for internal use only. It will
63 * become private in future versions.
64 * */
65 static final public String CONFIGURATOR_CLASS_KEY="log4j.configuratorClass";
66
67 /**
68 * @deprecated This variable is for internal use only. It will
69 * become private in future versions.
70 */
71 public static final String DEFAULT_INIT_OVERRIDE_KEY =
72 "log4j.defaultInitOverride";
73
74
75 static private Object guard = null;
76 static private RepositorySelector repositorySelector;
77
78 static {
79 // By default we use a DefaultRepositorySelector which always returns 'h'.
80 Hierarchy h = new Hierarchy(new RootLogger((Level) Level.DEBUG));
81 repositorySelector = new DefaultRepositorySelector(h);
82
83 /** Search for the properties file log4j.properties in the CLASSPATH. */
84 String override =OptionConverter.getSystemProperty(DEFAULT_INIT_OVERRIDE_KEY,
85 null);
86
87 // if there is no default init override, then get the resource
88 // specified by the user or the default config file.
89 if(override == null || "false".equalsIgnoreCase(override)) {
90
91 String configurationOptionStr = OptionConverter.getSystemProperty(
92 DEFAULT_CONFIGURATION_KEY,
93 null);
94
95 String configuratorClassName = OptionConverter.getSystemProperty(
96 CONFIGURATOR_CLASS_KEY,
97 null);
98
99 URL url = null;
100
101 // if the user has not specified the log4j.configuration
102 // property, we search first for the file "log4j.xml" and then
103 // "log4j.properties"
104 if(configurationOptionStr == null) {
105 url = Loader.getResource(DEFAULT_XML_CONFIGURATION_FILE);
106 if(url == null) {
107 url = Loader.getResource(DEFAULT_CONFIGURATION_FILE);
108 }
109 } else {
110 try {
111 url = new URL(configurationOptionStr);
112 } catch (MalformedURLException ex) {
113 // so, resource is not a URL:
114 // attempt to get the resource from the class path
115 url = Loader.getResource(configurationOptionStr);
116 }
117 }
118
119 // If we have a non-null url, then delegate the rest of the
120 // configuration to the OptionConverter.selectAndConfigure
121 // method.
122 if(url != null) {
123 LogLog.debug("Using URL ["+url+"] for automatic log4j configuration.");
124 try {
125 OptionConverter.selectAndConfigure(url, configuratorClassName,
126 LogManager.getLoggerRepository());
127 } catch (NoClassDefFoundError e) {
128 LogLog.warn("Error during default initialization", e);
129 }
130 } else {
131 LogLog.debug("Could not find resource: ["+configurationOptionStr+"].");
132 }
133 }
134 }
135
136 /**
137 Sets <code>LoggerFactory</code> but only if the correct
138 <em>guard</em> is passed as parameter.
139
140 <p>Initally the guard is null. If the guard is
141 <code>null</code>, then invoking this method sets the logger
142 factory and the guard. Following invocations will throw a {@link
143 IllegalArgumentException}, unless the previously set
144 <code>guard</code> is passed as the second parameter.
145
146 <p>This allows a high-level component to set the {@link
147 RepositorySelector} used by the <code>LogManager</code>.
148
149 <p>For example, when tomcat starts it will be able to install its
150 own repository selector. However, if and when Tomcat is embedded
151 within JBoss, then JBoss will install its own repository selector
152 and Tomcat will use the repository selector set by its container,
153 JBoss. */
154 static
155 public
156 void setRepositorySelector(RepositorySelector selector, Object guard)
157 throws IllegalArgumentException {
158 if((LogManager.guard != null) && (LogManager.guard != guard)) {
159 throw new IllegalArgumentException(
160 "Attempted to reset the LoggerFactory without possessing the guard.");
161 }
162
163 if(selector == null) {
164 throw new IllegalArgumentException("RepositorySelector must be non-null.");
165 }
166
167 LogManager.guard = guard;
168 LogManager.repositorySelector = selector;
169 }
170
171 static
172 public
173 LoggerRepository getLoggerRepository() {
174 if (repositorySelector == null) {
175 repositorySelector = new DefaultRepositorySelector(new NOPLoggerRepository());
176 guard = null;
177 LogLog.error("LogMananger.repositorySelector was null likely due to error in class reloading, using NOPLoggerRepository.");
178 }
179 return repositorySelector.getLoggerRepository();
180 }
181
182 /**
183 Retrieve the appropriate root logger.
184 */
185 public
186 static
187 Logger getRootLogger() {
188 // Delegate the actual manufacturing of the logger to the logger repository.
189 return getLoggerRepository().getRootLogger();
190 }
191
192 /**
193 Retrieve the appropriate {@link Logger} instance.
194 */
195 public
196 static
197 Logger getLogger(final String name) {
198 // Delegate the actual manufacturing of the logger to the logger repository.
199 return getLoggerRepository().getLogger(name);
200 }
201
202 /**
203 Retrieve the appropriate {@link Logger} instance.
204 */
205 public
206 static
207 Logger getLogger(final Class clazz) {
208 // Delegate the actual manufacturing of the logger to the logger repository.
209 return getLoggerRepository().getLogger(clazz.getName());
210 }
211
212
213 /**
214 Retrieve the appropriate {@link Logger} instance.
215 */
216 public
217 static
218 Logger getLogger(final String name, final LoggerFactory factory) {
219 // Delegate the actual manufacturing of the logger to the logger repository.
220 return getLoggerRepository().getLogger(name, factory);
221 }
222
223 public
224 static
225 Logger exists(final String name) {
226 return getLoggerRepository().exists(name);
227 }
228
229 public
230 static
231 Enumeration getCurrentLoggers() {
232 return getLoggerRepository().getCurrentLoggers();
233 }
234
235 public
236 static
237 void shutdown() {
238 getLoggerRepository().shutdown();
239 }
240
241 public
242 static
243 void resetConfiguration() {
244 getLoggerRepository().resetConfiguration();
245 }
246 }
247