1 /**
2 * Logback: the reliable, generic, fast and flexible logging framework.
3 * Copyright (C) 1999-2011, QOS.ch. All rights reserved.
4 *
5 * This program and the accompanying materials are dual-licensed under
6 * either the terms of the Eclipse Public License v1.0 as published by
7 * the Eclipse Foundation
8 *
9 * or (per the licensee's choosing)
10 *
11 * under the terms of the GNU Lesser General Public License version 2.1
12 * as published by the Free Software Foundation.
13 */
14 package ch.qos.logback.classic.pattern;
15
16 import ch.qos.logback.classic.spi.ILoggingEvent;
17 import ch.qos.logback.core.pattern.Converter;
18 import ch.qos.logback.core.pattern.ConverterUtil;
19 import ch.qos.logback.core.pattern.PostCompileProcessor;
20
21 public class EnsureExceptionHandling implements
22 PostCompileProcessor<ILoggingEvent> {
23
24 /**
25 * This implementation checks if any of the converters in the chain handles
26 * exceptions. If not, then this method adds a
27 * {@link ExtendedThrowableProxyConverter} instance to the end of the chain.
28 * <p>
29 * This allows appenders using this layout to output exception information
30 * event if the user forgets to add %ex to the pattern. Note that the
31 * appenders defined in the Core package are not aware of exceptions nor
32 * LoggingEvents.
33 * <p>
34 * If for some reason the user wishes to NOT print exceptions, then she can
35 * add %nopex to the pattern.
36 *
37 *
38 */
39 public void process(Converter<ILoggingEvent> head) {
40 if(head == null) {
41 // this should never happen
42 throw new IllegalArgumentException("cannot process empty chain");
43 }
44 if (!chainHandlesThrowable(head)) {
45 Converter<ILoggingEvent> tail = ConverterUtil.findTail(head);
46 Converter<ILoggingEvent> exConverter = new ExtendedThrowableProxyConverter();
47 tail.setNext(exConverter);
48 }
49 }
50
51 /**
52 * This method computes whether a chain of converters handles exceptions or
53 * not.
54 *
55 * @param head
56 * The first element of the chain
57 * @return true if can handle throwables contained in logging events
58 */
59 public boolean chainHandlesThrowable(Converter head) {
60 Converter c = head;
61 while (c != null) {
62 if (c instanceof ThrowableHandlingConverter) {
63 return true;
64 }
65 c = c.getNext();
66 }
67 return false;
68 }
69 }