View Javadoc

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&uuml;lc&uuml; */
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