1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.slf4j.helpers;
18
19 import org.apache.logging.log4j.LogManager;
20 import org.apache.logging.log4j.spi.AbstractLogger;
21 import org.apache.logging.log4j.spi.LoggerContext;
22 import org.apache.logging.slf4j.SLF4JLoggingException;
23 import org.slf4j.ILoggerFactory;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26 import org.slf4j.impl.SLF4JLogger;
27
28 import java.util.Map;
29 import java.util.WeakHashMap;
30 import java.util.concurrent.ConcurrentHashMap;
31 import java.util.concurrent.ConcurrentMap;
32
33
34
35
36 public class Log4JLoggerFactory implements ILoggerFactory {
37
38 private static final String FQCN = Log4JLoggerFactory.class.getName();
39 private static final String PACKAGE = "org.slf4j";
40
41 private final Map<LoggerContext, ConcurrentMap<String, Logger>> contextMap =
42 new WeakHashMap<LoggerContext, ConcurrentMap<String, Logger>>();
43
44 public Logger getLogger(String name) {
45 LoggerContext context = getContext();
46 ConcurrentMap<String, Logger> loggers = getLoggersMap(context);
47
48 if (loggers.containsKey(name)) {
49 return loggers.get(name);
50 }
51 String key = Logger.ROOT_LOGGER_NAME.equals(name) ? LogManager.ROOT_LOGGER_NAME : name;
52 org.apache.logging.log4j.Logger logger = context.getLogger(key);
53 if (logger instanceof AbstractLogger) {
54 loggers.putIfAbsent(name, new SLF4JLogger((AbstractLogger) logger, name));
55 return loggers.get(name);
56 }
57 throw new SLF4JLoggingException("SLF4J Adapter requires base logging system to extend Log4J AbstractLogger");
58 }
59
60 private ConcurrentMap<String, Logger> getLoggersMap(LoggerContext context) {
61 synchronized (contextMap) {
62 ConcurrentMap<String, Logger> map = contextMap.get(context);
63 if (map == null) {
64 map = new ConcurrentHashMap<String, Logger>();
65 contextMap.put(context, map);
66 }
67 return map;
68 }
69 }
70 private LoggerContext getContext() {
71 Throwable t = new Throwable();
72 boolean next = false;
73 boolean pkg = false;
74 String fqcn = LoggerFactory.class.getName();
75 for (StackTraceElement element : t.getStackTrace()) {
76 if (FQCN.equals(element.getClassName())) {
77 next = true;
78 continue;
79 }
80 if (next && element.getClassName().startsWith(PACKAGE)) {
81 fqcn = element.getClassName();
82 pkg = true;
83 continue;
84 }
85 if (pkg) {
86 break;
87 }
88 }
89 return PrivateManager.getContext(fqcn);
90 }
91
92
93
94
95 private static class PrivateManager extends LogManager {
96 private static final String FQCN = LoggerFactory.class.getName();
97
98 public static LoggerContext getContext() {
99 return getContext(FQCN, false);
100 }
101
102 public static LoggerContext getContext(String fqcn) {
103 return getContext(fqcn, false);
104 }
105
106 public static org.apache.logging.log4j.Logger getLogger(String name) {
107 return getLogger(FQCN, name);
108 }
109 }
110
111 }