1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j;
18
19 import org.apache.logging.log4j.simple.SimpleLoggerContextFactory;
20 import org.apache.logging.log4j.status.StatusLogger;
21 import org.apache.logging.log4j.spi.LoggerContext;
22 import org.apache.logging.log4j.spi.LoggerContextFactory;
23 import org.apache.logging.log4j.util.PropsUtil;
24
25 import java.io.IOException;
26 import java.net.URL;
27 import java.util.Enumeration;
28 import java.util.Map;
29 import java.util.Properties;
30 import java.util.SortedMap;
31 import java.util.TreeMap;
32
33
34
35
36 public class LogManager {
37
38
39
40 public static final String ROOT_LOGGER_NAME = "";
41
42 private static final String LOGGER_RESOURCE = "META-INF/log4j-provider.properties";
43 private static final String LOGGER_CONTEXT_FACTORY = "LoggerContextFactory";
44 private static final String API_VERSION = "Log4jAPIVersion";
45 private static final String FACTORY_PRIORITY = "FactoryPriority";
46 private static final String[] COMPATIBLE_API_VERSIONS = {
47 "2.0.0"
48 };
49
50 private static final String FACTORY_PROPERTY_NAME = "log4j2.loggerContextFactory";
51
52 private static LoggerContextFactory factory;
53
54 private static final Logger logger = StatusLogger.getLogger();
55
56
57
58
59 protected LogManager() {
60 }
61
62
63
64
65
66 static {
67
68 PropsUtil managerProps = new PropsUtil("log4j2.LogManager.properties");
69 String factoryClass = managerProps.getStringProperty(FACTORY_PROPERTY_NAME);
70 ClassLoader cl = findClassLoader();
71 if (factoryClass != null) {
72 try {
73 Class<?> clazz = cl.loadClass(factoryClass);
74 if (LoggerContextFactory.class.isAssignableFrom(clazz)) {
75 factory = (LoggerContextFactory) clazz.newInstance();
76 }
77 } catch (ClassNotFoundException cnfe) {
78 logger.error("Unable to locate configured LoggerContextFactory {}", factoryClass);
79 } catch (Exception ex) {
80 logger.error("Unable to create configured LoggerContextFactory {}", factoryClass, ex);
81 }
82 }
83
84 if (factory == null) {
85 SortedMap<Integer, LoggerContextFactory> factories = new TreeMap<Integer, LoggerContextFactory>();
86
87 Enumeration<URL> enumResources = null;
88 try {
89 enumResources = cl.getResources(LOGGER_RESOURCE);
90 } catch (IOException e) {
91 logger.fatal("Unable to locate " + LOGGER_RESOURCE, e);
92 }
93
94 if (enumResources != null) {
95 while (enumResources.hasMoreElements()) {
96 Properties props = new Properties();
97 URL url = enumResources.nextElement();
98 try {
99 props.load(url.openStream());
100 } catch (IOException ioe) {
101 logger.error("Unable to read " + url.toString(), ioe);
102 }
103 if (!validVersion(props.getProperty(API_VERSION))) {
104 continue;
105 }
106 String weight = props.getProperty(FACTORY_PRIORITY);
107 Integer priority = weight == null ? -1 : Integer.valueOf(weight);
108 String className = props.getProperty(LOGGER_CONTEXT_FACTORY);
109 if (className != null) {
110 try {
111 Class<?> clazz = cl.loadClass(className);
112 if (LoggerContextFactory.class.isAssignableFrom(clazz)) {
113 factories.put(priority, (LoggerContextFactory) clazz.newInstance());
114 } else {
115 logger.error(className + " does not implement " + LoggerContextFactory.class.getName());
116 }
117 } catch (ClassNotFoundException cnfe) {
118 logger.error("Unable to locate class " + className + " specified in " + url.toString(),
119 cnfe);
120 } catch (IllegalAccessException iae) {
121 logger.error("Unable to create class " + className + " specified in " + url.toString(),
122 iae);
123 } catch (Exception e) {
124 logger.error("Unable to create class " + className + " specified in " + url.toString(), e);
125 e.printStackTrace();
126 }
127 }
128 }
129 if (factories.size() == 0) {
130 logger.error("Unable to locate a logging implementation, using SimpleLogger");
131 factory = new SimpleLoggerContextFactory();
132 } else {
133 StringBuilder sb = new StringBuilder("Multiple logging implementations found: \n");
134 for (Map.Entry<Integer, LoggerContextFactory> entry : factories.entrySet()) {
135 sb.append("Factory: ").append(entry.getValue().getClass().getName());
136 sb.append(", Weighting: ").append(entry.getKey()).append("\n");
137 }
138 factory = factories.get(factories.lastKey());
139 sb.append("Using factory: ").append(factory.getClass().getName());
140 logger.warn(sb.toString());
141
142 }
143 } else {
144 logger.error("Unable to locate a logging implementation, using SimpleLogger");
145 factory = new SimpleLoggerContextFactory();
146 }
147 }
148 }
149
150
151
152
153
154 public static LoggerContextFactory getFactory() {
155 return factory;
156 }
157
158
159
160
161
162
163
164 public static Logger getLogger(String name) {
165 return factory.getContext(LogManager.class.getName(), null, false).getLogger(name);
166 }
167
168
169
170
171
172
173 public static Logger getLogger(Class<?> clazz) {
174 return getLogger(clazz != null ? clazz.getName() : null);
175 }
176
177
178
179
180
181
182 public static Logger getLogger(Object value) {
183 return getLogger(value != null ? value.getClass() : null);
184 }
185
186
187
188
189
190
191
192
193 protected static Logger getLogger(String fqcn, String name) {
194 return factory.getContext(fqcn, null, false).getLogger(name);
195 }
196
197
198
199
200
201
202
203
204 public static LoggerContext getContext() {
205 return factory.getContext(LogManager.class.getName(), null, true);
206 }
207
208
209
210
211
212
213
214
215
216
217 public static LoggerContext getContext(boolean currentContext) {
218 return factory.getContext(LogManager.class.getName(), null, currentContext);
219 }
220
221
222
223
224
225
226
227
228
229
230
231
232 public static LoggerContext getContext(ClassLoader loader, boolean currentContext) {
233 return factory.getContext(LogManager.class.getName(), loader, currentContext);
234 }
235
236
237
238
239
240
241
242
243
244
245
246 protected static LoggerContext getContext(String fqcn, boolean currentContext) {
247 return factory.getContext(fqcn, null, currentContext);
248 }
249
250
251
252
253
254
255
256
257
258
259
260
261
262 protected static LoggerContext getContext(String fqcn, ClassLoader loader, boolean currentContext) {
263 return factory.getContext(fqcn, loader, currentContext);
264 }
265
266 private static ClassLoader findClassLoader() {
267 ClassLoader cl;
268 if (System.getSecurityManager() == null) {
269 cl = Thread.currentThread().getContextClassLoader();
270 } else {
271 cl = java.security.AccessController.doPrivileged(
272 new java.security.PrivilegedAction<ClassLoader>() {
273 public ClassLoader run() {
274 return Thread.currentThread().getContextClassLoader();
275 }
276 }
277 );
278 }
279 if (cl == null) {
280 cl = LogManager.class.getClassLoader();
281 }
282
283 return cl;
284 }
285
286 private static boolean validVersion(String version) {
287 for (String v : COMPATIBLE_API_VERSIONS) {
288 if (version.startsWith(v)) {
289 return true;
290 }
291 }
292 return false;
293 }
294
295 }