1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.classic.spi;
15
16 import java.io.IOException;
17 import java.io.ObjectOutputStream;
18 import java.time.Clock;
19 import java.time.Instant;
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.List;
23 import java.util.Map;
24
25 import org.slf4j.MDC;
26 import org.slf4j.Marker;
27 import org.slf4j.event.KeyValuePair;
28 import org.slf4j.helpers.MessageFormatter;
29 import org.slf4j.spi.MDCAdapter;
30
31 import ch.qos.logback.classic.Level;
32 import ch.qos.logback.classic.Logger;
33 import ch.qos.logback.classic.LoggerContext;
34 import ch.qos.logback.classic.util.LogbackMDCAdapter;
35 import ch.qos.logback.core.spi.SequenceNumberGenerator;
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public class LoggingEvent implements ILoggingEvent {
54
55
56
57
58
59
60
61
62 transient String fqnOfLoggerClass;
63
64
65
66
67 private String threadName;
68
69 private String loggerName;
70 private LoggerContext loggerContext;
71 private LoggerContextVO loggerContextVO;
72
73
74
75
76
77
78
79
80
81 private transient Level level;
82
83 private String message;
84
85
86
87
88 transient String formattedMessage;
89
90 private transient Object[] argumentArray;
91
92 private ThrowableProxy throwableProxy;
93
94 private StackTraceElement[] callerDataArray;
95
96 private List<Marker> markerList;
97
98 private Map<String, String> mdcPropertyMap;
99
100
101
102
103 List<KeyValuePair> keyValuePairs;
104
105
106
107
108
109 private Instant instant;
110
111 private long timeStamp;
112 private int nanoseconds;
113
114 private long sequenceNumber;
115
116 public LoggingEvent() {
117 }
118
119 public LoggingEvent(String fqcn, Logger logger, Level level, String message, Throwable throwable,
120 Object[] argArray) {
121 this.fqnOfLoggerClass = fqcn;
122 this.loggerName = logger.getName();
123 this.loggerContext = logger.getLoggerContext();
124 this.loggerContextVO = loggerContext.getLoggerContextRemoteView();
125 this.level = level;
126
127 this.message = message;
128 this.argumentArray = argArray;
129
130 Instant instant = Clock.systemUTC().instant();
131 initTmestampFields(instant);
132
133 if (loggerContext != null) {
134 SequenceNumberGenerator sequenceNumberGenerator = loggerContext.getSequenceNumberGenerator();
135 if (sequenceNumberGenerator != null)
136 sequenceNumber = sequenceNumberGenerator.nextSequenceNumber();
137 }
138
139 if (throwable == null) {
140 throwable = extractThrowableAnRearrangeArguments(argArray);
141 }
142
143 if (throwable != null) {
144 this.throwableProxy = new ThrowableProxy(throwable);
145
146 if (loggerContext != null && loggerContext.isPackagingDataEnabled()) {
147 this.throwableProxy.calculatePackagingData();
148 }
149 }
150 }
151
152 void initTmestampFields(Instant instant) {
153 this.instant = instant;
154 long epochSecond = instant.getEpochSecond();
155 this.nanoseconds = instant.getNano();
156 long milliseconds = nanoseconds / 1000_000;
157 this.timeStamp = (epochSecond * 1000) + (milliseconds);
158 }
159
160 private Throwable extractThrowableAnRearrangeArguments(Object[] argArray) {
161 Throwable extractedThrowable = EventArgUtil.extractThrowable(argArray);
162 if (EventArgUtil.successfulExtraction(extractedThrowable)) {
163 this.argumentArray = EventArgUtil.trimmedCopy(argArray);
164 }
165 return extractedThrowable;
166 }
167
168 public void setArgumentArray(Object[] argArray) {
169 if (this.argumentArray != null) {
170 throw new IllegalStateException("argArray has been already set");
171 }
172 this.argumentArray = argArray;
173 }
174
175 public Object[] getArgumentArray() {
176 return this.argumentArray;
177 }
178
179 public void addKeyValuePair(KeyValuePair kvp) {
180 if (keyValuePairs == null) {
181 keyValuePairs = new ArrayList<>(4);
182 }
183 keyValuePairs.add(kvp);
184 }
185
186 public void setKeyValuePairs(List<KeyValuePair> kvpList) {
187 this.keyValuePairs = kvpList;
188 }
189
190 @Override
191 public List<KeyValuePair> getKeyValuePairs() {
192 return this.keyValuePairs;
193 }
194
195 public Level getLevel() {
196 return level;
197 }
198
199 public String getLoggerName() {
200 return loggerName;
201 }
202
203 public void setLoggerName(String loggerName) {
204 this.loggerName = loggerName;
205 }
206
207 public String getThreadName() {
208 if (threadName == null) {
209 threadName = (Thread.currentThread()).getName();
210 }
211 return threadName;
212 }
213
214
215
216
217
218 public void setThreadName(String threadName) throws IllegalStateException {
219 if (this.threadName != null) {
220 throw new IllegalStateException("threadName has been already set");
221 }
222 this.threadName = threadName;
223 }
224
225
226
227
228
229 public IThrowableProxy getThrowableProxy() {
230 return throwableProxy;
231 }
232
233
234
235
236 public void setThrowableProxy(ThrowableProxy tp) {
237 if (throwableProxy != null) {
238 throw new IllegalStateException("ThrowableProxy has been already set.");
239 } else {
240 throwableProxy = tp;
241 }
242 }
243
244
245
246
247
248
249
250
251
252 public void prepareForDeferredProcessing() {
253 this.getFormattedMessage();
254 this.getThreadName();
255
256 this.getMDCPropertyMap();
257 }
258
259 public void setLoggerContext(LoggerContext lc) {
260 this.loggerContext = lc;
261 }
262
263 public LoggerContextVO getLoggerContextVO() {
264 return loggerContextVO;
265 }
266
267 public void setLoggerContextRemoteView(LoggerContextVO loggerContextVO) {
268 this.loggerContextVO = loggerContextVO;
269 }
270
271 public String getMessage() {
272 return message;
273 }
274
275 public void setMessage(String message) {
276 if (this.message != null) {
277 throw new IllegalStateException("The message for this event has been set already.");
278 }
279 this.message = message;
280 }
281
282
283
284
285
286
287
288 public Instant getInstant() {
289 return instant;
290 }
291
292
293
294
295
296
297 public void setInstant(Instant instant) {
298 initTmestampFields(instant);
299 }
300
301
302
303
304 public long getTimeStamp() {
305 return timeStamp;
306 }
307
308
309
310
311
312
313 @Override
314 public int getNanoseconds() {
315 return nanoseconds;
316 }
317
318
319
320
321
322
323
324
325
326 public void setTimeStamp(long timeStamp) {
327 Instant instant = Instant.ofEpochMilli(timeStamp);
328 setInstant(instant);
329 }
330
331 @Override
332 public long getSequenceNumber() {
333 return sequenceNumber;
334 }
335
336 public void setSquenceNumber(long sn) {
337 sequenceNumber = sn;
338 }
339
340 public void setLevel(Level level) {
341 if (this.level != null) {
342 throw new IllegalStateException("The level has been already set for this event.");
343 }
344 this.level = level;
345 }
346
347
348
349
350
351
352
353
354
355
356
357 public StackTraceElement[] getCallerData() {
358 if (callerDataArray == null) {
359 callerDataArray = CallerData.extract(new Throwable(), fqnOfLoggerClass,
360 loggerContext.getMaxCallerDataDepth(), loggerContext.getFrameworkPackages());
361 }
362 return callerDataArray;
363 }
364
365 public boolean hasCallerData() {
366 return (callerDataArray != null);
367 }
368
369 public void setCallerData(StackTraceElement[] callerDataArray) {
370 this.callerDataArray = callerDataArray;
371 }
372
373 public List<Marker> getMarkerList() {
374 return markerList;
375 }
376
377 public void addMarker(Marker marker) {
378 if (marker == null) {
379 return;
380 }
381 if (markerList == null) {
382 markerList = new ArrayList<>(4);
383 }
384 markerList.add(marker);
385 }
386
387 public long getContextBirthTime() {
388 return loggerContextVO.getBirthTime();
389 }
390
391
392 public String getFormattedMessage() {
393 if (formattedMessage != null) {
394 return formattedMessage;
395 }
396 if (argumentArray != null) {
397 formattedMessage = MessageFormatter.arrayFormat(message, argumentArray).getMessage();
398 } else {
399 formattedMessage = message;
400 }
401
402 return formattedMessage;
403 }
404
405 public Map<String, String> getMDCPropertyMap() {
406
407 if (mdcPropertyMap == null) {
408 MDCAdapter mdc = MDC.getMDCAdapter();
409 if (mdc instanceof LogbackMDCAdapter)
410 mdcPropertyMap = ((LogbackMDCAdapter) mdc).getPropertyMap();
411 else
412 mdcPropertyMap = mdc.getCopyOfContextMap();
413 }
414
415 if (mdcPropertyMap == null)
416 mdcPropertyMap = Collections.emptyMap();
417
418 return mdcPropertyMap;
419 }
420
421
422
423
424
425
426
427 public void setMDCPropertyMap(Map<String, String> map) {
428 if (mdcPropertyMap != null) {
429 throw new IllegalStateException("The MDCPropertyMap has been already set for this event.");
430 }
431 this.mdcPropertyMap = map;
432
433 }
434
435
436
437
438
439
440 public Map<String, String> getMdc() {
441 return getMDCPropertyMap();
442 }
443
444 @Override
445 public String toString() {
446 StringBuilder sb = new StringBuilder();
447 sb.append('[');
448 sb.append(level).append("] ");
449 sb.append(getFormattedMessage());
450 return sb.toString();
451 }
452
453
454
455
456
457
458
459
460 private void writeObject(ObjectOutputStream out) throws IOException {
461 throw new UnsupportedOperationException(this.getClass() + " does not support serialization. "
462 + "Use LoggerEventVO instance instead. See also LoggerEventVO.build method.");
463 }
464
465 }