1
14 package ch.qos.logback.classic.spi;
15
16 import java.io.IOException;
17 import java.io.ObjectOutputStream;
18 import java.util.Collections;
19 import java.util.Map;
20
21 import org.slf4j.MDC;
22 import org.slf4j.Marker;
23 import org.slf4j.helpers.MessageFormatter;
24
25 import ch.qos.logback.classic.Level;
26 import ch.qos.logback.classic.Logger;
27 import ch.qos.logback.classic.LoggerContext;
28 import ch.qos.logback.classic.util.LogbackMDCAdapter;
29
30 import org.slf4j.spi.MDCAdapter;
31
32
48 public class LoggingEvent implements ILoggingEvent {
49
50
57 transient String fqnOfLoggerClass;
58
59
62 private String threadName;
63
64 private String loggerName;
65 private LoggerContext loggerContext;
66 private LoggerContextVO loggerContextVO;
67
68
76 private transient Level level;
77
78 private String message;
79
80
81
82
83 transient String formattedMessage;
84
85 private transient Object[] argumentArray;
86
87 private ThrowableProxy throwableProxy;
88
89 private StackTraceElement[] callerDataArray;
90
91 private Marker marker;
92
93 private Map<String, String> mdcPropertyMap;
94
95
99 private long timeStamp;
100
101 public LoggingEvent() {
102 }
103
104 public LoggingEvent(String fqcn, Logger logger, Level level, String message, Throwable throwable, Object[] argArray) {
105 this.fqnOfLoggerClass = fqcn;
106 this.loggerName = logger.getName();
107 this.loggerContext = logger.getLoggerContext();
108 this.loggerContextVO = loggerContext.getLoggerContextRemoteView();
109 this.level = level;
110
111 this.message = message;
112 this.argumentArray = argArray;
113
114 if (throwable == null) {
115 throwable = extractThrowableAnRearrangeArguments(argArray);
116 }
117
118 if (throwable != null) {
119 this.throwableProxy = new ThrowableProxy(throwable);
120 LoggerContext lc = logger.getLoggerContext();
121 if (lc.isPackagingDataEnabled()) {
122 this.throwableProxy.calculatePackagingData();
123 }
124 }
125
126 timeStamp = System.currentTimeMillis();
127 }
128
129 private Throwable extractThrowableAnRearrangeArguments(Object[] argArray) {
130 Throwable extractedThrowable = EventArgUtil.extractThrowable(argArray);
131 if (EventArgUtil.successfulExtraction(extractedThrowable)) {
132 this.argumentArray = EventArgUtil.trimmedCopy(argArray);
133 }
134 return extractedThrowable;
135 }
136
137 public void setArgumentArray(Object[] argArray) {
138 if (this.argumentArray != null) {
139 throw new IllegalStateException("argArray has been already set");
140 }
141 this.argumentArray = argArray;
142 }
143
144 public Object[] getArgumentArray() {
145 return this.argumentArray;
146 }
147
148 public Level getLevel() {
149 return level;
150 }
151
152 public String getLoggerName() {
153 return loggerName;
154 }
155
156 public void setLoggerName(String loggerName) {
157 this.loggerName = loggerName;
158 }
159
160 public String getThreadName() {
161 if (threadName == null) {
162 threadName = (Thread.currentThread()).getName();
163 }
164 return threadName;
165 }
166
167
171 public void setThreadName(String threadName) throws IllegalStateException {
172 if (this.threadName != null) {
173 throw new IllegalStateException("threadName has been already set");
174 }
175 this.threadName = threadName;
176 }
177
178
182 public IThrowableProxy getThrowableProxy() {
183 return throwableProxy;
184 }
185
186
189 public void setThrowableProxy(ThrowableProxy tp) {
190 if (throwableProxy != null) {
191 throw new IllegalStateException("ThrowableProxy has been already set.");
192 } else {
193 throwableProxy = tp;
194 }
195 }
196
197
205 public void prepareForDeferredProcessing() {
206 this.getFormattedMessage();
207 this.getThreadName();
208
209 this.getMDCPropertyMap();
210 }
211
212 public LoggerContextVO getLoggerContextVO() {
213 return loggerContextVO;
214 }
215
216 public void setLoggerContextRemoteView(LoggerContextVO loggerContextVO) {
217 this.loggerContextVO = loggerContextVO;
218 }
219
220 public String getMessage() {
221 return message;
222 }
223
224 public void setMessage(String message) {
225 if (this.message != null) {
226 throw new IllegalStateException("The message for this event has been set already.");
227 }
228 this.message = message;
229 }
230
231 public long getTimeStamp() {
232 return timeStamp;
233 }
234
235 public void setTimeStamp(long timeStamp) {
236 this.timeStamp = timeStamp;
237 }
238
239 public void setLevel(Level level) {
240 if (this.level != null) {
241 throw new IllegalStateException("The level has been already set for this event.");
242 }
243 this.level = level;
244 }
245
246
256 public StackTraceElement[] getCallerData() {
257 if (callerDataArray == null) {
258 callerDataArray = CallerData
259 .extract(new Throwable(), fqnOfLoggerClass, loggerContext.getMaxCallerDataDepth(), loggerContext.getFrameworkPackages());
260 }
261 return callerDataArray;
262 }
263
264 public boolean hasCallerData() {
265 return (callerDataArray != null);
266 }
267
268 public void setCallerData(StackTraceElement[] callerDataArray) {
269 this.callerDataArray = callerDataArray;
270 }
271
272 public Marker getMarker() {
273 return marker;
274 }
275
276 public void setMarker(Marker marker) {
277 if (this.marker != null) {
278 throw new IllegalStateException("The marker has been already set for this event.");
279 }
280 this.marker = marker;
281 }
282
283 public long getContextBirthTime() {
284 return loggerContextVO.getBirthTime();
285 }
286
287
288 public String getFormattedMessage() {
289 if (formattedMessage != null) {
290 return formattedMessage;
291 }
292 if (argumentArray != null) {
293 formattedMessage = MessageFormatter.arrayFormat(message, argumentArray).getMessage();
294 } else {
295 formattedMessage = message;
296 }
297
298 return formattedMessage;
299 }
300
301 public Map<String, String> getMDCPropertyMap() {
302
303 if (mdcPropertyMap == null) {
304 MDCAdapter mdc = MDC.getMDCAdapter();
305 if (mdc instanceof LogbackMDCAdapter)
306 mdcPropertyMap = ((LogbackMDCAdapter) mdc).getPropertyMap();
307 else
308 mdcPropertyMap = mdc.getCopyOfContextMap();
309 }
310
311 if (mdcPropertyMap == null)
312 mdcPropertyMap = Collections.emptyMap();
313
314 return mdcPropertyMap;
315 }
316
317
323 public void setMDCPropertyMap(Map<String, String> map) {
324 if (mdcPropertyMap != null) {
325 throw new IllegalStateException("The MDCPropertyMap has been already set for this event.");
326 }
327 this.mdcPropertyMap = map;
328
329 }
330
331
336 public Map<String, String> getMdc() {
337 return getMDCPropertyMap();
338 }
339
340 @Override
341 public String toString() {
342 StringBuilder sb = new StringBuilder();
343 sb.append('[');
344 sb.append(level).append("] ");
345 sb.append(getFormattedMessage());
346 return sb.toString();
347 }
348
349
355 private void writeObject(ObjectOutputStream out) throws IOException {
356 throw new UnsupportedOperationException(this.getClass() + " does not support serialization. "
357 + "Use LoggerEventVO instance instead. See also LoggerEventVO.build method.");
358 }
359
360 }
361