1
2
3
4
5
6
7
8
9
10
11 package psiprobe.tools.logging.slf4jlogback13;
12
13 import java.lang.reflect.InvocationTargetException;
14 import java.lang.reflect.Method;
15 import java.util.ArrayList;
16 import java.util.List;
17
18 import org.apache.commons.lang3.reflect.MethodUtils;
19
20 import psiprobe.tools.logging.DefaultAccessor;
21
22
23
24
25
26
27
28
29
30
31
32
33
34 public class TomcatSlf4jLogback13FactoryAccessor extends DefaultAccessor {
35
36
37
38
39
40
41
42
43
44
45
46
47
48 public TomcatSlf4jLogback13FactoryAccessor(ClassLoader cl)
49 throws ClassNotFoundException, IllegalAccessException, InvocationTargetException,
50 NoSuchMethodException, SecurityException, IllegalArgumentException {
51
52
53 final List<?> providers = findServiceProviders(cl);
54 if (providers.isEmpty()) {
55 throw new RuntimeException("The SLF4J provider binding was not Logback");
56 }
57
58
59 Object provider = providers.get(0);
60
61
62 Method initialize = MethodUtils.getAccessibleMethod(provider.getClass(), "initialize");
63 initialize.invoke(provider);
64
65
66 Method getLoggerFactory =
67 MethodUtils.getAccessibleMethod(provider.getClass(), "getLoggerFactory");
68 Object loggerFactory = getLoggerFactory.invoke(provider);
69
70
71 Class<?> loggerFactoryClass =
72 cl.loadClass("org.apache.juli.logging.ch.qos.logback.classic.LoggerContext");
73 if (!loggerFactoryClass.isInstance(loggerFactory)) {
74 throw new RuntimeException("The SLF4J provider binding was not Logback");
75 }
76 setTarget(loggerFactory);
77 }
78
79
80
81
82
83
84 public TomcatSlf4jLogback13LoggerAccessor getRootLogger() {
85
86
87
88
89 return getLogger("ROOT");
90 }
91
92
93
94
95
96
97
98
99 public TomcatSlf4jLogback13LoggerAccessor getLogger(String name) {
100 try {
101 Class<? extends Object> clazz = getTarget().getClass();
102 Method getLogger = MethodUtils.getAccessibleMethod(clazz, "getLogger", String.class);
103
104 Object logger = getLogger.invoke(getTarget(), name);
105 if (logger == null) {
106 throw new NullPointerException(getTarget() + ".getLogger(\"" + name + "\") returned null");
107 }
108 TomcatSlf4jLogback13LoggerAccessor accessor = new TomcatSlf4jLogback13LoggerAccessor();
109 accessor.setTarget(logger);
110 accessor.setApplication(getApplication());
111 return accessor;
112
113 } catch (Exception e) {
114 logger.error("{}.getLogger('{}') failed", getTarget(), name, e);
115 }
116 return null;
117 }
118
119
120
121
122
123
124
125 @SuppressWarnings("unchecked")
126 public List<TomcatSlf4jLogback13AppenderAccessor> getAppenders() {
127 List<TomcatSlf4jLogback13AppenderAccessor> appenders = new ArrayList<>();
128 try {
129 Class<? extends Object> clazz = getTarget().getClass();
130 Method getLoggerList = MethodUtils.getAccessibleMethod(clazz, "getLoggerList");
131
132 List<Object> loggers = (List<Object>) getLoggerList.invoke(getTarget());
133 for (Object logger : loggers) {
134 TomcatSlf4jLogback13LoggerAccessor accessor = new TomcatSlf4jLogback13LoggerAccessor();
135 accessor.setTarget(logger);
136 accessor.setApplication(getApplication());
137
138 appenders.addAll(accessor.getAppenders());
139 }
140 } catch (Exception e) {
141 logger.error("{}.getLoggerList() failed", getTarget(), e);
142 }
143 return appenders;
144 }
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 private static List<?> findServiceProviders(final ClassLoader cl)
161 throws NoSuchMethodException, SecurityException, ClassNotFoundException,
162 IllegalAccessException, IllegalArgumentException, InvocationTargetException {
163 final Class<?> loggerFactory = cl.loadClass("org.apache.juli.logging.org.slf4j.LoggerFactory");
164 final Method findServiceProviders = loggerFactory.getDeclaredMethod("findServiceProviders");
165
166 findServiceProviders.setAccessible(true);
167 final List<?> providers = (List<?>) findServiceProviders.invoke(null);
168 findServiceProviders.setAccessible(false);
169 return providers;
170 }
171
172 }