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.util.List;
20
21 import org.apache.logging.log4j.Level;
22 import org.apache.logging.log4j.Marker;
23 import org.apache.logging.log4j.ThreadContext;
24 import org.apache.logging.log4j.core.ContextDataInjector;
25 import org.apache.logging.log4j.core.LogEvent;
26 import org.apache.logging.log4j.core.async.ThreadNameCachingStrategy;
27 import org.apache.logging.log4j.core.config.Property;
28 import org.apache.logging.log4j.core.util.Clock;
29 import org.apache.logging.log4j.core.util.ClockFactory;
30 import org.apache.logging.log4j.message.Message;
31 import org.apache.logging.log4j.message.TimestampMessage;
32 import org.apache.logging.log4j.util.StringMap;
33
34
35
36
37
38 public class ReusableLogEventFactory implements LogEventFactory {
39 private static final ThreadNameCachingStrategy THREAD_NAME_CACHING_STRATEGY = ThreadNameCachingStrategy.create();
40 private static final Clock CLOCK = ClockFactory.getClock();
41
42 private static ThreadLocal<MutableLogEvent> mutableLogEventThreadLocal = new ThreadLocal<>();
43 private final ContextDataInjector injector = ContextDataInjectorFactory.createInjector();
44
45
46
47
48
49
50
51
52
53
54
55
56
57 @Override
58 public LogEvent createEvent(final String loggerName, final Marker marker,
59 final String fqcn, final Level level, final Message message,
60 final List<Property> properties, final Throwable t) {
61 MutableLogEvent result = mutableLogEventThreadLocal.get();
62 if (result == null || result.reserved) {
63 final boolean initThreadLocal = result == null;
64 result = new MutableLogEvent();
65
66
67 result.setThreadId(Thread.currentThread().getId());
68 result.setThreadName(Thread.currentThread().getName());
69 result.setThreadPriority(Thread.currentThread().getPriority());
70 if (initThreadLocal) {
71 mutableLogEventThreadLocal.set(result);
72 }
73 }
74 result.reserved = true;
75 result.clear();
76
77 result.setLoggerName(loggerName);
78 result.setMarker(marker);
79 result.setLoggerFqcn(fqcn);
80 result.setLevel(level == null ? Level.OFF : level);
81 result.setMessage(message);
82 result.setThrown(t);
83 result.setContextData(injector.injectContextData(properties, (StringMap) result.getContextData()));
84 result.setContextStack(ThreadContext.getDepth() == 0 ? ThreadContext.EMPTY_STACK : ThreadContext.cloneStack());
85 result.setTimeMillis(message instanceof TimestampMessage
86 ? ((TimestampMessage) message).getTimestamp()
87 : CLOCK.currentTimeMillis());
88 result.setNanoTime(Log4jLogEvent.getNanoClock().nanoTime());
89
90 if (THREAD_NAME_CACHING_STRATEGY == ThreadNameCachingStrategy.UNCACHED) {
91 result.setThreadName(Thread.currentThread().getName());
92 result.setThreadPriority(Thread.currentThread().getPriority());
93 }
94 return result;
95 }
96
97
98
99
100
101
102
103 public static void release(final LogEvent logEvent) {
104 if (logEvent instanceof MutableLogEvent) {
105 ((MutableLogEvent) logEvent).reserved = false;
106 }
107 }
108 }