1
2
3
4
5
6
7
8
9
10 package ch.qos.logback.classic.pattern;
11
12 import java.util.ArrayList;
13 import java.util.List;
14 import java.util.Map;
15
16 import ch.qos.logback.classic.spi.LoggingEvent;
17 import ch.qos.logback.classic.spi.ThrowableDataPoint;
18 import ch.qos.logback.classic.spi.ThrowableProxy;
19 import ch.qos.logback.core.Context;
20 import ch.qos.logback.core.CoreConstants;
21 import ch.qos.logback.core.boolex.EvaluationException;
22 import ch.qos.logback.core.boolex.EventEvaluator;
23 import ch.qos.logback.core.status.ErrorStatus;
24
25
26
27
28
29
30 public class ThrowableProxyConverter extends ThrowableHandlingConverter {
31
32 int lengthOption;
33 List<EventEvaluator<LoggingEvent>> evaluatorList = null;
34
35 final int MAX_ERROR_COUNT = 4;
36 int errorCount = 0;
37
38 @SuppressWarnings("unchecked")
39 public void start() {
40
41 String lengthStr = getFirstOption();
42
43 if (lengthStr == null) {
44 lengthOption = Integer.MAX_VALUE;
45 } else {
46 lengthStr = lengthStr.toLowerCase();
47 if ("full".equals(lengthStr)) {
48 lengthOption = Integer.MAX_VALUE;
49 } else if ("short".equals(lengthStr)) {
50 lengthOption = 2;
51 } else {
52 try {
53
54 lengthOption = Integer.parseInt(lengthStr) + 1;
55 } catch (NumberFormatException nfe) {
56 addError("Could not parser [" + lengthStr + " as an integer");
57 lengthOption = Integer.MAX_VALUE;
58 }
59 }
60 }
61
62 final List optionList = getOptionList();
63
64 if (optionList != null && optionList.size() > 1) {
65 final int optionListSize = optionList.size();
66 for (int i = 1; i < optionListSize; i++) {
67 String evaluatorStr = (String) optionList.get(i);
68 Context context = getContext();
69 Map evaluatorMap = (Map) context.getObject(CoreConstants.EVALUATOR_MAP);
70 EventEvaluator<LoggingEvent> ee = (EventEvaluator<LoggingEvent>) evaluatorMap.get(evaluatorStr);
71 addEvaluator(ee);
72 }
73 }
74 super.start();
75 }
76
77 private void addEvaluator(EventEvaluator<LoggingEvent> ee) {
78 if (evaluatorList == null) {
79 evaluatorList = new ArrayList<EventEvaluator<LoggingEvent>>();
80 }
81 evaluatorList.add(ee);
82 }
83
84 public void stop() {
85 evaluatorList = null;
86 super.stop();
87 }
88
89 protected void extraData(StringBuilder builder, ThrowableDataPoint tdp) {
90
91 }
92
93 protected void prepareLoggingEvent(LoggingEvent event) {
94
95 }
96
97 public String convert(LoggingEvent event) {
98 StringBuilder buf = new StringBuilder(32);
99
100 ThrowableProxy information = event.getThrowableProxy();
101
102 if (information == null) {
103 return CoreConstants.EMPTY_STRING;
104 }
105
106 ThrowableDataPoint[] tdpArray = information.getThrowableDataPointArray();
107
108 int length = (lengthOption > tdpArray.length) ? tdpArray.length
109 : lengthOption;
110
111
112 if (evaluatorList != null) {
113 boolean printStack = true;
114 for (int i = 0; i < evaluatorList.size(); i++) {
115 EventEvaluator<LoggingEvent> ee = evaluatorList.get(i);
116 try {
117 if (ee.evaluate(event)) {
118 printStack = false;
119 break;
120 }
121 } catch (EvaluationException eex) {
122 errorCount++;
123 if (errorCount < MAX_ERROR_COUNT) {
124 addError("Exception thrown for evaluator named [" + ee.getName()
125 + "]", eex);
126 } else if (errorCount == MAX_ERROR_COUNT) {
127 ErrorStatus errorStatus = new ErrorStatus(
128 "Exception thrown for evaluator named [" + ee.getName() + "].",
129 this, eex);
130 errorStatus.add(new ErrorStatus("This was the last warning about this evaluator's errors." +
131 "We don't want the StatusManager to get flooded.", this));
132 addStatus(errorStatus);
133 }
134 }
135 }
136
137 if (!printStack) {
138 return CoreConstants.EMPTY_STRING;
139 }
140 }
141
142 prepareLoggingEvent(event);
143
144 buf.append(tdpArray[0]).append(CoreConstants.LINE_SEPARATOR);
145 for (int i = 1; i < length; i++) {
146 String string = tdpArray[i].toString();
147 buf.append(string);
148 extraData(buf, tdpArray[i]);
149 buf.append(CoreConstants.LINE_SEPARATOR);
150 }
151
152 return buf.toString();
153 }
154
155 }