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.util.StringMap;
32
33
34
35
36
37 public class ReusableLogEventFactory implements LogEventFactory, LocationAwareLogEventFactory {
38 private static final ThreadNameCachingStrategy THREAD_NAME_CACHING_STRATEGY = ThreadNameCachingStrategy.create();
39 private static final Clock CLOCK = ClockFactory.getClock();
40
41 private static ThreadLocal<MutableLogEvent> mutableLogEventThreadLocal = new ThreadLocal<>();
42 private final ContextDataInjector injector = ContextDataInjectorFactory.createInjector();
43
44
45
46
47
48
49
50
51
52
53
54
55
56 @Override
57 public LogEvent createEvent(final String loggerName, final Marker marker,
58 final String fqcn, final Level level, final Message message,
59 final List<Property> properties, final Throwable t) {
60 return createEvent(loggerName, marker, fqcn, null, level, message, properties, t);
61 }
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76 @Override
77 public LogEvent createEvent(final String loggerName, final Marker marker, final String fqcn,
78 final StackTraceElement location, final Level level, final Message message,
79 final List<Property> properties, final Throwable t) {
80 MutableLogEvent result = mutableLogEventThreadLocal.get();
81 if (result == null || result.reserved) {
82 final boolean initThreadLocal = result == null;
83 result = new MutableLogEvent();
84
85
86 result.setThreadId(Thread.currentThread().getId());
87 result.setThreadName(Thread.currentThread().getName());
88 result.setThreadPriority(Thread.currentThread().getPriority());
89 if (initThreadLocal) {
90 mutableLogEventThreadLocal.set(result);
91 }
92 }
93 result.reserved = true;
94 result.clear();
95
96 result.setLoggerName(loggerName);
97 result.setMarker(marker);
98 result.setLoggerFqcn(fqcn);
99 result.setLevel(level == null ? Level.OFF : level);
100 result.setMessage(message);
101 result.initTime(CLOCK, Log4jLogEvent.getNanoClock());
102 result.setThrown(t);
103 result.setSource(location);
104 result.setContextData(injector.injectContextData(properties, (StringMap) result.getContextData()));
105 result.setContextStack(ThreadContext.getDepth() == 0 ? ThreadContext.EMPTY_STACK : ThreadContext.cloneStack());
106
107 if (THREAD_NAME_CACHING_STRATEGY == ThreadNameCachingStrategy.UNCACHED) {
108 result.setThreadName(Thread.currentThread().getName());
109 result.setThreadPriority(Thread.currentThread().getPriority());
110 }
111 return result;
112 }
113
114
115
116
117
118
119
120 public static void release(final LogEvent logEvent) {
121 if (logEvent instanceof MutableLogEvent) {
122 final MutableLogEvent mutableLogEvent = (MutableLogEvent) logEvent;
123 mutableLogEvent.clear();
124 mutableLogEvent.reserved = false;
125 }
126 }
127 }