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