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