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