@Override public boolean process(final Exchange exchange, final AsyncCallback callback) { // do not trace if tracing is disabled if (!tracer.isEnabled() || (routeContext != null && !routeContext.isTracing())) { return processor.process(exchange, callback); } // interceptor will also trace routes supposed only for TraceEvents so we need to skip // logging TraceEvents to avoid infinite looping if (exchange.getProperty(Exchange.TRACE_EVENT, false, Boolean.class)) { // but we must still process to allow routing of TraceEvents to eg a JPA endpoint return processor.process(exchange, callback); } final boolean shouldLog = shouldLogNode(node) && shouldLogExchange(exchange); // whether we should trace it or not, some nodes should be skipped as they are abstract // intermediate steps for instance related to on completion boolean trace = true; boolean sync = true; // okay this is a regular exchange being routed we might need to log and trace try { // before if (shouldLog) { // traced holds the information about the current traced route path if (exchange.getUnitOfWork() != null) { TracedRouteNodes traced = exchange.getUnitOfWork().getTracedRouteNodes(); if (node instanceof OnCompletionDefinition || node instanceof OnExceptionDefinition) { // skip any of these as its just a marker definition trace = false; } else if (ProcessorDefinitionHelper.isFirstChildOfType( OnCompletionDefinition.class, node)) { // special for on completion tracing traceOnCompletion(traced, exchange); } else if (ProcessorDefinitionHelper.isFirstChildOfType( OnExceptionDefinition.class, node)) { // special for on exception traceOnException(traced, exchange); } else if (ProcessorDefinitionHelper.isFirstChildOfType(CatchDefinition.class, node)) { // special for do catch traceDoCatch(traced, exchange); } else if (ProcessorDefinitionHelper.isFirstChildOfType(FinallyDefinition.class, node)) { // special for do finally traceDoFinally(traced, exchange); } else if (ProcessorDefinitionHelper.isFirstChildOfType( AggregateDefinition.class, node)) { // special for aggregate traceAggregate(traced, exchange); } else { // regular so just add it traced.addTraced(new DefaultRouteNode(node, super.getProcessor())); } } else { LOG.trace("Cannot trace as this Exchange does not have an UnitOfWork: {}", exchange); } } // log and trace the processor Object state = null; if (shouldLog && trace) { logExchange(exchange); // either call the in or generic trace method depending on OUT has been enabled or not if (tracer.isTraceOutExchanges()) { state = traceExchangeIn(exchange); } else { traceExchange(exchange); } } final Object traceState = state; // special for interceptor where we need to keep booking how far we have routed in the // intercepted processors if (node.getParent() instanceof InterceptDefinition && exchange.getUnitOfWork() != null) { TracedRouteNodes traced = exchange.getUnitOfWork().getTracedRouteNodes(); traceIntercept((InterceptDefinition) node.getParent(), traced, exchange); } // process the exchange sync = processor.process( exchange, new AsyncCallback() { @Override public void done(boolean doneSync) { try { // after (trace out) if (shouldLog && tracer.isTraceOutExchanges()) { logExchange(exchange); traceExchangeOut(exchange, traceState); } } catch (Throwable e) { // some exception occurred in trace logic if (shouldLogException(exchange)) { logException(exchange, e); } exchange.setException(e); } finally { // ensure callback is always invoked callback.done(doneSync); } } }); } catch (Throwable e) { // some exception occurred in trace logic if (shouldLogException(exchange)) { logException(exchange, e); } exchange.setException(e); } return sync; }
/** Returns true if the given exchange should be logged in the trace list */ protected boolean shouldLogExchange(Exchange exchange) { return tracer.isEnabled() && (tracer.getTraceFilter() == null || tracer.getTraceFilter().matches(exchange)); }