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 }