1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.logging.log4j.core.impl;
18
19 import java.io.IOException;
20 import java.io.InvalidObjectException;
21 import java.io.ObjectInputStream;
22 import java.io.Serializable;
23 import java.rmi.MarshalledObject;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Objects;
27
28 import org.apache.logging.log4j.Level;
29 import org.apache.logging.log4j.Marker;
30 import org.apache.logging.log4j.ThreadContext;
31 import org.apache.logging.log4j.core.ContextDataInjector;
32 import org.apache.logging.log4j.util.ReadOnlyStringMap;
33 import org.apache.logging.log4j.core.LogEvent;
34 import org.apache.logging.log4j.core.async.RingBufferLogEvent;
35 import org.apache.logging.log4j.core.config.LoggerConfig;
36 import org.apache.logging.log4j.core.config.Property;
37 import org.apache.logging.log4j.core.util.Clock;
38 import org.apache.logging.log4j.core.util.ClockFactory;
39 import org.apache.logging.log4j.core.util.DummyNanoClock;
40 import org.apache.logging.log4j.core.util.NanoClock;
41 import org.apache.logging.log4j.message.LoggerNameAwareMessage;
42 import org.apache.logging.log4j.message.Message;
43 import org.apache.logging.log4j.message.ReusableMessage;
44 import org.apache.logging.log4j.message.SimpleMessage;
45 import org.apache.logging.log4j.message.TimestampMessage;
46 import org.apache.logging.log4j.util.StackLocatorUtil;
47 import org.apache.logging.log4j.util.StringMap;
48 import org.apache.logging.log4j.status.StatusLogger;
49 import org.apache.logging.log4j.util.Strings;
50
51
52
53
54 public class Log4jLogEvent implements LogEvent {
55
56 private static final long serialVersionUID = -8393305700508709443L;
57 private static final Clock CLOCK = ClockFactory.getClock();
58 private static volatile NanoClock nanoClock = new DummyNanoClock();
59 private static final ContextDataInjector CONTEXT_DATA_INJECTOR = ContextDataInjectorFactory.createInjector();
60
61 private final String loggerFqcn;
62 private final Marker marker;
63 private final Level level;
64 private final String loggerName;
65 private Message message;
66 private final long timeMillis;
67 private final transient Throwable thrown;
68 private ThrowableProxy thrownProxy;
69 private final StringMap contextData;
70 private final ThreadContext.ContextStack contextStack;
71 private long threadId;
72 private String threadName;
73 private int threadPriority;
74 private StackTraceElement source;
75 private boolean includeLocation;
76 private boolean endOfBatch = false;
77
78 private final transient long nanoTime;
79
80
81 public static class Builder implements org.apache.logging.log4j.core.util.Builder<LogEvent> {
82
83 private String loggerFqcn;
84 private Marker marker;
85 private Level level;
86 private String loggerName;
87 private Message message;
88 private Throwable thrown;
89 private long timeMillis = CLOCK.currentTimeMillis();
90 private ThrowableProxy thrownProxy;
91 private StringMap contextData = createContextData((List<Property>) null);
92 private ThreadContext.ContextStack contextStack = ThreadContext.getImmutableStack();
93 private long threadId;
94 private String threadName;
95 private int threadPriority;
96 private StackTraceElement source;
97 private boolean includeLocation;
98 private boolean endOfBatch = false;
99 private long nanoTime;
100
101 public Builder() {
102 }
103
104 public Builder(final LogEvent other) {
105 Objects.requireNonNull(other);
106 if (other instanceof RingBufferLogEvent) {
107 ((RingBufferLogEvent) other).initializeBuilder(this);
108 return;
109 }
110 if (other instanceof MutableLogEvent) {
111 ((MutableLogEvent) other).initializeBuilder(this);
112 return;
113 }
114 this.loggerFqcn = other.getLoggerFqcn();
115 this.marker = other.getMarker();
116 this.level = other.getLevel();
117 this.loggerName = other.getLoggerName();
118 this.message = other.getMessage();
119 this.timeMillis = other.getTimeMillis();
120 this.thrown = other.getThrown();
121 this.contextStack = other.getContextStack();
122 this.includeLocation = other.isIncludeLocation();
123 this.endOfBatch = other.isEndOfBatch();
124 this.nanoTime = other.getNanoTime();
125
126
127 if (other instanceof Log4jLogEvent) {
128 final Log4jLogEvent evt = (Log4jLogEvent) other;
129 this.contextData = evt.contextData;
130 this.thrownProxy = evt.thrownProxy;
131 this.source = evt.source;
132 this.threadId = evt.threadId;
133 this.threadName = evt.threadName;
134 this.threadPriority = evt.threadPriority;
135 } else {
136 if (other.getContextData() instanceof StringMap) {
137 this.contextData = (StringMap) other.getContextData();
138 } else {
139 if (this.contextData.isFrozen()) {
140 this.contextData = ContextDataFactory.createContextData();
141 } else {
142 this.contextData.clear();
143 }
144 this.contextData.putAll(other.getContextData());
145
146 }
147 this.thrownProxy = other.getThrownProxy();
148 this.source = other.getSource();
149 this.threadId = other.getThreadId();
150 this.threadName = other.getThreadName();
151 this.threadPriority = other.getThreadPriority();
152 }
153 }
154
155 public Builder setLevel(final Level level) {
156 this.level = level;
157 return this;
158 }
159
160 public Builder setLoggerFqcn(final String loggerFqcn) {
161 this.loggerFqcn = loggerFqcn;
162 return this;
163 }
164
165 public Builder setLoggerName(final String loggerName) {
166 this.loggerName = loggerName;
167 return this;
168 }
169
170 public Builder setMarker(final Marker marker) {
171 this.marker = marker;
172 return this;
173 }
174
175 public Builder setMessage(final Message message) {
176 this.message = message;
177 return this;
178 }
179
180 public Builder setThrown(final Throwable thrown) {
181 this.thrown = thrown;
182 return this;
183 }
184
185 public Builder setTimeMillis(final long timeMillis) {
186 this.timeMillis = timeMillis;
187 return this;
188 }
189
190 public Builder setThrownProxy(final ThrowableProxy thrownProxy) {
191 this.thrownProxy = thrownProxy;
192 return this;
193 }
194
195 @Deprecated
196 public Builder setContextMap(final Map<String, String> contextMap) {
197 contextData = ContextDataFactory.createContextData();
198 if (contextMap != null) {
199 for (final Map.Entry<String, String> entry : contextMap.entrySet()) {
200 contextData.putValue(entry.getKey(), entry.getValue());
201 }
202 }
203 return this;
204 }
205
206 public Builder setContextData(final StringMap contextData) {
207 this.contextData = contextData;
208 return this;
209 }
210
211 public Builder setContextStack(final ThreadContext.ContextStack contextStack) {
212 this.contextStack = contextStack;
213 return this;
214 }
215
216 public Builder setThreadId(final long threadId) {
217 this.threadId = threadId;
218 return this;
219 }
220
221 public Builder setThreadName(final String threadName) {
222 this.threadName = threadName;
223 return this;
224 }
225
226 public Builder setThreadPriority(final int threadPriority) {
227 this.threadPriority = threadPriority;
228 return this;
229 }
230
231 public Builder setSource(final StackTraceElement source) {
232 this.source = source;
233 return this;
234 }
235
236 public Builder setIncludeLocation(final boolean includeLocation) {
237 this.includeLocation = includeLocation;
238 return this;
239 }
240
241 public Builder setEndOfBatch(final boolean endOfBatch) {
242 this.endOfBatch = endOfBatch;
243 return this;
244 }
245
246
247
248
249
250
251
252 public Builder setNanoTime(final long nanoTime) {
253 this.nanoTime = nanoTime;
254 return this;
255 }
256
257 @Override
258 public Log4jLogEvent build() {
259 final Log4jLogEvent result = new Log4jLogEvent(loggerName, marker, loggerFqcn, level, message, thrown,
260 thrownProxy, contextData, contextStack, threadId, threadName, threadPriority, source, timeMillis,
261 nanoTime);
262 result.setIncludeLocation(includeLocation);
263 result.setEndOfBatch(endOfBatch);
264 return result;
265 }
266 }
267
268
269
270
271
272 public static Builder newBuilder() {
273 return new Builder();
274 }
275
276 public Log4jLogEvent() {
277 this(Strings.EMPTY, null, Strings.EMPTY, null, null, (Throwable) null, null, null, null, 0, null,
278 0, null, CLOCK.currentTimeMillis(), nanoClock.nanoTime());
279 }
280
281
282
283
284
285 @Deprecated
286 public Log4jLogEvent(final long timestamp) {
287 this(Strings.EMPTY, null, Strings.EMPTY, null, null, (Throwable) null, null, null, null, 0, null,
288 0, null, timestamp, nanoClock.nanoTime());
289 }
290
291
292
293
294
295
296
297
298
299
300
301 @Deprecated
302 public Log4jLogEvent(final String loggerName, final Marker marker, final String loggerFQCN, final Level level,
303 final Message message, final Throwable t) {
304 this(loggerName, marker, loggerFQCN, level, message, null, t);
305 }
306
307
308
309
310
311
312
313
314
315
316
317
318 public Log4jLogEvent(final String loggerName, final Marker marker, final String loggerFQCN, final Level level,
319 final Message message, final List<Property> properties, final Throwable t) {
320 this(loggerName, marker, loggerFQCN, level, message, t, null, createContextData(properties),
321 ThreadContext.getDepth() == 0 ? null : ThreadContext.cloneStack(),
322 0,
323 null,
324 0,
325 null,
326
327 message instanceof TimestampMessage ? ((TimestampMessage) message).getTimestamp() :
328 CLOCK.currentTimeMillis(), nanoClock.nanoTime());
329 }
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346 @Deprecated
347 public Log4jLogEvent(final String loggerName, final Marker marker, final String loggerFQCN, final Level level,
348 final Message message, final Throwable t, final Map<String, String> mdc,
349 final ThreadContext.ContextStack ndc, final String threadName,
350 final StackTraceElement location, final long timestampMillis) {
351 this(loggerName, marker, loggerFQCN, level, message, t, null, createContextData(mdc), ndc, 0,
352 threadName, 0, location, timestampMillis, nanoClock.nanoTime());
353 }
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372 @Deprecated
373 public static Log4jLogEvent createEvent(final String loggerName, final Marker marker, final String loggerFQCN,
374 final Level level, final Message message, final Throwable thrown,
375 final ThrowableProxy thrownProxy,
376 final Map<String, String> mdc, final ThreadContext.ContextStack ndc,
377 final String threadName, final StackTraceElement location,
378 final long timestamp) {
379 final Log4jLogEvent result = new Log4jLogEvent(loggerName, marker, loggerFQCN, level, message, thrown,
380 thrownProxy, createContextData(mdc), ndc, 0, threadName, 0, location, timestamp, nanoClock.nanoTime());
381 return result;
382 }
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403 private Log4jLogEvent(final String loggerName, final Marker marker, final String loggerFQCN, final Level level,
404 final Message message, final Throwable thrown, final ThrowableProxy thrownProxy,
405 final StringMap contextData, final ThreadContext.ContextStack contextStack, final long threadId,
406 final String threadName, final int threadPriority, final StackTraceElement source,
407 final long timestampMillis, final long nanoTime) {
408 this.loggerName = loggerName;
409 this.marker = marker;
410 this.loggerFqcn = loggerFQCN;
411 this.level = level == null ? Level.OFF : level;
412 this.message = message;
413 this.thrown = thrown;
414 this.thrownProxy = thrownProxy;
415 this.contextData = contextData == null ? ContextDataFactory.createContextData() : contextData;
416 this.contextStack = contextStack == null ? ThreadContext.EMPTY_STACK : contextStack;
417 this.timeMillis = message instanceof TimestampMessage
418 ? ((TimestampMessage) message).getTimestamp()
419 : timestampMillis;
420 this.threadId = threadId;
421 this.threadName = threadName;
422 this.threadPriority = threadPriority;
423 this.source = source;
424 if (message != null && message instanceof LoggerNameAwareMessage) {
425 ((LoggerNameAwareMessage) message).setLoggerName(loggerName);
426 }
427 this.nanoTime = nanoTime;
428 }
429
430 private static StringMap createContextData(final Map<String, String> contextMap) {
431 final StringMap result = ContextDataFactory.createContextData();
432 if (contextMap != null) {
433 for (final Map.Entry<String, String> entry : contextMap.entrySet()) {
434 result.putValue(entry.getKey(), entry.getValue());
435 }
436 }
437 return result;
438 }
439
440 private static StringMap createContextData(final List<Property> properties) {
441 final StringMap reusable = ContextDataFactory.createContextData();
442 return CONTEXT_DATA_INJECTOR.injectContextData(properties, reusable);
443 }
444
445
446
447
448
449 public static NanoClock getNanoClock() {
450 return nanoClock;
451 }
452
453
454
455
456
457
458
459
460
461 public static void setNanoClock(final NanoClock nanoClock) {
462 Log4jLogEvent.nanoClock = Objects.requireNonNull(nanoClock, "NanoClock must be non-null");
463 StatusLogger.getLogger().trace("Using {} for nanosecond timestamps.", nanoClock.getClass().getSimpleName());
464 }
465
466
467
468
469
470 public Builder asBuilder() {
471 return new Builder(this);
472 }
473
474 @Override
475 public Log4jLogEvent toImmutable() {
476 if (getMessage() instanceof ReusableMessage) {
477 makeMessageImmutable();
478 }
479 return this;
480 }
481
482
483
484
485
486 @Override
487 public Level getLevel() {
488 return level;
489 }
490
491
492
493
494
495 @Override
496 public String getLoggerName() {
497 return loggerName;
498 }
499
500
501
502
503
504 @Override
505 public Message getMessage() {
506 return message;
507 }
508
509 public void makeMessageImmutable() {
510 message = new SimpleMessage(message.getFormattedMessage());
511 }
512
513 @Override
514 public long getThreadId() {
515 if (threadId == 0) {
516 threadId = Thread.currentThread().getId();
517 }
518 return threadId;
519 }
520
521
522
523
524
525 @Override
526 public String getThreadName() {
527 if (threadName == null) {
528 threadName = Thread.currentThread().getName();
529 }
530 return threadName;
531 }
532
533 @Override
534 public int getThreadPriority() {
535 if (threadPriority == 0) {
536 threadPriority = Thread.currentThread().getPriority();
537 }
538 return threadPriority;
539 }
540
541
542
543
544
545 @Override
546 public long getTimeMillis() {
547 return timeMillis;
548 }
549
550
551
552
553
554 @Override
555 public Throwable getThrown() {
556 return thrown;
557 }
558
559
560
561
562
563 @Override
564 public ThrowableProxy getThrownProxy() {
565 if (thrownProxy == null && thrown != null) {
566 thrownProxy = new ThrowableProxy(thrown);
567 }
568 return thrownProxy;
569 }
570
571
572
573
574
575
576 @Override
577 public Marker getMarker() {
578 return marker;
579 }
580
581
582
583
584
585 @Override
586 public String getLoggerFqcn() {
587 return loggerFqcn;
588 }
589
590
591
592
593
594
595 @Override
596 public ReadOnlyStringMap getContextData() {
597 return contextData;
598 }
599
600
601
602
603 @Override
604 public Map<String, String> getContextMap() {
605 return contextData.toMap();
606 }
607
608
609
610
611
612 @Override
613 public ThreadContext.ContextStack getContextStack() {
614 return contextStack;
615 }
616
617
618
619
620
621
622 @Override
623 public StackTraceElement getSource() {
624 if (source != null) {
625 return source;
626 }
627 if (loggerFqcn == null || !includeLocation) {
628 return null;
629 }
630 source = StackLocatorUtil.calcLocation(loggerFqcn);
631 return source;
632 }
633
634 @Override
635 public boolean isIncludeLocation() {
636 return includeLocation;
637 }
638
639 @Override
640 public void setIncludeLocation(final boolean includeLocation) {
641 this.includeLocation = includeLocation;
642 }
643
644 @Override
645 public boolean isEndOfBatch() {
646 return endOfBatch;
647 }
648
649 @Override
650 public void setEndOfBatch(final boolean endOfBatch) {
651 this.endOfBatch = endOfBatch;
652 }
653
654 @Override
655 public long getNanoTime() {
656 return nanoTime;
657 }
658
659
660
661
662
663 protected Object writeReplace() {
664 getThrownProxy();
665 return new LogEventProxy(this, this.includeLocation);
666 }
667
668
669
670
671
672
673
674
675
676
677 public static Serializable serialize(final LogEvent event, final boolean includeLocation) {
678 if (event instanceof Log4jLogEvent) {
679 event.getThrownProxy();
680 return new LogEventProxy((Log4jLogEvent) event, includeLocation);
681 }
682 return new LogEventProxy(event, includeLocation);
683 }
684
685
686
687
688
689
690
691
692
693
694 public static Serializable serialize(final Log4jLogEvent event, final boolean includeLocation) {
695 event.getThrownProxy();
696 return new LogEventProxy(event, includeLocation);
697 }
698
699 public static boolean canDeserialize(final Serializable event) {
700 return event instanceof LogEventProxy;
701 }
702
703 public static Log4jLogEvent deserialize(final Serializable event) {
704 Objects.requireNonNull(event, "Event cannot be null");
705 if (event instanceof LogEventProxy) {
706 final LogEventProxy proxy = (LogEventProxy) event;
707 final Log4jLogEvent result = new Log4jLogEvent(proxy.loggerName, proxy.marker,
708 proxy.loggerFQCN, proxy.level, proxy.message,
709 proxy.thrown, proxy.thrownProxy, proxy.contextData, proxy.contextStack, proxy.threadId,
710 proxy.threadName, proxy.threadPriority, proxy.source, proxy.timeMillis, proxy.nanoTime);
711 result.setEndOfBatch(proxy.isEndOfBatch);
712 result.setIncludeLocation(proxy.isLocationRequired);
713 return result;
714 }
715 throw new IllegalArgumentException("Event is not a serialized LogEvent: " + event.toString());
716 }
717
718 private void readObject(final ObjectInputStream stream) throws InvalidObjectException {
719 throw new InvalidObjectException("Proxy required");
720 }
721
722 public static LogEvent createMemento(final LogEvent logEvent) {
723 return new Log4jLogEvent.Builder(logEvent).build();
724 }
725
726
727
728
729
730
731 public static Log4jLogEvent createMemento(final LogEvent event, final boolean includeLocation) {
732 return deserialize(serialize(event, includeLocation));
733 }
734
735 @Override
736 public String toString() {
737 final StringBuilder sb = new StringBuilder();
738 final String n = loggerName.isEmpty() ? LoggerConfig.ROOT : loggerName;
739 sb.append("Logger=").append(n);
740 sb.append(" Level=").append(level.name());
741 sb.append(" Message=").append(message == null ? null : message.getFormattedMessage());
742 return sb.toString();
743 }
744
745 @Override
746 public boolean equals(final Object o) {
747 if (this == o) {
748 return true;
749 }
750 if (o == null || getClass() != o.getClass()) {
751 return false;
752 }
753
754 final Log4jLogEvent that = (Log4jLogEvent) o;
755
756 if (endOfBatch != that.endOfBatch) {
757 return false;
758 }
759 if (includeLocation != that.includeLocation) {
760 return false;
761 }
762 if (timeMillis != that.timeMillis) {
763 return false;
764 }
765 if (nanoTime != that.nanoTime) {
766 return false;
767 }
768 if (loggerFqcn != null ? !loggerFqcn.equals(that.loggerFqcn) : that.loggerFqcn != null) {
769 return false;
770 }
771 if (level != null ? !level.equals(that.level) : that.level != null) {
772 return false;
773 }
774 if (source != null ? !source.equals(that.source) : that.source != null) {
775 return false;
776 }
777 if (marker != null ? !marker.equals(that.marker) : that.marker != null) {
778 return false;
779 }
780 if (contextData != null ? !contextData.equals(that.contextData) : that.contextData != null) {
781 return false;
782 }
783 if (!message.equals(that.message)) {
784 return false;
785 }
786 if (!loggerName.equals(that.loggerName)) {
787 return false;
788 }
789 if (contextStack != null ? !contextStack.equals(that.contextStack) : that.contextStack != null) {
790 return false;
791 }
792 if (threadId != that.threadId) {
793 return false;
794 }
795 if (threadName != null ? !threadName.equals(that.threadName) : that.threadName != null) {
796 return false;
797 }
798 if (threadPriority != that.threadPriority) {
799 return false;
800 }
801 if (thrown != null ? !thrown.equals(that.thrown) : that.thrown != null) {
802 return false;
803 }
804 if (thrownProxy != null ? !thrownProxy.equals(that.thrownProxy) : that.thrownProxy != null) {
805 return false;
806 }
807
808 return true;
809 }
810
811 @Override
812 public int hashCode() {
813
814 int result = loggerFqcn != null ? loggerFqcn.hashCode() : 0;
815 result = 31 * result + (marker != null ? marker.hashCode() : 0);
816 result = 31 * result + (level != null ? level.hashCode() : 0);
817 result = 31 * result + loggerName.hashCode();
818 result = 31 * result + message.hashCode();
819 result = 31 * result + (int) (timeMillis ^ (timeMillis >>> 32));
820 result = 31 * result + (int) (nanoTime ^ (nanoTime >>> 32));
821 result = 31 * result + (thrown != null ? thrown.hashCode() : 0);
822 result = 31 * result + (thrownProxy != null ? thrownProxy.hashCode() : 0);
823 result = 31 * result + (contextData != null ? contextData.hashCode() : 0);
824 result = 31 * result + (contextStack != null ? contextStack.hashCode() : 0);
825 result = 31 * result + (int) (threadId ^ (threadId >>> 32));
826 result = 31 * result + (threadName != null ? threadName.hashCode() : 0);
827 result = 31 * result + (threadPriority ^ (threadPriority >>> 32));
828 result = 31 * result + (source != null ? source.hashCode() : 0);
829 result = 31 * result + (includeLocation ? 1 : 0);
830 result = 31 * result + (endOfBatch ? 1 : 0);
831
832 return result;
833 }
834
835
836
837
838 static class LogEventProxy implements Serializable {
839
840 private static final long serialVersionUID = -8634075037355293699L;
841 private final String loggerFQCN;
842 private final Marker marker;
843 private final Level level;
844 private final String loggerName;
845
846 private final transient Message message;
847
848 private MarshalledObject<Message> marshalledMessage;
849
850 private String messageString;
851 private final long timeMillis;
852 private final transient Throwable thrown;
853 private final ThrowableProxy thrownProxy;
854
855 private final StringMap contextData;
856 private final ThreadContext.ContextStack contextStack;
857
858 private final long threadId;
859 private final String threadName;
860
861 private final int threadPriority;
862 private final StackTraceElement source;
863 private final boolean isLocationRequired;
864 private final boolean isEndOfBatch;
865
866 private final transient long nanoTime;
867
868 public LogEventProxy(final Log4jLogEvent event, final boolean includeLocation) {
869 this.loggerFQCN = event.loggerFqcn;
870 this.marker = event.marker;
871 this.level = event.level;
872 this.loggerName = event.loggerName;
873 this.message = event.message instanceof ReusableMessage
874 ? memento((ReusableMessage) event.message)
875 : event.message;
876 this.timeMillis = event.timeMillis;
877 this.thrown = event.thrown;
878 this.thrownProxy = event.thrownProxy;
879 this.contextData = event.contextData;
880 this.contextStack = event.contextStack;
881 this.source = includeLocation ? event.getSource() : null;
882 this.threadId = event.getThreadId();
883 this.threadName = event.getThreadName();
884 this.threadPriority = event.getThreadPriority();
885 this.isLocationRequired = includeLocation;
886 this.isEndOfBatch = event.endOfBatch;
887 this.nanoTime = event.nanoTime;
888 }
889
890 public LogEventProxy(final LogEvent event, final boolean includeLocation) {
891 this.loggerFQCN = event.getLoggerFqcn();
892 this.marker = event.getMarker();
893 this.level = event.getLevel();
894 this.loggerName = event.getLoggerName();
895
896 final Message temp = event.getMessage();
897 message = temp instanceof ReusableMessage
898 ? memento((ReusableMessage) temp)
899 : temp;
900 this.timeMillis = event.getTimeMillis();
901 this.thrown = event.getThrown();
902 this.thrownProxy = event.getThrownProxy();
903 this.contextData = memento(event.getContextData());
904 this.contextStack = event.getContextStack();
905 this.source = includeLocation ? event.getSource() : null;
906 this.threadId = event.getThreadId();
907 this.threadName = event.getThreadName();
908 this.threadPriority = event.getThreadPriority();
909 this.isLocationRequired = includeLocation;
910 this.isEndOfBatch = event.isEndOfBatch();
911 this.nanoTime = event.getNanoTime();
912 }
913
914 private static Message memento(final ReusableMessage message) {
915 return message.memento();
916 }
917
918 private static StringMap memento(final ReadOnlyStringMap data) {
919 final StringMap result = ContextDataFactory.createContextData();
920 result.putAll(data);
921 return result;
922 }
923
924 private static MarshalledObject<Message> marshall(final Message msg) {
925 try {
926 return new MarshalledObject<>(msg);
927 } catch (final Exception ex) {
928 return null;
929 }
930 }
931
932 private void writeObject(final java.io.ObjectOutputStream s) throws IOException {
933 this.messageString = message.getFormattedMessage();
934 this.marshalledMessage = marshall(message);
935 s.defaultWriteObject();
936 }
937
938
939
940
941
942 protected Object readResolve() {
943 final Log4jLogEvent result = new Log4jLogEvent(loggerName, marker, loggerFQCN, level, message(), thrown,
944 thrownProxy, contextData, contextStack, threadId, threadName, threadPriority, source, timeMillis,
945 nanoTime);
946 result.setEndOfBatch(isEndOfBatch);
947 result.setIncludeLocation(isLocationRequired);
948 return result;
949 }
950
951 private Message message() {
952 if (marshalledMessage != null) {
953 try {
954 return marshalledMessage.get();
955 } catch (final Exception ex) {
956 }
957 }
958 return new SimpleMessage(messageString);
959 }
960 }
961
962 }