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                // switch string buffer
171                sb = answer;
172            }
173    
174            if (multiline) {
175                sb.insert(0, "Exchange[");
176                sb.append("]");
177                return sb.toString();
178            } else {
179                // get rid of the leading space comma if needed
180                if (sb.length() > 0 && sb.charAt(0) == ',' && sb.charAt(1) == ' ') {
181                    sb.replace(0, 2, "");
182                }
183                sb.insert(0, "Exchange[");
184                sb.append("]");
185    
186                return sb.toString();
187            }
188        }
189    
190        public boolean isShowExchangeId() {
191            return showExchangeId;
192        }
193    
194        public void setShowExchangeId(boolean showExchangeId) {
195            this.showExchangeId = showExchangeId;
196        }
197    
198        public boolean isShowProperties() {
199            return showProperties;
200        }
201    
202        public void setShowProperties(boolean showProperties) {
203            this.showProperties = showProperties;
204        }
205    
206        public boolean isShowHeaders() {
207            return showHeaders;
208        }
209    
210        public void setShowHeaders(boolean showHeaders) {
211            this.showHeaders = showHeaders;
212        }
213    
214        public boolean isShowBodyType() {
215            return showBodyType;
216        }
217    
218        public void setShowBodyType(boolean showBodyType) {
219            this.showBodyType = showBodyType;
220        }
221    
222        public boolean isShowBody() {
223            return showBody;
224        }
225    
226        public void setShowBody(boolean showBody) {
227            this.showBody = showBody;
228        }
229    
230        public boolean isShowOut() {
231            return showOut;
232        }
233    
234        public void setShowOut(boolean showOut) {
235            this.showOut = showOut;
236        }
237    
238        public boolean isShowAll() {
239            return showAll;
240        }
241    
242        public void setShowAll(boolean showAll) {
243            this.showAll = showAll;
244        }
245    
246        public boolean isShowException() {
247            return showException;
248        }
249    
250        public void setShowException(boolean showException) {
251            this.showException = showException;
252        }
253    
254        public boolean isShowStackTrace() {
255            return showStackTrace;
256        }
257    
258        public void setShowStackTrace(boolean showStackTrace) {
259            this.showStackTrace = showStackTrace;
260        }
261    
262        public boolean isShowCaughtException() {
263            return showCaughtException;
264        }
265    
266        public void setShowCaughtException(boolean showCaughtException) {
267            this.showCaughtException = showCaughtException;
268        }
269    
270        public boolean isMultiline() {
271            return multiline;
272        }
273    
274        public int getMaxChars() {
275            return maxChars;
276        }
277    
278        public void setMaxChars(int maxChars) {
279            this.maxChars = maxChars;
280        }
281    
282        /**
283         * If enabled then each information is outputted on a newline.
284         */
285        public void setMultiline(boolean multiline) {
286            this.multiline = multiline;
287        }
288    
289        public boolean isShowFuture() {
290            return showFuture;
291        }
292    
293        /**
294         * If enabled Camel will on Future objects wait for it to complete to obtain the payload to be logged.
295         * <p/>
296         * Is default disabled.
297         */
298        public void setShowFuture(boolean showFuture) {
299            this.showFuture = showFuture;
300        }
301    
302        public boolean isShowExchangePattern() {
303            return showExchangePattern;
304        }
305    
306        public void setShowExchangePattern(boolean showExchangePattern) {
307            this.showExchangePattern = showExchangePattern;
308        }
309    
310        public boolean isShowStreams() {
311            return showStreams;
312        }
313    
314        /**
315         * If enabled Camel will output stream objects
316         * <p/>
317         * Is default disabled.
318         */
319        public void setShowStreams(boolean showStreams) {
320            this.showStreams = showStreams;
321        }
322    
323        public boolean isShowFiles() {
324            return showFiles;
325        }
326    
327        /**
328         * If enabled Camel will output files
329         * <p/>
330         * Is default disabled.
331         */
332        public void setShowFiles(boolean showFiles) {
333            this.showFiles = showFiles;
334        }
335    
336        // Implementation methods
337        //-------------------------------------------------------------------------
338        protected String getBodyAsString(Message message) {
339            if (message.getBody() instanceof Future) {
340                if (!isShowFuture()) {
341                    // just use a to string of the future object
342                    return message.getBody().toString();
343                }
344            }
345    
346            return MessageHelper.extractBodyForLogging(message, "", isShowStreams(), isShowFiles(), -1);
347        }
348    
349        protected String getBodyTypeAsString(Message message) {
350            String answer = ObjectHelper.classCanonicalName(message.getBody());
351            if (answer != null && answer.startsWith("java.lang.")) {
352                return answer.substring(10);
353            }
354            return answer;
355        }
356    
357    }