1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.log4j.spi;
19
20 import java.io.InterruptedIOException;
21 import java.io.ObjectInputStream;
22 import java.io.ObjectOutputStream;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Hashtable;
28 import java.util.Map;
29 import java.util.Set;
30
31 import org.apache.log4j.Category;
32 import org.apache.log4j.Level;
33 import org.apache.log4j.MDC;
34 import org.apache.log4j.NDC;
35 import org.apache.log4j.Priority;
36 import org.apache.log4j.helpers.Loader;
37 import org.apache.log4j.helpers.LogLog;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class LoggingEvent implements java.io.Serializable {
56
57 private static long startTime = System.currentTimeMillis();
58
59
60 transient public final String fqnOfCategoryClass;
61
62
63
64
65
66
67
68
69
70
71
72 transient private Category logger;
73
74
75
76
77
78
79
80
81
82 final public String categoryName;
83
84
85
86
87
88
89
90
91
92
93
94
95
96 transient public Priority level;
97
98
99 private String ndc;
100
101
102 private Hashtable mdcCopy;
103
104
105
106
107
108
109 private boolean ndcLookupRequired = true;
110
111
112
113
114
115 private boolean mdcCopyLookupRequired = true;
116
117
118 transient private Object message;
119
120
121
122 private String renderedMessage;
123
124
125 private String threadName;
126
127
128
129
130
131 private ThrowableInformation throwableInfo;
132
133
134
135 public final long timeStamp;
136
137 private LocationInfo locationInfo;
138
139
140 static final long serialVersionUID = -868428216207166145L;
141
142 static final Integer[] PARAM_ARRAY = new Integer[1];
143 static final String TO_LEVEL = "toLevel";
144 static final Class[] TO_LEVEL_PARAMS = new Class[] {int.class};
145 static final Hashtable methodCache = new Hashtable(3);
146
147
148
149
150
151
152
153
154
155
156
157 public LoggingEvent(String fqnOfCategoryClass, Category logger,
158 Priority level, Object message, Throwable throwable) {
159 this.fqnOfCategoryClass = fqnOfCategoryClass;
160 this.logger = logger;
161 this.categoryName = logger.getName();
162 this.level = level;
163 this.message = message;
164 if(throwable != null) {
165 this.throwableInfo = new ThrowableInformation(throwable, logger);
166 }
167 timeStamp = System.currentTimeMillis();
168 }
169
170
171
172
173
174
175
176
177
178
179
180
181 public LoggingEvent(String fqnOfCategoryClass, Category logger,
182 long timeStamp, Priority level, Object message,
183 Throwable throwable) {
184 this.fqnOfCategoryClass = fqnOfCategoryClass;
185 this.logger = logger;
186 this.categoryName = logger.getName();
187 this.level = level;
188 this.message = message;
189 if(throwable != null) {
190 this.throwableInfo = new ThrowableInformation(throwable, logger);
191 }
192
193 this.timeStamp = timeStamp;
194 }
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211 public LoggingEvent(final String fqnOfCategoryClass,
212 final Category logger,
213 final long timeStamp,
214 final Level level,
215 final Object message,
216 final String threadName,
217 final ThrowableInformation throwable,
218 final String ndc,
219 final LocationInfo info,
220 final java.util.Map properties) {
221 super();
222 this.fqnOfCategoryClass = fqnOfCategoryClass;
223 this.logger = logger;
224 if (logger != null) {
225 categoryName = logger.getName();
226 } else {
227 categoryName = null;
228 }
229 this.level = level;
230 this.message = message;
231 if(throwable != null) {
232 this.throwableInfo = throwable;
233 }
234
235 this.timeStamp = timeStamp;
236 this.threadName = threadName;
237 ndcLookupRequired = false;
238 this.ndc = ndc;
239 this.locationInfo = info;
240 mdcCopyLookupRequired = false;
241 if (properties != null) {
242 mdcCopy = new java.util.Hashtable(properties);
243 }
244 }
245
246
247
248
249
250
251 public LocationInfo getLocationInformation() {
252 if(locationInfo == null) {
253 locationInfo = new LocationInfo(new Throwable(), fqnOfCategoryClass);
254 }
255 return locationInfo;
256 }
257
258
259
260
261 public Level getLevel() {
262 return (Level) level;
263 }
264
265
266
267
268
269 public String getLoggerName() {
270 return categoryName;
271 }
272
273
274
275
276
277
278 public Category getLogger() {
279 return logger;
280 }
281
282
283
284
285
286
287
288
289
290
291 public
292 Object getMessage() {
293 if(message != null) {
294 return message;
295 } else {
296 return getRenderedMessage();
297 }
298 }
299
300
301
302
303
304
305 public
306 String getNDC() {
307 if(ndcLookupRequired) {
308 ndcLookupRequired = false;
309 ndc = NDC.get();
310 }
311 return ndc;
312 }
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327 public
328 Object getMDC(String key) {
329 Object r;
330
331
332 if(mdcCopy != null) {
333 r = mdcCopy.get(key);
334 if(r != null) {
335 return r;
336 }
337 }
338 return MDC.get(key);
339 }
340
341
342
343
344
345 public
346 void getMDCCopy() {
347 if(mdcCopyLookupRequired) {
348 mdcCopyLookupRequired = false;
349
350
351 Hashtable t = (Hashtable) MDC.getContext();
352 if(t != null) {
353 mdcCopy = (Hashtable) t.clone();
354 }
355 }
356 }
357
358 public
359 String getRenderedMessage() {
360 if(renderedMessage == null && message != null) {
361 if(message instanceof String)
362 renderedMessage = (String) message;
363 else {
364 LoggerRepository repository = logger.getLoggerRepository();
365
366 if(repository instanceof RendererSupport) {
367 RendererSupport rs = (RendererSupport) repository;
368 renderedMessage= rs.getRendererMap().findAndRender(message);
369 } else {
370 renderedMessage = message.toString();
371 }
372 }
373 }
374 return renderedMessage;
375 }
376
377
378
379
380 public static long getStartTime() {
381 return startTime;
382 }
383
384 public
385 String getThreadName() {
386 if(threadName == null)
387 threadName = (Thread.currentThread()).getName();
388 return threadName;
389 }
390
391
392
393
394
395
396
397
398
399 public
400 ThrowableInformation getThrowableInformation() {
401 return throwableInfo;
402 }
403
404
405
406
407 public
408 String[] getThrowableStrRep() {
409
410 if(throwableInfo == null)
411 return null;
412 else
413 return throwableInfo.getThrowableStrRep();
414 }
415
416
417 private
418 void readLevel(ObjectInputStream ois)
419 throws java.io.IOException, ClassNotFoundException {
420
421 int p = ois.readInt();
422 try {
423 String className = (String) ois.readObject();
424 if(className == null) {
425 level = Level.toLevel(p);
426 } else {
427 Method m = (Method) methodCache.get(className);
428 if(m == null) {
429 Class clazz = Loader.loadClass(className);
430
431
432
433
434
435
436 m = clazz.getDeclaredMethod(TO_LEVEL, TO_LEVEL_PARAMS);
437 methodCache.put(className, m);
438 }
439 PARAM_ARRAY[0] = new Integer(p);
440 level = (Level) m.invoke(null, PARAM_ARRAY);
441 }
442 } catch(InvocationTargetException e) {
443 if (e.getTargetException() instanceof InterruptedException
444 || e.getTargetException() instanceof InterruptedIOException) {
445 Thread.currentThread().interrupt();
446 }
447 LogLog.warn("Level deserialization failed, reverting to default.", e);
448 level = Level.toLevel(p);
449 } catch(NoSuchMethodException e) {
450 LogLog.warn("Level deserialization failed, reverting to default.", e);
451 level = Level.toLevel(p);
452 } catch(IllegalAccessException e) {
453 LogLog.warn("Level deserialization failed, reverting to default.", e);
454 level = Level.toLevel(p);
455 } catch(RuntimeException e) {
456 LogLog.warn("Level deserialization failed, reverting to default.", e);
457 level = Level.toLevel(p);
458 }
459 }
460
461 private void readObject(ObjectInputStream ois)
462 throws java.io.IOException, ClassNotFoundException {
463 ois.defaultReadObject();
464 readLevel(ois);
465
466
467 if(locationInfo == null)
468 locationInfo = new LocationInfo(null, null);
469 }
470
471 private
472 void writeObject(ObjectOutputStream oos) throws java.io.IOException {
473
474
475 this.getThreadName();
476
477
478 this.getRenderedMessage();
479
480
481
482 this.getNDC();
483
484
485
486 this.getMDCCopy();
487
488
489 this.getThrowableStrRep();
490
491 oos.defaultWriteObject();
492
493
494 writeLevel(oos);
495 }
496
497 private
498 void writeLevel(ObjectOutputStream oos) throws java.io.IOException {
499
500 oos.writeInt(level.toInt());
501
502 Class clazz = level.getClass();
503 if(clazz == Level.class) {
504 oos.writeObject(null);
505 } else {
506
507
508
509 oos.writeObject(clazz.getName());
510 }
511 }
512
513
514
515
516
517
518
519
520
521
522
523 public final void setProperty(final String propName,
524 final String propValue) {
525 if (mdcCopy == null) {
526 getMDCCopy();
527 }
528 if (mdcCopy == null) {
529 mdcCopy = new Hashtable();
530 }
531 mdcCopy.put(propName, propValue);
532 }
533
534
535
536
537
538
539
540
541
542
543
544 public final String getProperty(final String key) {
545 Object value = getMDC(key);
546 String retval = null;
547 if (value != null) {
548 retval = value.toString();
549 }
550 return retval;
551 }
552
553
554
555
556
557
558
559 public final boolean locationInformationExists() {
560 return (locationInfo != null);
561 }
562
563
564
565
566
567
568
569
570 public final long getTimeStamp() {
571 return timeStamp;
572 }
573
574
575
576
577
578
579
580
581
582
583
584
585 public Set getPropertyKeySet() {
586 return getProperties().keySet();
587 }
588
589
590
591
592
593
594
595
596
597
598
599
600 public Map getProperties() {
601 getMDCCopy();
602 Map properties;
603 if (mdcCopy == null) {
604 properties = new HashMap();
605 } else {
606 properties = mdcCopy;
607 }
608 return Collections.unmodifiableMap(properties);
609 }
610
611
612
613
614
615
616
617 public String getFQNOfLoggerClass() {
618 return fqnOfCategoryClass;
619 }
620
621
622
623
624
625
626
627
628
629
630 public Object removeProperty(String propName) {
631 if (mdcCopy == null) {
632 getMDCCopy();
633 }
634 if (mdcCopy == null) {
635 mdcCopy = new Hashtable();
636 }
637 return mdcCopy.remove(propName);
638 }
639 }