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 }