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 }