1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.slf4j.jul;
26
27 import java.util.logging.Level;
28 import java.util.logging.LogRecord;
29
30 import org.slf4j.Logger;
31 import org.slf4j.Marker;
32 import org.slf4j.event.EventConstants;
33 import org.slf4j.event.LoggingEvent;
34 import org.slf4j.helpers.AbstractLogger;
35 import org.slf4j.helpers.FormattingTuple;
36 import org.slf4j.helpers.LegacyAbstractLogger;
37 import org.slf4j.helpers.MessageFormatter;
38 import org.slf4j.helpers.NormalizedParameters;
39 import org.slf4j.helpers.SubstituteLogger;
40 import org.slf4j.spi.DefaultLoggingEventBuilder;
41 import org.slf4j.spi.LocationAwareLogger;
42
43
44
45
46
47
48
49
50
51
52 public final class JDK14LoggerAdapter extends LegacyAbstractLogger implements LocationAwareLogger {
53
54 private static final long serialVersionUID = -8053026990503422791L;
55
56 transient final java.util.logging.Logger logger;
57
58
59
60 JDK14LoggerAdapter(java.util.logging.Logger logger) {
61 this.logger = logger;
62 this.name = logger.getName();
63 }
64
65
66
67
68
69
70 public boolean isTraceEnabled() {
71 return logger.isLoggable(Level.FINEST);
72 }
73
74
75
76
77
78
79 public boolean isDebugEnabled() {
80 return logger.isLoggable(Level.FINE);
81 }
82
83
84
85
86
87
88 public boolean isInfoEnabled() {
89 return logger.isLoggable(Level.INFO);
90 }
91
92
93
94
95
96
97
98 public boolean isWarnEnabled() {
99 return logger.isLoggable(Level.WARNING);
100 }
101
102
103
104
105
106
107 public boolean isErrorEnabled() {
108 return logger.isLoggable(Level.SEVERE);
109 }
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 @Override
139 protected void handleNormalizedLoggingCall(org.slf4j.event.Level level, Marker marker, String msg, Object[] args, Throwable throwable) {
140 innerNormalizedLoggingCallHandler(getFullyQualifiedCallerName(), level, marker, msg, args, throwable);
141 }
142
143 private void innerNormalizedLoggingCallHandler(String fqcn, org.slf4j.event.Level level, Marker marker, String msg, Object[] args, Throwable throwable) {
144
145 Level julLevel = slf4jLevelToJULLevel(level);
146 String formattedMessage = MessageFormatter.basicArrayFormat(msg, args);
147 LogRecord record = new LogRecord(julLevel, formattedMessage);
148
149
150 record.setLoggerName(getName());
151 record.setThrown(throwable);
152
153
154
155 fillCallerData(fqcn, record);
156 logger.log(record);
157 }
158
159 @Override
160 protected String getFullyQualifiedCallerName() {
161 return SELF;
162 }
163
164 @Override
165 public void log(Marker marker, String callerFQCN, int slf4jLevelInt, String message, Object[] arguments, Throwable throwable) {
166
167 org.slf4j.event.Level slf4jLevel = org.slf4j.event.Level.intToLevel(slf4jLevelInt);
168 Level julLevel = slf4jLevelIntToJULLevel(slf4jLevelInt);
169
170 if (logger.isLoggable(julLevel)) {
171 NormalizedParameters np = NormalizedParameters.normalize(message, arguments, throwable);
172 innerNormalizedLoggingCallHandler(callerFQCN, slf4jLevel, marker, np.getMessage(), np.getArguments(), np.getThrowable());
173 }
174 }
175
176
177
178
179
180
181 final private void fillCallerData(String callerFQCN, LogRecord record) {
182 StackTraceElement[] steArray = new Throwable().getStackTrace();
183
184 int selfIndex = -1;
185 for (int i = 0; i < steArray.length; i++) {
186 final String className = steArray[i].getClassName();
187
188 if (barrierMatch(callerFQCN, className)) {
189 selfIndex = i;
190 break;
191 }
192 }
193
194 int found = -1;
195 for (int i = selfIndex + 1; i < steArray.length; i++) {
196 final String className = steArray[i].getClassName();
197 if (!(barrierMatch(callerFQCN, className))) {
198 found = i;
199 break;
200 }
201 }
202
203 if (found != -1) {
204 StackTraceElement ste = steArray[found];
205
206
207 record.setSourceClassName(ste.getClassName());
208 record.setSourceMethodName(ste.getMethodName());
209 }
210 }
211
212 static String SELF = JDK14LoggerAdapter.class.getName();
213
214 static String SUPER = LegacyAbstractLogger.class.getName();
215 static String SUPER_OF_SUPER = AbstractLogger.class.getName();
216 static String SUBSTITUE = SubstituteLogger.class.getName();
217 static String FLUENT = DefaultLoggingEventBuilder.class.getName();
218
219 static String[] BARRIER_CLASSES = new String[] { SUPER_OF_SUPER, SUPER, SELF, SUBSTITUE, FLUENT };
220
221 private boolean barrierMatch(String callerFQCN, String candidateClassName) {
222 if (candidateClassName.equals(callerFQCN))
223 return true;
224 for (String barrierClassName : BARRIER_CLASSES) {
225 if (barrierClassName.equals(candidateClassName)) {
226 return true;
227 }
228 }
229 return false;
230 }
231
232 private static Level slf4jLevelIntToJULLevel(int levelInt) {
233 org.slf4j.event.Level slf4jLevel = org.slf4j.event.Level.intToLevel(levelInt);
234 return slf4jLevelToJULLevel(slf4jLevel);
235 }
236
237 private static Level slf4jLevelToJULLevel(org.slf4j.event.Level slf4jLevel) {
238 Level julLevel;
239 switch (slf4jLevel) {
240 case TRACE:
241 julLevel = Level.FINEST;
242 break;
243 case DEBUG:
244 julLevel = Level.FINE;
245 break;
246 case INFO:
247 julLevel = Level.INFO;
248 break;
249 case WARN:
250 julLevel = Level.WARNING;
251 break;
252 case ERROR:
253 julLevel = Level.SEVERE;
254 break;
255 default:
256 throw new IllegalStateException("Level " + slf4jLevel + " is not recognized.");
257 }
258 return julLevel;
259 }
260
261
262
263
264 public void log(LoggingEvent event) {
265
266
267 Level julLevel = slf4jLevelToJULLevel(event.getLevel());
268 if (logger.isLoggable(julLevel)) {
269 LogRecord record = eventToRecord(event, julLevel);
270 logger.log(record);
271 }
272 }
273
274 private LogRecord eventToRecord(LoggingEvent event, Level julLevel) {
275 String format = event.getMessage();
276 Object[] arguments = event.getArgumentArray();
277 FormattingTuple ft = MessageFormatter.arrayFormat(format, arguments);
278 if (ft.getThrowable() != null && event.getThrowable() != null) {
279 throw new IllegalArgumentException("both last element in argument array and last argument are of type Throwable");
280 }
281
282 Throwable t = event.getThrowable();
283 if (ft.getThrowable() != null) {
284 t = ft.getThrowable();
285 throw new IllegalStateException("fix above code");
286 }
287
288 LogRecord record = new LogRecord(julLevel, ft.getMessage());
289 record.setLoggerName(event.getLoggerName());
290 record.setMillis(event.getTimeStamp());
291 record.setSourceClassName(EventConstants.NA_SUBST);
292 record.setSourceMethodName(EventConstants.NA_SUBST);
293
294 record.setThrown(t);
295 return record;
296 }
297
298 }