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 org.apache.logging.log4j.Level;
20 import org.apache.logging.log4j.ThreadContext;
21 import org.apache.logging.log4j.Marker;
22 import org.apache.logging.log4j.core.LogEvent;
23 import org.apache.logging.log4j.message.LoggerNameAwareMessage;
24 import org.apache.logging.log4j.message.Message;
25 import org.apache.logging.log4j.message.TimestampMessage;
26
27 import java.io.InvalidObjectException;
28 import java.io.ObjectInputStream;
29 import java.io.Serializable;
30 import java.util.HashMap;
31 import java.util.Map;
32 import java.util.Stack;
33
34
35
36
37 public class Log4jLogEvent implements LogEvent, Serializable {
38
39 private static final long serialVersionUID = -1351367343806656055L;
40 private static final String NOT_AVAIL = "?";
41 private final String fqcnOfLogger;
42 private final Marker marker;
43 private final Level level;
44 private final String name;
45 private final Message message;
46 private final long timestamp;
47 private final ThrowableProxy throwable;
48 private final Map<String, String> mdc;
49 private final Stack<String> ndc;
50 private String threadName = null;
51 private StackTraceElement location;
52
53
54
55
56
57
58
59
60
61
62 public Log4jLogEvent(String loggerName, Marker marker, String fqcn, Level level, Message message, Throwable t) {
63 this(loggerName, marker, fqcn, level, message, t, ThreadContext.getContext(), ThreadContext.cloneStack(), null,
64 null, System.currentTimeMillis());
65 }
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 public Log4jLogEvent(String loggerName, Marker marker, String fqcn, Level level, Message message, Throwable t,
82 Map<String, String> mdc, Stack<String> ndc, String threadName, StackTraceElement location,
83 long timestamp) {
84 name = loggerName;
85 this.marker = marker;
86 this.fqcnOfLogger = fqcn;
87 this.level = level;
88 this.message = message;
89 this.throwable = t == null ? null : new ThrowableProxy(t);
90 this.mdc = mdc;
91 this.ndc = ndc;
92 this.timestamp = message instanceof TimestampMessage ? ((TimestampMessage) message).getTimestamp() : timestamp;
93 this.threadName = threadName;
94 this.location = location;
95 if (message != null && message instanceof LoggerNameAwareMessage) {
96 ((LoggerNameAwareMessage) message).setLoggerName(name);
97 }
98 }
99
100
101
102
103
104 public Level getLevel() {
105 return level;
106 }
107
108
109
110
111
112 public String getLoggerName() {
113 return name;
114 }
115
116
117
118
119
120 public Message getMessage() {
121 return message;
122 }
123
124
125
126
127
128 public String getThreadName() {
129 if (threadName == null) {
130 threadName = Thread.currentThread().getName();
131 }
132 return threadName;
133 }
134
135
136
137
138
139 public long getMillis() {
140 return timestamp;
141 }
142
143
144
145
146
147 public Throwable getThrown() {
148 return throwable;
149 }
150
151
152
153
154
155 public Marker getMarker() {
156 return marker;
157 }
158
159
160
161
162
163 public String getFQCN() {
164 return fqcnOfLogger;
165 }
166
167
168
169
170
171
172 public Map<String, String> getContextMap() {
173 return mdc;
174 }
175
176
177
178
179
180
181 public Stack<String> getContextStack() {
182 return ndc;
183 }
184
185
186
187
188
189
190 public StackTraceElement getSource() {
191 if (fqcnOfLogger == null) {
192 return null;
193 }
194 if (location == null) {
195 StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
196 boolean next = false;
197 for (StackTraceElement element : stackTrace) {
198 String className = element.getClassName();
199 if (next) {
200 if (fqcnOfLogger.equals(className)) {
201 continue;
202 }
203 location = element;
204 break;
205 }
206
207 if (fqcnOfLogger.equals(className)) {
208 next = true;
209 } else if (NOT_AVAIL.equals(className)) {
210 break;
211 }
212 }
213 }
214
215 return location;
216 }
217
218
219
220
221
222 protected Object writeReplace() {
223 return new LogEventProxy(this);
224 }
225
226 private void readObject(ObjectInputStream stream) throws InvalidObjectException {
227 throw new InvalidObjectException("Proxy required");
228 }
229
230 @Override
231 public String toString() {
232 StringBuilder sb = new StringBuilder();
233 String n = name.length() == 0 ? "root" : name;
234 sb.append("Logger=").append(n);
235 sb.append(" Level=").append(level.name());
236 sb.append(" Message").append(message.getFormattedMessage());
237 return sb.toString();
238 }
239
240
241
242
243 private static class LogEventProxy implements Serializable {
244
245 private static final long serialVersionUID = -7139032940312647146L;
246 private final String fqcnOfLogger;
247 private final Marker marker;
248 private final Level level;
249 private final String name;
250 private final Message message;
251 private final long timestamp;
252 private final Throwable throwable;
253 private final HashMap<String, String> mdc;
254 private final Stack<String> ndc;
255 private String threadName;
256 private StackTraceElement location;
257
258 public LogEventProxy(Log4jLogEvent event) {
259 this.fqcnOfLogger = event.fqcnOfLogger;
260 this.marker = event.marker;
261 this.level = event.level;
262 this.name = event.name;
263 this.message = event.message;
264 this.timestamp = event.timestamp;
265 this.throwable = event.throwable;
266 this.mdc = new HashMap<String, String>(event.mdc);
267 this.ndc = event.ndc;
268 this.location = event.getSource();
269 this.threadName = event.getThreadName();
270 }
271
272
273
274
275
276 protected Object readResolve() {
277 return new Log4jLogEvent(name, marker, fqcnOfLogger, level, message, throwable, mdc, ndc, threadName,
278 location, timestamp);
279 }
280
281 }
282
283 }