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 level = (Level) m.invoke(null, new Integer[] { new Integer(p) } );
440 }
441 } catch(InvocationTargetException e) {
442 if (e.getTargetException() instanceof InterruptedException
443 || e.getTargetException() instanceof InterruptedIOException) {
444 Thread.currentThread().interrupt();
445 }
446 LogLog.warn("Level deserialization failed, reverting to default.", e);
447 level = Level.toLevel(p);
448 } catch(NoSuchMethodException e) {
449 LogLog.warn("Level deserialization failed, reverting to default.", e);
450 level = Level.toLevel(p);
451 } catch(IllegalAccessException e) {
452 LogLog.warn("Level deserialization failed, reverting to default.", e);
453 level = Level.toLevel(p);
454 } catch(RuntimeException e) {
455 LogLog.warn("Level deserialization failed, reverting to default.", e);
456 level = Level.toLevel(p);
457 }
458 }
459
460 private void readObject(ObjectInputStream ois)
461 throws java.io.IOException, ClassNotFoundException {
462 ois.defaultReadObject();
463 readLevel(ois);
464
465
466 if(locationInfo == null)
467 locationInfo = new LocationInfo(null, null);
468 }
469
470 private
471 void writeObject(ObjectOutputStream oos) throws java.io.IOException {
472
473
474 this.getThreadName();
475
476
477 this.getRenderedMessage();
478
479
480
481 this.getNDC();
482
483
484
485 this.getMDCCopy();
486
487
488 this.getThrowableStrRep();
489
490 oos.defaultWriteObject();
491
492
493 writeLevel(oos);
494 }
495
496 private
497 void writeLevel(ObjectOutputStream oos) throws java.io.IOException {
498
499 oos.writeInt(level.toInt());
500
501 Class clazz = level.getClass();
502 if(clazz == Level.class) {
503 oos.writeObject(null);
504 } else {
505
506
507
508 oos.writeObject(clazz.getName());
509 }
510 }
511
512
513
514
515
516
517
518
519
520
521
522 public final void setProperty(final String propName,
523 final String propValue) {
524 if (mdcCopy == null) {
525 getMDCCopy();
526 }
527 if (mdcCopy == null) {
528 mdcCopy = new Hashtable();
529 }
530 mdcCopy.put(propName, propValue);
531 }
532
533
534
535
536
537
538
539
540
541
542
543 public final String getProperty(final String key) {
544 Object value = getMDC(key);
545 String retval = null;
546 if (value != null) {
547 retval = value.toString();
548 }
549 return retval;
550 }
551
552
553
554
555
556
557
558 public final boolean locationInformationExists() {
559 return (locationInfo != null);
560 }
561
562
563
564
565
566
567
568
569 public final long getTimeStamp() {
570 return timeStamp;
571 }
572
573
574
575
576
577
578
579
580
581
582
583
584 public Set getPropertyKeySet() {
585 return getProperties().keySet();
586 }
587
588
589
590
591
592
593
594
595
596
597
598
599 public Map getProperties() {
600 getMDCCopy();
601 Map properties;
602 if (mdcCopy == null) {
603 properties = new HashMap();
604 } else {
605 properties = mdcCopy;
606 }
607 return Collections.unmodifiableMap(properties);
608 }
609
610
611
612
613
614
615
616 public String getFQNOfLoggerClass() {
617 return fqnOfCategoryClass;
618 }
619
620
621
622
623
624
625
626
627
628
629 public Object removeProperty(String propName) {
630 if (mdcCopy == null) {
631 getMDCCopy();
632 }
633 if (mdcCopy == null) {
634 mdcCopy = new Hashtable();
635 }
636 return mdcCopy.remove(propName);
637 }
638 }