001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.log;
018
019 import java.io.PrintWriter;
020 import java.io.StringWriter;
021 import java.util.concurrent.Future;
022
023 import org.apache.camel.Exchange;
024 import org.apache.camel.Message;
025 import org.apache.camel.StreamCache;
026 import org.apache.camel.spi.ExchangeFormatter;
027 import org.apache.camel.util.ObjectHelper;
028
029 /**
030 * Log formatter to format the logging output.
031 */
032 public class LogFormatter implements ExchangeFormatter {
033
034 private boolean showExchangeId;
035 private boolean showProperties;
036 private boolean showHeaders;
037 private boolean showBodyType = true;
038 private boolean showBody = true;
039 private boolean showOut;
040 private boolean showException;
041 private boolean showCaughtException;
042 private boolean showStackTrace;
043 private boolean showAll;
044 private boolean multiline;
045 private boolean showFuture;
046 private int maxChars;
047
048 public Object format(Exchange exchange) {
049 Message in = exchange.getIn();
050
051 StringBuilder sb = new StringBuilder("");
052 if (showAll || showExchangeId) {
053 if (multiline) {
054 sb.append('\n');
055 }
056 sb.append(", Id:").append(exchange.getExchangeId());
057 }
058 if (showAll || showProperties) {
059 if (multiline) {
060 sb.append('\n');
061 }
062 sb.append(", Properties:").append(exchange.getProperties());
063 }
064 if (showAll || showHeaders) {
065 if (multiline) {
066 sb.append('\n');
067 }
068 sb.append(", Headers:").append(in.getHeaders());
069 }
070 if (showAll || showBodyType) {
071 if (multiline) {
072 sb.append('\n');
073 }
074 sb.append(", BodyType:").append(getBodyTypeAsString(in));
075 }
076 if (showAll || showBody) {
077 if (multiline) {
078 sb.append('\n');
079 }
080 sb.append(", Body:").append(getBodyAsString(in));
081 }
082
083 if (showAll || showException || showCaughtException) {
084
085 // try exception on exchange first
086 Exception exception = exchange.getException();
087 boolean caught = false;
088 if ((showAll || showCaughtException) && exception == null) {
089 // fallback to caught exception
090 exception = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
091 caught = true;
092 }
093
094 if (exception != null) {
095 if (multiline) {
096 sb.append('\n');
097 }
098 if (caught) {
099 sb.append(", CaughtExceptionType:").append(exception.getClass().getCanonicalName());
100 sb.append(", CaughtExceptionMessage:").append(exception.getMessage());
101 } else {
102 sb.append(", ExceptionType:").append(exception.getClass().getCanonicalName());
103 sb.append(", ExceptionMessage:").append(exception.getMessage());
104 }
105 if (showAll || showStackTrace) {
106 StringWriter sw = new StringWriter();
107 exception.printStackTrace(new PrintWriter(sw));
108 sb.append(", StackTrace:").append(sw.toString());
109 }
110 }
111 }
112
113 if (showAll || showOut) {
114 if (exchange.hasOut()) {
115 Message out = exchange.getOut();
116 if (showAll || showHeaders) {
117 if (multiline) {
118 sb.append('\n');
119 }
120 sb.append(", OutHeaders:").append(out.getHeaders());
121 }
122 if (showAll || showBodyType) {
123 if (multiline) {
124 sb.append('\n');
125 }
126 sb.append(", OutBodyType:").append(getBodyTypeAsString(out));
127 }
128 if (showAll || showBody) {
129 if (multiline) {
130 sb.append('\n');
131 }
132 sb.append(", OutBody:").append(getBodyAsString(out));
133 }
134 } else {
135 if (multiline) {
136 sb.append('\n');
137 }
138 sb.append(", Out: null");
139 }
140 }
141
142 if (maxChars > 0) {
143 StringBuilder answer = new StringBuilder();
144 for (String s : sb.toString().split("\n")) {
145 if (s != null) {
146 if (s.length() > maxChars) {
147 s = s.substring(0, maxChars);
148 answer.append(s).append("...");
149 } else {
150 answer.append(s);
151 }
152 if (multiline) {
153 answer.append("\n");
154 }
155 }
156 }
157
158 // get rid of the leading space comma if needed
159 return "Exchange[" + (multiline ? answer.append(']').toString() : answer.toString().substring(2) + "]");
160 }
161
162 // get rid of the leading space comma if needed
163 return "Exchange[" + (multiline ? sb.append(']').toString() : sb.toString().substring(2) + "]");
164 }
165
166 public boolean isShowExchangeId() {
167 return showExchangeId;
168 }
169
170 public void setShowExchangeId(boolean showExchangeId) {
171 this.showExchangeId = showExchangeId;
172 }
173
174 public boolean isShowProperties() {
175 return showProperties;
176 }
177
178 public void setShowProperties(boolean showProperties) {
179 this.showProperties = showProperties;
180 }
181
182 public boolean isShowHeaders() {
183 return showHeaders;
184 }
185
186 public void setShowHeaders(boolean showHeaders) {
187 this.showHeaders = showHeaders;
188 }
189
190 public boolean isShowBodyType() {
191 return showBodyType;
192 }
193
194 public void setShowBodyType(boolean showBodyType) {
195 this.showBodyType = showBodyType;
196 }
197
198 public boolean isShowBody() {
199 return showBody;
200 }
201
202 public void setShowBody(boolean showBody) {
203 this.showBody = showBody;
204 }
205
206 public boolean isShowOut() {
207 return showOut;
208 }
209
210 public void setShowOut(boolean showOut) {
211 this.showOut = showOut;
212 }
213
214 public boolean isShowAll() {
215 return showAll;
216 }
217
218 public void setShowAll(boolean showAll) {
219 this.showAll = showAll;
220 }
221
222 public boolean isShowException() {
223 return showException;
224 }
225
226 public void setShowException(boolean showException) {
227 this.showException = showException;
228 }
229
230 public boolean isShowStackTrace() {
231 return showStackTrace;
232 }
233
234 public void setShowStackTrace(boolean showStackTrace) {
235 this.showStackTrace = showStackTrace;
236 }
237
238 public boolean isShowCaughtException() {
239 return showCaughtException;
240 }
241
242 public void setShowCaughtException(boolean showCaughtException) {
243 this.showCaughtException = showCaughtException;
244 }
245
246 public boolean isMultiline() {
247 return multiline;
248 }
249
250 public int getMaxChars() {
251 return maxChars;
252 }
253
254 public void setMaxChars(int maxChars) {
255 this.maxChars = maxChars;
256 }
257
258 /**
259 * If enabled then each information is outputted on a newline.
260 */
261 public void setMultiline(boolean multiline) {
262 this.multiline = multiline;
263 }
264
265 public boolean isShowFuture() {
266 return showFuture;
267 }
268
269 /**
270 * If enabled Camel will on Future objects wait for it to complete to obtain the payload to be logged.
271 * <p/>
272 * Is default disabled.
273 */
274 public void setShowFuture(boolean showFuture) {
275 this.showFuture = showFuture;
276 }
277
278
279 // Implementation methods
280 //-------------------------------------------------------------------------
281 protected Object getBodyAsString(Message message) {
282 if (message.getBody() instanceof Future) {
283 if (!isShowFuture()) {
284 // just use a to string of the future object
285 return message.getBody().toString();
286 }
287 }
288
289 StreamCache newBody = message.getBody(StreamCache.class);
290 if (newBody != null) {
291 message.setBody(newBody);
292 }
293
294 Object answer = message.getBody(String.class);
295 if (answer == null) {
296 answer = message.getBody();
297 }
298
299 if (newBody != null) {
300 // Reset the StreamCache
301 newBody.reset();
302 }
303 return answer;
304 }
305
306 protected Object getBodyTypeAsString(Message message) {
307 String answer = ObjectHelper.classCanonicalName(message.getBody());
308 if (answer != null && answer.startsWith("java.lang.")) {
309 return answer.substring(10);
310 }
311 return answer;
312 }
313
314 }