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: 710133 $
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 if (tracer.isTraceOutExchanges() && shouldLogNode(node) && shouldLogExchange(exchange)) {
086 logExchange(exchange);
087 }
088 } catch (Exception e) {
089 if (shouldLogException(exchange)) {
090 logException(exchange, e);
091 }
092 throw e;
093 }
094 }
095
096 public Object format(Exchange exchange) {
097 return formatter.format(this, exchange);
098 }
099
100 // Properties
101 //-------------------------------------------------------------------------
102 public ProcessorType getNode() {
103 return node;
104 }
105
106 public Logger getLogger() {
107 return logger;
108 }
109
110 public TraceFormatter getFormatter() {
111 return formatter;
112 }
113
114 // Implementation methods
115 //-------------------------------------------------------------------------
116 protected void logExchange(Exchange exchange) {
117 logger.process(exchange);
118 }
119
120 protected void logException(Exchange exchange, Throwable throwable) {
121 if (tracer.isTraceExceptions()) {
122 logger.process(exchange, throwable);
123 }
124 }
125
126 /**
127 * Returns true if the given exchange should be logged in the trace list
128 */
129 protected boolean shouldLogExchange(Exchange exchange) {
130 return (tracer == null || tracer.isEnabled())
131 && (tracer.getTraceFilter() == null || tracer.getTraceFilter().matches(exchange));
132 }
133
134 /**
135 * Returns true if the given exchange should be logged when an exception was thrown
136 */
137 protected boolean shouldLogException(Exchange exchange) {
138 return tracer.isTraceExceptions();
139 }
140
141 /**
142 * Returns whether exchanges coming out of processors should be traced
143 */
144 public boolean shouldTraceOutExchanges() {
145 return tracer.isTraceOutExchanges();
146 }
147
148 /**
149 * Returns true if the given node should be logged in the trace list
150 */
151 protected boolean shouldLogNode(ProcessorType node) {
152 if (node == null) {
153 return false;
154 }
155 if (!tracer.isTraceInterceptors() && (node instanceof InterceptStrategy || node instanceof InterceptorRef)) {
156 return false;
157 }
158 return true;
159 }
160
161 }