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.processor.interceptor;
018    
019    import org.apache.camel.Exchange;
020    import org.apache.camel.Processor;
021    import org.apache.camel.model.InterceptorRef;
022    import org.apache.camel.model.ProcessorType;
023    import org.apache.camel.processor.DelegateProcessor;
024    import org.apache.camel.processor.Logger;
025    import org.apache.camel.spi.InterceptStrategy;
026    import org.apache.commons.logging.LogFactory;
027    
028    /**
029     * An interceptor for debugging and tracing routes
030     *
031     * @version $Revision: 700185 $
032     */
033    public class TraceInterceptor extends DelegateProcessor implements ExchangeFormatter {
034        private Logger logger;
035        private final ProcessorType node;
036        private final Tracer tracer;
037        private TraceFormatter formatter;
038    
039        public TraceInterceptor(ProcessorType node, Processor target, TraceFormatter formatter, Tracer tracer) {
040            super(target);
041            this.tracer = tracer;
042            this.node = node;
043            this.formatter = formatter;
044    
045            // set logger to use
046            if (tracer.getLogName() != null) {
047                logger = new Logger(LogFactory.getLog(tracer.getLogName()), this);
048            } else {
049                // use default logger
050                logger = new Logger(LogFactory.getLog(TraceInterceptor.class), this);
051            }
052    
053            // set logging level if provided
054            if (tracer.getLogLevel() != null) {
055                logger.setLevel(tracer.getLogLevel());
056            }
057    
058            if (tracer.getFormatter() != null) {
059                this.formatter = tracer.getFormatter();
060            }
061        }
062    
063        /**
064         * @deprecated will be removed in Camel 2.0
065         */
066        public TraceInterceptor(ProcessorType node, Processor target, TraceFormatter formatter) {
067            this(node, target, formatter, new Tracer());
068        }
069    
070        public TraceInterceptor(ProcessorType node, Processor target, Tracer tracer) {
071            this(node, target, null, tracer);
072        }
073    
074        @Override
075        public String toString() {
076            return "TraceInterceptor[" + node + "]";
077        }
078    
079        public void process(final Exchange exchange) throws Exception {
080            try {
081                if (shouldLogNode(node) && shouldLogExchange(exchange)) {
082                    logExchange(exchange);
083                }
084                super.proceed(exchange);
085            } catch (Exception e) {
086                if (shouldLogException(exchange)) {
087                    logException(exchange, e);
088                }
089                throw e;
090            }
091        }
092    
093        public Object format(Exchange exchange) {
094            return formatter.format(this, exchange);
095        }
096    
097        // Properties
098        //-------------------------------------------------------------------------
099        public ProcessorType getNode() {
100            return node;
101        }
102    
103        public Logger getLogger() {
104            return logger;
105        }
106    
107        public TraceFormatter getFormatter() {
108            return formatter;
109        }
110    
111        // Implementation methods
112        //-------------------------------------------------------------------------
113        protected void logExchange(Exchange exchange) {
114            logger.process(exchange);
115        }
116    
117        protected void logException(Exchange exchange, Throwable throwable) {
118            if (tracer.isTraceExceptions()) {
119                logger.process(exchange, throwable);
120            }
121        }
122    
123        /**
124         * Returns true if the given exchange should be logged in the trace list
125         */
126        protected boolean shouldLogExchange(Exchange exchange) {
127            return (tracer == null || tracer.isEnabled())
128                && (tracer.getTraceFilter() == null || tracer.getTraceFilter().matches(exchange));
129        }
130    
131        /**
132         * Returns true if the given exchange should be logged when an exception was thrown
133         */
134        protected boolean shouldLogException(Exchange exchange) {
135            return tracer.isTraceExceptions();
136        }
137    
138    
139        /**
140         * Returns true if the given node should be logged in the trace list
141         */
142        protected boolean shouldLogNode(ProcessorType node) {
143            if (node == null) {
144                return false;
145            }
146            if (!tracer.isTraceInterceptors() && (node instanceof InterceptStrategy || node instanceof InterceptorRef)) {
147                return false;
148            }
149            return true;
150        }
151    
152    }