1 package uk.org.lidalia.slf4jtest;
2
3 import java.io.PrintStream;
4 import java.util.Collections;
5 import java.util.Map;
6
7 import org.joda.time.Instant;
8 import org.slf4j.Marker;
9 import org.slf4j.helpers.MessageFormatter;
10
11 import com.google.common.base.Function;
12 import com.google.common.base.Optional;
13 import com.google.common.collect.ImmutableList;
14 import com.google.common.collect.ImmutableMap;
15
16 import uk.org.lidalia.lang.Identity;
17 import uk.org.lidalia.lang.RichObject;
18 import uk.org.lidalia.slf4jext.Level;
19
20 import static com.google.common.base.Optional.absent;
21 import static com.google.common.base.Optional.fromNullable;
22 import static com.google.common.base.Preconditions.checkNotNull;
23 import static com.google.common.collect.FluentIterable.from;
24 import static java.util.Arrays.asList;
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 @SuppressWarnings({ "PMD.ExcessivePublicCount", "PMD.TooManyMethods" })
46 public class LoggingEvent extends RichObject {
47
48 public static LoggingEvent trace(final String message, final Object... arguments) {
49 return new LoggingEvent(Level.TRACE, message, arguments);
50 }
51
52 public static LoggingEvent trace(final Throwable throwable, final String message, final Object... arguments) {
53 return new LoggingEvent(Level.TRACE, throwable, message, arguments);
54 }
55
56 public static LoggingEvent trace(final Marker marker, final String message, final Object... arguments) {
57 return new LoggingEvent(Level.TRACE, marker, message, arguments);
58 }
59
60 public static LoggingEvent trace(
61 final Marker marker, final Throwable throwable, final String message, final Object... arguments) {
62 return new LoggingEvent(Level.TRACE, marker, throwable, message, arguments);
63 }
64
65 public static LoggingEvent trace(final Map<String, String> mdc, final String message, final Object... arguments) {
66 return new LoggingEvent(Level.TRACE, mdc, message, arguments);
67 }
68
69 public static LoggingEvent trace(
70 final Map<String, String> mdc, final Throwable throwable, final String message, final Object... arguments) {
71 return new LoggingEvent(Level.TRACE, mdc, throwable, message, arguments);
72 }
73
74 public static LoggingEvent trace(
75 final Map<String, String> mdc, final Marker marker, final String message, final Object... arguments) {
76 return new LoggingEvent(Level.TRACE, mdc, marker, message, arguments);
77 }
78
79 public static LoggingEvent trace(
80 final Map<String, String> mdc,
81 final Marker marker,
82 final Throwable throwable,
83 final String message,
84 final Object... arguments) {
85 return new LoggingEvent(Level.TRACE, mdc, marker, throwable, message, arguments);
86 }
87
88 public static LoggingEvent debug(final String message, final Object... arguments) {
89 return new LoggingEvent(Level.DEBUG, message, arguments);
90 }
91
92 public static LoggingEvent debug(final Throwable throwable, final String message, final Object... arguments) {
93 return new LoggingEvent(Level.DEBUG, throwable, message, arguments);
94 }
95
96 public static LoggingEvent debug(final Marker marker, final String message, final Object... arguments) {
97 return new LoggingEvent(Level.DEBUG, marker, message, arguments);
98 }
99
100 public static LoggingEvent debug(
101 final Marker marker, final Throwable throwable, final String message, final Object... arguments) {
102 return new LoggingEvent(Level.DEBUG, marker, throwable, message, arguments);
103 }
104
105 public static LoggingEvent debug(final Map<String, String> mdc, final String message, final Object... arguments) {
106 return new LoggingEvent(Level.DEBUG, mdc, message, arguments);
107 }
108
109 public static LoggingEvent debug(
110 final Map<String, String> mdc, final Throwable throwable, final String message, final Object... arguments) {
111 return new LoggingEvent(Level.DEBUG, mdc, throwable, message, arguments);
112 }
113
114 public static LoggingEvent debug(
115 final Map<String, String> mdc, final Marker marker, final String message, final Object... arguments) {
116 return new LoggingEvent(Level.DEBUG, mdc, marker, message, arguments);
117 }
118
119 public static LoggingEvent debug(
120 final Map<String, String> mdc,
121 final Marker marker,
122 final Throwable throwable,
123 final String message,
124 final Object... arguments) {
125 return new LoggingEvent(Level.DEBUG, mdc, marker, throwable, message, arguments);
126 }
127
128 public static LoggingEvent info(final String message, final Object... arguments) {
129 return new LoggingEvent(Level.INFO, message, arguments);
130 }
131
132 public static LoggingEvent info(final Throwable throwable, final String message, final Object... arguments) {
133 return new LoggingEvent(Level.INFO, throwable, message, arguments);
134 }
135
136 public static LoggingEvent info(final Marker marker, final String message, final Object... arguments) {
137 return new LoggingEvent(Level.INFO, marker, message, arguments);
138 }
139
140 public static LoggingEvent info(
141 final Marker marker, final Throwable throwable, final String message, final Object... arguments) {
142 return new LoggingEvent(Level.INFO, marker, throwable, message, arguments);
143 }
144
145 public static LoggingEvent info(final Map<String, String> mdc, final String message, final Object... arguments) {
146 return new LoggingEvent(Level.INFO, mdc, message, arguments);
147 }
148
149 public static LoggingEvent info(
150 final Map<String, String> mdc, final Throwable throwable, final String message, final Object... arguments) {
151 return new LoggingEvent(Level.INFO, mdc, throwable, message, arguments);
152 }
153
154 public static LoggingEvent info(
155 final Map<String, String> mdc, final Marker marker, final String message, final Object... arguments) {
156 return new LoggingEvent(Level.INFO, mdc, marker, message, arguments);
157 }
158
159 public static LoggingEvent info(
160 final Map<String, String> mdc,
161 final Marker marker,
162 final Throwable throwable,
163 final String message,
164 final Object... arguments) {
165 return new LoggingEvent(Level.INFO, mdc, marker, throwable, message, arguments);
166 }
167
168 public static LoggingEvent warn(final String message, final Object... arguments) {
169 return new LoggingEvent(Level.WARN, message, arguments);
170 }
171
172 public static LoggingEvent warn(final Throwable throwable, final String message, final Object... arguments) {
173 return new LoggingEvent(Level.WARN, throwable, message, arguments);
174 }
175
176 public static LoggingEvent warn(final Marker marker, final String message, final Object... arguments) {
177 return new LoggingEvent(Level.WARN, marker, message, arguments);
178 }
179
180 public static LoggingEvent warn(
181 final Marker marker, final Throwable throwable, final String message, final Object... arguments) {
182 return new LoggingEvent(Level.WARN, marker, throwable, message, arguments);
183 }
184
185 public static LoggingEvent warn(final Map<String, String> mdc, final String message, final Object... arguments) {
186 return new LoggingEvent(Level.WARN, mdc, message, arguments);
187 }
188
189 public static LoggingEvent warn(
190 final Map<String, String> mdc, final Throwable throwable, final String message, final Object... arguments) {
191 return new LoggingEvent(Level.WARN, mdc, throwable, message, arguments);
192 }
193
194 public static LoggingEvent warn(
195 final Map<String, String> mdc, final Marker marker, final String message, final Object... arguments) {
196 return new LoggingEvent(Level.WARN, mdc, marker, message, arguments);
197 }
198
199 public static LoggingEvent warn(
200 final Map<String, String> mdc,
201 final Marker marker,
202 final Throwable throwable,
203 final String message,
204 final Object... arguments) {
205 return new LoggingEvent(Level.WARN, mdc, marker, throwable, message, arguments);
206 }
207
208 public static LoggingEvent error(final String message, final Object... arguments) {
209 return new LoggingEvent(Level.ERROR, message, arguments);
210 }
211
212 public static LoggingEvent error(final Throwable throwable, final String message, final Object... arguments) {
213 return new LoggingEvent(Level.ERROR, throwable, message, arguments);
214 }
215
216 public static LoggingEvent error(final Marker marker, final String message, final Object... arguments) {
217 return new LoggingEvent(Level.ERROR, marker, message, arguments);
218 }
219
220 public static LoggingEvent error(
221 final Marker marker, final Throwable throwable, final String message, final Object... arguments) {
222 return new LoggingEvent(Level.ERROR, marker, throwable, message, arguments);
223 }
224
225 public static LoggingEvent error(final Map<String, String> mdc, final String message, final Object... arguments) {
226 return new LoggingEvent(Level.ERROR, mdc, message, arguments);
227 }
228
229 public static LoggingEvent error(
230 final Map<String, String> mdc, final Throwable throwable, final String message, final Object... arguments) {
231 return new LoggingEvent(Level.ERROR, mdc, throwable, message, arguments);
232 }
233
234 public static LoggingEvent error(
235 final Map<String, String> mdc, final Marker marker, final String message, final Object... arguments) {
236 return new LoggingEvent(Level.ERROR, mdc, marker, message, arguments);
237 }
238
239 public static LoggingEvent error(
240 final Map<String, String> mdc,
241 final Marker marker,
242 final Throwable throwable,
243 final String message,
244 final Object... arguments) {
245 return new LoggingEvent(Level.ERROR, mdc, marker, throwable, message, arguments);
246 }
247
248 public LoggingEvent(final Level level, final String message, final Object... arguments) {
249 this(level, Collections.<String, String>emptyMap(), Optional.<Marker>absent(), Optional.<Throwable>absent(),
250 message, arguments);
251 }
252
253 public LoggingEvent(final Level level, final Throwable throwable, final String message, final Object... arguments) {
254 this(level, Collections.<String, String>emptyMap(), Optional.<Marker>absent(), fromNullable(throwable),
255 message, arguments);
256 }
257
258 public LoggingEvent(final Level level, final Marker marker, final String message, final Object... arguments) {
259 this(level, Collections.<String, String>emptyMap(), fromNullable(marker), Optional.<Throwable>absent(),
260 message, arguments);
261 }
262
263 public LoggingEvent(
264 final Level level, final Marker marker, final Throwable throwable, final String message, final Object... arguments) {
265 this(level, Collections.<String, String>emptyMap(), fromNullable(marker), fromNullable(throwable), message, arguments);
266 }
267
268 public LoggingEvent(final Level level, final Map<String, String> mdc, final String message, final Object... arguments) {
269 this(level, mdc, Optional.<Marker>absent(), Optional.<Throwable>absent(), message, arguments);
270 }
271
272 public LoggingEvent(
273 final Level level,
274 final Map<String, String> mdc,
275 final Throwable throwable,
276 final String message,
277 final Object... arguments) {
278 this(level, mdc, Optional.<Marker>absent(), fromNullable(throwable), message, arguments);
279 }
280
281 public LoggingEvent(
282 final Level level,
283 final Map<String, String> mdc,
284 final Marker marker,
285 final String message,
286 final Object... arguments) {
287 this(level, mdc, fromNullable(marker), Optional.<Throwable>absent(), message, arguments);
288 }
289
290 public LoggingEvent(
291 final Level level,
292 final Map<String, String> mdc,
293 final Marker marker,
294 final Throwable throwable,
295 final String message,
296 final Object... arguments) {
297 this(level, mdc, fromNullable(marker), fromNullable(throwable), message, arguments);
298 }
299
300 private LoggingEvent(
301 final Level level,
302 final Map<String, String> mdc,
303 final Optional<Marker> marker,
304 final Optional<Throwable> throwable,
305 final String message,
306 final Object... arguments) {
307 this(Optional.<TestLogger>absent(), level, mdc, marker, throwable, message, arguments);
308 }
309
310 LoggingEvent(
311 final Optional<TestLogger> creatingLogger,
312 final Level level,
313 final Map<String, String> mdc,
314 final Optional<Marker> marker,
315 final Optional<Throwable> throwable,
316 final String message,
317 final Object... arguments) {
318 super();
319 this.creatingLogger = creatingLogger;
320 this.level = checkNotNull(level);
321 this.mdc = ImmutableMap.copyOf(mdc);
322 this.marker = checkNotNull(marker);
323 this.throwable = checkNotNull(throwable);
324 this.message = checkNotNull(message);
325 this.arguments = from(asList(arguments)).transform(TO_NON_NULL_VALUE).toList();
326 }
327
328 private static final Function<Object, Object> TO_NON_NULL_VALUE = new Function<Object, Object>() {
329 @Override
330 public Object apply(final Object input) {
331 return fromNullable(input).or((Object) absent());
332 }
333 };
334
335 @Identity private final Level level;
336 @Identity private final ImmutableMap<String, String> mdc;
337 @Identity private final Optional<Marker> marker;
338 @Identity private final Optional<Throwable> throwable;
339 @Identity private final String message;
340 @Identity private final ImmutableList<Object> arguments;
341
342 private final Optional<TestLogger> creatingLogger;
343 private final Instant timestamp = new Instant();
344 private final String threadName = Thread.currentThread().getName();
345
346 public Level getLevel() {
347 return level;
348 }
349
350 public ImmutableMap<String, String> getMdc() {
351 return mdc;
352 }
353
354 public Optional<Marker> getMarker() {
355 return marker;
356 }
357
358 public String getMessage() {
359 return message;
360 }
361
362 public ImmutableList<Object> getArguments() {
363 return arguments;
364 }
365
366 public Optional<Throwable> getThrowable() {
367 return throwable;
368 }
369
370
371
372
373
374 public TestLogger getCreatingLogger() {
375 return creatingLogger.get();
376 }
377
378
379
380
381 public Instant getTimestamp() {
382 return timestamp;
383 }
384
385
386
387
388 public String getThreadName() {
389 return threadName;
390 }
391
392 void print() {
393 final PrintStream output = printStreamForLevel();
394 output.println(formatLogStatement());
395 throwable.transform(printThrowableTo(output));
396 }
397
398 private static Function<Throwable, String> printThrowableTo(final PrintStream output) {
399 return new Function<Throwable, String>() {
400 @Override
401 public String apply(final Throwable throwableToPrint) {
402 throwableToPrint.printStackTrace(output);
403 return "";
404 }
405 };
406 }
407
408 private String formatLogStatement() {
409 return getTimestamp() + " [" + getThreadName() + "] " + getLevel() + safeLoggerName() + " - " + getFormattedMessage();
410 }
411
412 private String safeLoggerName() {
413 return creatingLogger.transform(toLoggerNameString).or("");
414 }
415
416 private static final Function<TestLogger, String> toLoggerNameString = new Function<TestLogger, String>() {
417 @Override
418 public String apply(final TestLogger logger) {
419 return " " + logger.getName();
420 }
421 };
422
423 private String getFormattedMessage() {
424 return MessageFormatter.arrayFormat(getMessage(), getArguments().toArray()).getMessage();
425 }
426
427 private PrintStream printStreamForLevel() {
428 switch (level) {
429 case ERROR:
430 case WARN:
431 return System.err;
432 default:
433 return System.out;
434 }
435 }
436 }