24
24
*/
25
25
package org .slf4j .jul ;
26
26
27
+ import java .util .List ;
27
28
import java .util .logging .Level ;
28
29
import java .util .logging .LogRecord ;
29
30
30
31
import org .slf4j .Logger ;
31
32
import org .slf4j .Marker ;
32
33
import org .slf4j .event .EventConstants ;
34
+ import org .slf4j .event .KeyValuePair ;
33
35
import org .slf4j .event .LoggingEvent ;
34
36
import org .slf4j .helpers .AbstractLogger ;
35
37
import org .slf4j .helpers .FormattingTuple ;
36
38
import org .slf4j .helpers .LegacyAbstractLogger ;
37
39
import org .slf4j .helpers .MessageFormatter ;
38
40
import org .slf4j .helpers .NormalizedParameters ;
39
- import org .slf4j .helpers .SubstituteLogger ;
40
- import org .slf4j .spi .DefaultLoggingEventBuilder ;
41
41
import org .slf4j .spi .LocationAwareLogger ;
42
+ import org .slf4j .spi .LoggingEventAware ;
42
43
43
44
/**
44
45
* A wrapper over {@link java.util.logging.Logger java.util.logging.Logger} in
49
50
* @author Ceki Gülcü
50
51
* @author Peter Royal
51
52
*/
52
- public final class JDK14LoggerAdapter extends LegacyAbstractLogger implements LocationAwareLogger {
53
+ public final class JDK14LoggerAdapter extends LegacyAbstractLogger implements LocationAwareLogger , LoggingEventAware {
53
54
54
55
private static final long serialVersionUID = -8053026990503422791L ;
55
56
@@ -139,7 +140,8 @@ public boolean isErrorEnabled() {
139
140
*/
140
141
@ Override
141
142
protected void handleNormalizedLoggingCall (org .slf4j .event .Level level , Marker marker , String msg , Object [] args , Throwable throwable ) {
142
- innerNormalizedLoggingCallHandler (getFullyQualifiedCallerName (), level , marker , msg , args , throwable );
143
+ // AbstractLogger is the entry point of all classic API calls
144
+ innerNormalizedLoggingCallHandler (SUPER_OF_SUPER , level , marker , msg , args , throwable );
143
145
}
144
146
145
147
private void innerNormalizedLoggingCallHandler (String fqcn , org .slf4j .event .Level level , Marker marker , String msg , Object [] args , Throwable throwable ) {
@@ -180,13 +182,28 @@ public void log(Marker marker, String callerFQCN, int slf4jLevelInt, String mess
180
182
*
181
183
* @param record The record to update
182
184
*/
183
- final private void fillCallerData (String callerFQCN , LogRecord record ) {
185
+ private void fillCallerData (String callerFQCN , LogRecord record ) {
184
186
StackTraceElement [] steArray = new Throwable ().getStackTrace ();
187
+ // Find the first stack trace element matching the caller boundary
188
+ int selfIndex = NOT_FOUND ;
189
+ for (int i = 0 ; i < steArray .length ; i ++) {
190
+ final String className = steArray [i ].getClassName ();
191
+ if (className .equals (callerFQCN )) {
192
+ selfIndex = i ;
193
+ break ;
194
+ }
195
+ }
196
+ // Find the first stack trace element after the caller boundary
197
+ int found = NOT_FOUND ;
198
+ for (int i = selfIndex + 1 ; i < steArray .length ; i ++) {
199
+ final String className = steArray [i ].getClassName ();
200
+ if (!(className .equals (callerFQCN ))) {
201
+ found = i ;
202
+ break ;
203
+ }
204
+ }
185
205
186
- int furthestIndex = findFurthestIndex (callerFQCN , steArray );
187
-
188
- if (furthestIndex != NOT_FOUND ) {
189
- int found = furthestIndex +1 ;
206
+ if (found != NOT_FOUND ) {
190
207
StackTraceElement ste = steArray [found ];
191
208
// setting the class name has the side effect of setting
192
209
// the needToInferCaller variable to false.
@@ -195,42 +212,9 @@ final private void fillCallerData(String callerFQCN, LogRecord record) {
195
212
}
196
213
}
197
214
198
- // find the furthest index which matches any of the barrier classes
199
- // We assume that the actual caller is at most MAX_SEARCH_DEPTH calls away
200
- private int findFurthestIndex (String callerFQCN , StackTraceElement [] steArray ) {
201
-
202
- final int maxIndex = Math .min (MAX_SEARCH_DEPTH , steArray .length );
203
- int furthestIndex = NOT_FOUND ;
204
-
205
- for (int i = 0 ; i < maxIndex ; i ++) {
206
- final String className = steArray [i ].getClassName ();
207
- if (barrierMatch (callerFQCN , className )) {
208
- furthestIndex = i ;
209
- }
210
- }
211
- return furthestIndex ;
212
- }
213
-
214
- static final int MAX_SEARCH_DEPTH = 12 ;
215
- static String SELF = JDK14LoggerAdapter .class .getName ();
215
+ static String SELF = JDK14LoggerAdapter .class .getName ();
216
216
217
- static String SUPER = LegacyAbstractLogger .class .getName ();
218
217
static String SUPER_OF_SUPER = AbstractLogger .class .getName ();
219
- static String SUBSTITUE = SubstituteLogger .class .getName ();
220
- static String FLUENT = DefaultLoggingEventBuilder .class .getName ();
221
-
222
- static String [] BARRIER_CLASSES = new String [] { SUPER_OF_SUPER , SUPER , SELF , SUBSTITUE , FLUENT };
223
-
224
- private boolean barrierMatch (String callerFQCN , String candidateClassName ) {
225
- if (candidateClassName .equals (callerFQCN ))
226
- return true ;
227
- for (String barrierClassName : BARRIER_CLASSES ) {
228
- if (barrierClassName .equals (candidateClassName )) {
229
- return true ;
230
- }
231
- }
232
- return false ;
233
- }
234
218
235
219
private static Level slf4jLevelIntToJULLevel (int levelInt ) {
236
220
org .slf4j .event .Level slf4jLevel = org .slf4j .event .Level .intToLevel (levelInt );
@@ -264,12 +248,15 @@ private static Level slf4jLevelToJULLevel(org.slf4j.event.Level slf4jLevel) {
264
248
/**
265
249
* @since 1.7.15
266
250
*/
251
+ @ Override
267
252
public void log (LoggingEvent event ) {
268
253
// assumes that the invocation is made from a substitute logger
269
254
// this assumption might change in the future with the advent of a fluent API
270
255
Level julLevel = slf4jLevelToJULLevel (event .getLevel ());
271
256
if (logger .isLoggable (julLevel )) {
272
257
LogRecord record = eventToRecord (event , julLevel );
258
+ String callerBoundary = event .getCallerBoundary ();
259
+ fillCallerData (callerBoundary != null ? callerBoundary : SELF , record );
273
260
logger .log (record );
274
261
}
275
262
}
@@ -279,16 +266,18 @@ private LogRecord eventToRecord(LoggingEvent event, Level julLevel) {
279
266
Object [] arguments = event .getArgumentArray ();
280
267
FormattingTuple ft = MessageFormatter .arrayFormat (format , arguments );
281
268
if (ft .getThrowable () != null && event .getThrowable () != null ) {
282
- throw new IllegalArgumentException ("both last element in argument array and last argument are of type Throwable" );
269
+ throw new IllegalArgumentException (
270
+ "both last element in argument array and last argument are of type Throwable" );
283
271
}
284
272
285
273
Throwable t = event .getThrowable ();
286
- if (ft .getThrowable () != null ) {
274
+ if (t == null && ft .getThrowable () != null ) {
287
275
t = ft .getThrowable ();
288
- throw new IllegalStateException ("fix above code" );
289
276
}
290
277
291
- LogRecord record = new LogRecord (julLevel , ft .getMessage ());
278
+ LogRecord record = new LogRecord (
279
+ julLevel ,
280
+ prependMarkersAndKeyValuePairs (event .getMarkers (), event .getKeyValuePairs (), ft .getMessage ()));
292
281
record .setLoggerName (event .getLoggerName ());
293
282
record .setMillis (event .getTimeStamp ());
294
283
record .setSourceClassName (EventConstants .NA_SUBST );
@@ -298,4 +287,31 @@ private LogRecord eventToRecord(LoggingEvent event, Level julLevel) {
298
287
return record ;
299
288
}
300
289
290
+ private String prependMarkersAndKeyValuePairs (
291
+ List <Marker > markers , List <KeyValuePair > KeyValuePairs , String message ) {
292
+ boolean hasMarkers = isNotEmpty (markers );
293
+ boolean hasKeyValuePairs = isNotEmpty (KeyValuePairs );
294
+ if (!hasMarkers && !hasKeyValuePairs ) {
295
+ return message ;
296
+ }
297
+ StringBuilder sb = new StringBuilder (message .length ());
298
+ if (hasMarkers ) {
299
+ for (Marker marker : markers ) {
300
+ sb .append (marker ).append (' ' );
301
+ }
302
+ }
303
+ if (hasKeyValuePairs ) {
304
+ for (KeyValuePair keyValuePair : KeyValuePairs ) {
305
+ sb .append (keyValuePair .key )
306
+ .append ('=' )
307
+ .append (keyValuePair .value )
308
+ .append (' ' );
309
+ }
310
+ }
311
+ return sb .append (message ).toString ();
312
+ }
313
+
314
+ private boolean isNotEmpty (List <?> list ) {
315
+ return list != null && !list .isEmpty ();
316
+ }
301
317
}
0 commit comments