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 java.util.List;
020    
021    import org.apache.camel.CamelContext;
022    import org.apache.camel.Endpoint;
023    import org.apache.camel.LoggingLevel;
024    import org.apache.camel.Predicate;
025    import org.apache.camel.Processor;
026    import org.apache.camel.model.ProcessorDefinition;
027    import org.apache.camel.spi.InterceptStrategy;
028    
029    /**
030     * An interceptor strategy for tracing routes
031     *
032     * @version $Revision: 750806 $
033     */
034    public class Tracer implements InterceptStrategy {
035    
036        private TraceFormatter formatter = new DefaultTraceFormatter();
037        private boolean enabled = true;
038        private String logName;
039        private LoggingLevel logLevel;
040        private Predicate traceFilter;
041        private boolean traceInterceptors;
042        private boolean traceExceptions = true;
043        private boolean traceOutExchanges;
044        private String destinationUri;
045        private Endpoint destination;
046        private boolean useJpa;
047    
048        /**
049         * A helper method to return the Tracer instance for a given {@link CamelContext} if one is enabled
050         *
051         * @param context the camel context the tracer is connected to
052         * @return the tracer or null if none can be found
053         */
054        public static Tracer getTracer(CamelContext context) {
055            List<InterceptStrategy> list = context.getInterceptStrategies();
056            for (InterceptStrategy interceptStrategy : list) {
057                if (interceptStrategy instanceof Tracer) {
058                    return (Tracer)interceptStrategy;
059                }
060            }
061            return null;
062        }
063    
064        public Processor wrapProcessorInInterceptors(ProcessorDefinition processorType, Processor target) throws Exception {
065            // Force the creation of an id, otherwise the id is not available when the trace formatter is
066            // outputting trace information
067            String id = processorType.idOrCreate();
068            return new TraceInterceptor(processorType, target, formatter, this);
069        }
070    
071        public TraceFormatter getFormatter() {
072            return formatter;
073        }
074    
075        public DefaultTraceFormatter getDefaultTraceFormatter() {
076            if (formatter instanceof DefaultTraceFormatter) {
077                return (DefaultTraceFormatter) formatter;
078            }
079            return null;
080        }
081    
082        public void setFormatter(TraceFormatter formatter) {
083            this.formatter = formatter;
084        }
085    
086        public void setEnabled(boolean flag) {
087            enabled = flag;
088        }
089    
090        public boolean isEnabled() {
091            return enabled;
092        }
093    
094        public boolean isTraceInterceptors() {
095            return traceInterceptors;
096        }
097    
098        /**
099         * Sets whether interceptors should be traced or not
100         */
101        public void setTraceInterceptors(boolean traceInterceptors) {
102            this.traceInterceptors = traceInterceptors;
103        }
104    
105        public Predicate getTraceFilter() {
106            return traceFilter;
107        }
108    
109        /**
110         * Sets a predicate to be used as filter when tracing
111         */
112        public void setTraceFilter(Predicate traceFilter) {
113            this.traceFilter = traceFilter;
114        }
115    
116        public LoggingLevel getLogLevel() {
117            return logLevel;
118        }
119    
120        /**
121         * Sets the logging level to output tracing. Will use <tt>INFO</tt> level by default.
122         */
123        public void setLogLevel(LoggingLevel logLevel) {
124            this.logLevel = logLevel;
125        }
126    
127        public boolean isTraceExceptions() {
128            return traceExceptions;
129        }
130    
131        /**
132         * Sets whether thrown exceptions should be traced
133         */
134        public void setTraceExceptions(boolean traceExceptions) {
135            this.traceExceptions = traceExceptions;
136        }
137    
138        public String getLogName() {
139            return logName;
140        }
141    
142        /**
143         * Sets the logging name to use.
144         * Will default use <tt>org.apache.camel.processor.interceptor.TraceInterceptor<tt>.
145         */
146        public void setLogName(String logName) {
147            this.logName = logName;
148        }
149    
150        /**
151         * Sets whether exchanges coming out of processors should be traced
152         */    
153        public void setTraceOutExchanges(boolean traceOutExchanges) {
154            this.traceOutExchanges = traceOutExchanges;
155        }
156        
157        public boolean isTraceOutExchanges() {
158            return traceOutExchanges;
159        }
160    
161        public String getDestinationUri() {
162            return destinationUri;
163        }
164    
165        /**
166         * Sets an optional destination to send the traced Exchange wrapped in a {@link TraceEventExchange}.
167         * <p/>
168         * Can be used to store tracing as files, in a database or whatever. The routing of the Exchange
169         * will happen synchronously and the original route will first continue when this destination routing
170         * has been compledted.
171         */
172        public void setDestinationUri(String destinationUri) {
173            this.destinationUri = destinationUri;
174        }
175    
176        public Endpoint getDestination() {
177            return destination;
178        }
179    
180        /**
181         * See {@link #setDestinationUri(String)}
182         */
183        public void setDestination(Endpoint destination) {
184            this.destination = destination;
185        }
186    
187        public boolean isUseJpa() {
188            return useJpa;
189        }
190    
191        /**
192         * Sets whether we should use a JpaTraceEventMessage instead of
193         * an ordinary {@link org.apache.camel.processor.interceptor.DefaultTraceEventMessage}
194         * <p/>
195         * Use this to allow persistence of trace events into a database using JPA.
196         * This requires camel-jpa in the classpath.
197         */
198        public void setUseJpa(boolean useJpa) {
199            this.useJpa = useJpa;
200        }
201    }