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