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.spi.ExchangeFormatter;
026    import org.apache.camel.util.MessageHelper;
027    import org.apache.camel.util.ObjectHelper;
028    
029    /**
030     * Logger formatter to format the logging output.
031     */
032    public class LogFormatter implements ExchangeFormatter {
033    
034        protected static final String LS = System.getProperty("line.separator");
035    
036        private boolean showExchangeId;
037        private boolean showExchangePattern = true;
038        private boolean showProperties;
039        private boolean showHeaders;
040        private boolean showBodyType = true;
041        private boolean showBody = true;
042        private boolean showOut;
043        private boolean showException;
044        private boolean showCaughtException;
045        private boolean showStackTrace;
046        private boolean showAll;
047        private boolean multiline;
048        private boolean showFuture;
049        private boolean showStreams;
050        private boolean showFiles;
051        private int maxChars = 10000;
052    
053        public String format(Exchange exchange) {
054            Message in = exchange.getIn();
055    
056            StringBuilder sb = new StringBuilder();
057            if (showAll || showExchangeId) {
058                if (multiline) {
059                    sb.append(LS);
060                }
061                sb.append(", Id:").append(exchange.getExchangeId());
062            }
063            if (showAll || showExchangePattern) {
064                if (multiline) {
065                    sb.append(LS);
066                }
067                sb.append(", ExchangePattern:").append(exchange.getPattern());
068            }
069    
070            if (showAll || showProperties) {
071                if (multiline) {
072                    sb.append(LS);
073                }
074                sb.append(", Properties:").append(exchange.getProperties());
075            }
076            if (showAll || showHeaders) {
077                if (multiline) {
078                    sb.append(LS);
079                }
080                sb.append(", Headers:").append(in.getHeaders());
081            }
082            if (showAll || showBodyType) {
083                if (multiline) {
084                    sb.append(LS);
085                }
086                sb.append(", BodyType:").append(getBodyTypeAsString(in));
087            }
088            if (showAll || showBody) {
089                if (multiline) {
090                    sb.append(LS);
091                }
092                sb.append(", Body:").append(getBodyAsString(in));
093            }
094    
095            if (showAll || showException || showCaughtException) {
096    
097                // try exception on exchange first
098                Exception exception = exchange.getException();
099                boolean caught = false;
100                if ((showAll || showCaughtException) && exception == null) {
101                    // fallback to caught exception
102                    exception = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
103                    caught = true;
104                }
105    
106                if (exception != null) {
107                    if (multiline) {
108                        sb.append(LS);
109                    }
110                    if (caught) {
111                        sb.append(", CaughtExceptionType:").append(exception.getClass().getCanonicalName());
112                        sb.append(", CaughtExceptionMessage:").append(exception.getMessage());
113                    } else {
114                        sb.append(", ExceptionType:").append(exception.getClass().getCanonicalName());
115                        sb.append(", ExceptionMessage:").append(exception.getMessage());
116                    }
117                    if (showAll || showStackTrace) {
118                        StringWriter sw = new StringWriter();
119                        exception.printStackTrace(new PrintWriter(sw));
120                        sb.append(", StackTrace:").append(sw.toString());
121                    }
122                }
123            }
124    
125            if (showAll || showOut) {
126                if (exchange.hasOut()) {
127                    Message out = exchange.getOut();
128                    if (showAll || showHeaders) {
129                        if (multiline) {
130                            sb.append(LS);
131                        }
132                        sb.append(", OutHeaders:").append(out.getHeaders());
133                    }
134                    if (showAll || showBodyType) {
135                        if (multiline) {
136                            sb.append(LS);
137                        }
138                        sb.append(", OutBodyType:").append(getBodyTypeAsString(out));
139                    }
140                    if (showAll || showBody) {
141                        if (multiline) {
142                            sb.append(LS);
143                        }
144                        sb.append(", OutBody:").append(getBodyAsString(out));
145                    }
146                } else {
147                    if (multiline) {
148                        sb.append(LS);
149                    }
150                    sb.append(", Out: null");
151                }
152            }
153    
154            if (maxChars > 0) {
155                StringBuilder answer = new StringBuilder();
156                for (String s : sb.toString().split(LS)) {
157                    if (s != null) {
158                        if (s.length() > maxChars) {
159                            s = s.substring(0, maxChars);
160                            answer.append(s).append("...");
161                        } else {
162                            answer.append(s);
163                        }
164                        if (multiline) {
165                            answer.append(LS);
166                        }
167                    }
168                }
169    
170                // get rid of the leading space comma if needed
171                return "Exchange[" + (multiline ? answer.append(']').toString() : answer.toString().substring(2) + "]");
172            }
173    
174            // get rid of the leading space comma if needed
175            return "Exchange[" + (multiline ? sb.append(']').toString() : sb.toString().substring(2) + "]");
176        }
177    
178        public boolean isShowExchangeId() {
179            return showExchangeId;
180        }
181    
182        public void setShowExchangeId(boolean showExchangeId) {
183            this.showExchangeId = showExchangeId;
184        }
185    
186        public boolean isShowProperties() {
187            return showProperties;
188        }
189    
190        public void setShowProperties(boolean showProperties) {
191            this.showProperties = showProperties;
192        }
193    
194        public boolean isShowHeaders() {
195            return showHeaders;
196        }
197    
198        public void setShowHeaders(boolean showHeaders) {
199            this.showHeaders = showHeaders;
200        }
201    
202        public boolean isShowBodyType() {
203            return showBodyType;
204        }
205    
206        public void setShowBodyType(boolean showBodyType) {
207            this.showBodyType = showBodyType;
208        }
209    
210        public boolean isShowBody() {
211            return showBody;
212        }
213    
214        public void setShowBody(boolean showBody) {
215            this.showBody = showBody;
216        }
217    
218        public boolean isShowOut() {
219            return showOut;
220        }
221    
222        public void setShowOut(boolean showOut) {
223            this.showOut = showOut;
224        }
225    
226        public boolean isShowAll() {
227            return showAll;
228        }
229    
230        public void setShowAll(boolean showAll) {
231            this.showAll = showAll;
232        }
233    
234        public boolean isShowException() {
235            return showException;
236        }
237    
238        public void setShowException(boolean showException) {
239            this.showException = showException;
240        }
241    
242        public boolean isShowStackTrace() {
243            return showStackTrace;
244        }
245    
246        public void setShowStackTrace(boolean showStackTrace) {
247            this.showStackTrace = showStackTrace;
248        }
249    
250        public boolean isShowCaughtException() {
251            return showCaughtException;
252        }
253    
254        public void setShowCaughtException(boolean showCaughtException) {
255            this.showCaughtException = showCaughtException;
256        }
257    
258        public boolean isMultiline() {
259            return multiline;
260        }
261    
262        public int getMaxChars() {
263            return maxChars;
264        }
265    
266        public void setMaxChars(int maxChars) {
267            this.maxChars = maxChars;
268        }
269    
270        /**
271         * If enabled then each information is outputted on a newline.
272         */
273        public void setMultiline(boolean multiline) {
274            this.multiline = multiline;
275        }
276    
277        public boolean isShowFuture() {
278            return showFuture;
279        }
280    
281        /**
282         * If enabled Camel will on Future objects wait for it to complete to obtain the payload to be logged.
283         * <p/>
284         * Is default disabled.
285         */
286        public void setShowFuture(boolean showFuture) {
287            this.showFuture = showFuture;
288        }
289    
290        public boolean isShowExchangePattern() {
291            return showExchangePattern;
292        }
293    
294        public void setShowExchangePattern(boolean showExchangePattern) {
295            this.showExchangePattern = showExchangePattern;
296        }
297    
298        public boolean isShowStreams() {
299            return showStreams;
300        }
301    
302        /**
303         * If enabled Camel will output stream objects
304         * <p/>
305         * Is default disabled.
306         */
307        public void setShowStreams(boolean showStreams) {
308            this.showStreams = showStreams;
309        }
310    
311        public boolean isShowFiles() {
312            return showFiles;
313        }
314    
315        /**
316         * If enabled Camel will output files
317         * <p/>
318         * Is default disabled.
319         */
320        public void setShowFiles(boolean showFiles) {
321            this.showFiles = showFiles;
322        }
323    
324        // Implementation methods
325        //-------------------------------------------------------------------------
326        protected String getBodyAsString(Message message) {
327            if (message.getBody() instanceof Future) {
328                if (!isShowFuture()) {
329                    // just use a to string of the future object
330                    return message.getBody().toString();
331                }
332            }
333    
334            return MessageHelper.extractBodyForLogging(message, "", isShowStreams(), isShowFiles(), -1);
335        }
336    
337        protected String getBodyTypeAsString(Message message) {
338            String answer = ObjectHelper.classCanonicalName(message.getBody());
339            if (answer != null && answer.startsWith("java.lang.")) {
340                return answer.substring(10);
341            }
342            return answer;
343        }
344    
345    }