View Javadoc
1   package org.apache.commons.jcs3.log;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one or more
5    * contributor license agreements. See the NOTICE file distributed with
6    * this work for additional information regarding copyright ownership.
7    * The ASF licenses this file to You under the Apache license, Version 2.0
8    * (the "License"); you may not use this file except in compliance with
9    * the License. You may obtain a copy of the License at
10   *
11   *      http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the license for the specific language governing permissions and
17   * limitations under the license.
18   */
19  
20  import java.util.ArrayList;
21  import java.util.Iterator;
22  import java.util.List;
23  import java.util.ServiceConfigurationError;
24  import java.util.ServiceLoader;
25  
26  /**
27   * This is a borrowed and stripped-down version of the log4j2 LogManager class.
28   *
29   * The anchor point for the JCS logging system. The most common usage of this
30   * class is to obtain a named {@link Log}.
31   */
32  public class LogManager
33  {
34      /**
35       * The name of log subsystem
36       */
37      private static String logSystem;
38  
39      /** Log systems currently known */
40      public static final String LOGSYSTEM_JAVA_UTIL_LOGGING = "jul";
41      public static final String LOGSYSTEM_LOG4J2 = "log4j2";
42  
43      /**
44       * The SPI LogFactory
45       */
46      private static class LogFactoryHolder
47      {
48          static final LogFactory INSTANCE = createLogFactory();
49  
50          /**
51           * Scans the classpath to find a logging implementation.
52           *
53           * @return the LogFactory
54           * @throws RuntimeException, if no factory implementation could be found
55           */
56          private static LogFactory createLogFactory()
57          {
58              final ServiceLoader<LogFactory> factories = ServiceLoader.load(LogFactory.class);
59              if (LogManager.logSystem == null)
60              {
61                  LogManager.logSystem = System.getProperty("jcs.logSystem",
62                          LOGSYSTEM_JAVA_UTIL_LOGGING);
63              }
64  
65              // Store errors that may occur until log system is available
66              List<ServiceConfigurationError> errors = new ArrayList<>();
67              Iterator<LogFactory> itr = factories.iterator();
68              LogFactory factory = null;
69              while (itr.hasNext())
70              {
71                  try
72                  {
73                      LogFactory instance = itr.next();
74                      if (logSystem.equalsIgnoreCase(instance.getName()))
75                      {
76                          factory = instance;
77                          break;
78                      }
79                  }
80                  catch (ServiceConfigurationError e)
81                  {
82                      errors.add(e);
83                  }
84              }
85              if (factory != null)
86              {
87                  if (!errors.isEmpty())
88                  {
89                      Log log = factory.getLog(LogFactoryHolder.class);
90  
91                      for (ServiceConfigurationError error : errors)
92                      {
93                          log.debug("Error loading LogFactory", error);
94                      }
95                      log.debug("Found LogFactory for " + logSystem);
96                  }
97                  return factory;
98              }
99  
100             // No log system could be found --> report errors to stderr
101             errors.forEach(e -> System.err.println(e.getMessage()));
102             throw new RuntimeException("Could not find factory implementation for log subsystem " + logSystem);
103         }
104     }
105 
106     /**
107      * Set the log system. Must be called before getLog is called
108      *
109      * @param logSystem the logSystem to set
110      */
111     public static void setLogSystem(final String logSystem)
112     {
113         LogManager.logSystem = logSystem;
114     }
115 
116     /**
117      * Return the LogFactory
118      */
119     private static LogFactory getLogFactory()
120     {
121         return LogFactoryHolder.INSTANCE;
122     }
123 
124     /**
125      * Prevents instantiation
126      */
127     protected LogManager()
128     {
129     }
130 
131     /**
132      * Shutdown the logging system if the logging system supports it.
133      */
134     public static void shutdown()
135     {
136         getLogFactory().shutdown();
137     }
138 
139     /**
140      * Returns a Log using the fully qualified name of the Class as the Log
141      * name.
142      *
143      * @param clazz
144      *            The Class whose name should be used as the Log name.
145      * @return The Log.
146      * @throws UnsupportedOperationException
147      *             if {@code clazz} is {@code null}
148      */
149     public static Log getLog(final Class<?> clazz)
150     {
151         return getLogFactory().getLog(clazz);
152     }
153 
154     /**
155      * Returns a Log with the specified name.
156      *
157      * @param name
158      *            The logger name.
159      * @return The Log.
160      * @throws UnsupportedOperationException
161      *             if {@code name} is {@code null}
162      */
163     public static Log getLog(final String name)
164     {
165         return getLogFactory().getLog(name);
166     }
167 
168     /**
169      * Returns the root logger.
170      *
171      * @return the root logger, named {@link LogFactory#ROOT_LOGGER_NAME}.
172      */
173     public static Log getRootLogger()
174     {
175         return getLog(LogFactory.ROOT_LOGGER_NAME);
176     }
177 }