Search in sources :

Example 1 with TracedRouteNodes

use of org.apache.camel.spi.TracedRouteNodes in project camel by apache.

the class MulticastProcessor method doProcessParallel.

private void doProcessParallel(final ProcessorExchangePair pair) throws Exception {
    final Exchange exchange = pair.getExchange();
    Processor processor = pair.getProcessor();
    Producer producer = pair.getProducer();
    TracedRouteNodes traced = exchange.getUnitOfWork() != null ? exchange.getUnitOfWork().getTracedRouteNodes() : null;
    // compute time taken if sending to another endpoint
    StopWatch watch = null;
    if (producer != null) {
        watch = new StopWatch();
    }
    try {
        // prepare tracing starting from a new block
        if (traced != null) {
            traced.pushBlock();
        }
        if (producer != null) {
            EventHelper.notifyExchangeSending(exchange.getContext(), exchange, producer.getEndpoint());
        }
        // let the prepared process it, remember to begin the exchange pair
        AsyncProcessor async = AsyncProcessorConverterHelper.convert(processor);
        pair.begin();
        // we invoke it synchronously as parallel async routing is too hard
        AsyncProcessorHelper.process(async, exchange);
    } finally {
        pair.done();
        // pop the block so by next round we have the same staring point and thus the tracing looks accurate
        if (traced != null) {
            traced.popBlock();
        }
        if (producer != null) {
            long timeTaken = watch.stop();
            Endpoint endpoint = producer.getEndpoint();
            // emit event that the exchange was sent to the endpoint
            // this is okay to do here in the finally block, as the processing is not using the async routing engine
            //( we invoke it synchronously as parallel async routing is too hard)
            EventHelper.notifyExchangeSent(exchange.getContext(), exchange, endpoint, timeTaken);
        }
    }
}
Also used : AtomicExchange(org.apache.camel.util.concurrent.AtomicExchange) Exchange(org.apache.camel.Exchange) AsyncProcessor(org.apache.camel.AsyncProcessor) Processor(org.apache.camel.Processor) Producer(org.apache.camel.Producer) Endpoint(org.apache.camel.Endpoint) AsyncProcessor(org.apache.camel.AsyncProcessor) TracedRouteNodes(org.apache.camel.spi.TracedRouteNodes) StopWatch(org.apache.camel.util.StopWatch)

Example 2 with TracedRouteNodes

use of org.apache.camel.spi.TracedRouteNodes in project camel by apache.

the class DefaultTraceFormatter method extractBreadCrumb.

/**
     * Creates the breadcrumb based on whether this was a trace of
     * an exchange coming out of or into a processing step. For example, 
     * <br/><tt>transform(body) -> ID-mojo/39713-1225468755256/2-0</tt>
     * <br/>or
     * <br/><tt>ID-mojo/39713-1225468755256/2-0 -> transform(body)</tt>
     */
protected String extractBreadCrumb(TraceInterceptor interceptor, ProcessorDefinition<?> currentNode, Exchange exchange) {
    String id = "";
    String result;
    if (!showBreadCrumb && !showExchangeId && !showShortExchangeId && !showNode) {
        return "";
    }
    // compute breadcrumb id
    if (showBreadCrumb) {
        id = getBreadCrumbID(exchange).toString();
    } else if (showExchangeId || showShortExchangeId) {
        id = getBreadCrumbID(exchange).toString();
        if (showShortExchangeId) {
            // only output last part of id
            id = id.substring(id.lastIndexOf('-') + 1);
        }
    }
    // compute from, to and route
    String from = "";
    String to = "";
    String route = "";
    if (showNode || showRouteId) {
        if (exchange.getUnitOfWork() != null) {
            TracedRouteNodes traced = exchange.getUnitOfWork().getTracedRouteNodes();
            RouteNode traceFrom = traced.getSecondLastNode();
            if (traceFrom != null) {
                from = getNodeMessage(traceFrom, exchange);
            } else if (exchange.getFromEndpoint() != null) {
                from = "from(" + exchange.getFromEndpoint().getEndpointUri() + ")";
            }
            RouteNode traceTo = traced.getLastNode();
            if (traceTo != null) {
                to = getNodeMessage(traceTo, exchange);
                // information which route it belongs to
                if (traceTo.isAbstract() && traceTo.getProcessorDefinition() == null) {
                    traceTo = traced.getSecondLastNode();
                }
                if (traceTo != null) {
                    route = extractRoute(traceTo.getProcessorDefinition());
                }
            }
        }
    }
    // assemble result with and without the to/from
    if (showNode) {
        if (showRouteId && route != null) {
            result = id.trim() + " >>> (" + route + ") " + from + " --> " + to.trim() + " <<< ";
        } else {
            result = id.trim() + " >>> " + from + " --> " + to.trim() + " <<< ";
        }
        if (interceptor.shouldTraceOutExchanges() && exchange.hasOut()) {
            result += " (OUT) ";
        }
    } else {
        result = id;
    }
    if (breadCrumbLength > 0) {
        // we want to ensure text coming after this is aligned for readability
        return String.format("%1$-" + breadCrumbLength + "." + breadCrumbLength + "s", result.trim());
    } else {
        return result.trim();
    }
}
Also used : RouteNode(org.apache.camel.RouteNode) TracedRouteNodes(org.apache.camel.spi.TracedRouteNodes)

Example 3 with TracedRouteNodes

use of org.apache.camel.spi.TracedRouteNodes in project camel by apache.

the class MulticastProcessor method doProcessSequential.

private boolean doProcessSequential(final Exchange original, final AtomicExchange result, final Iterable<ProcessorExchangePair> pairs, final Iterator<ProcessorExchangePair> it, final ProcessorExchangePair pair, final AsyncCallback callback, final AtomicInteger total) {
    boolean sync = true;
    final Exchange exchange = pair.getExchange();
    Processor processor = pair.getProcessor();
    final Producer producer = pair.getProducer();
    TracedRouteNodes traced = exchange.getUnitOfWork() != null ? exchange.getUnitOfWork().getTracedRouteNodes() : null;
    // compute time taken if sending to another endpoint
    final StopWatch watch = producer != null ? new StopWatch() : null;
    try {
        // prepare tracing starting from a new block
        if (traced != null) {
            traced.pushBlock();
        }
        if (producer != null) {
            EventHelper.notifyExchangeSending(exchange.getContext(), exchange, producer.getEndpoint());
        }
        // let the prepared process it, remember to begin the exchange pair
        AsyncProcessor async = AsyncProcessorConverterHelper.convert(processor);
        pair.begin();
        sync = async.process(exchange, new AsyncCallback() {

            public void done(boolean doneSync) {
                // we are done with the exchange pair
                pair.done();
                // okay we are done, so notify the exchange was sent
                if (producer != null) {
                    long timeTaken = watch.stop();
                    Endpoint endpoint = producer.getEndpoint();
                    // emit event that the exchange was sent to the endpoint
                    EventHelper.notifyExchangeSent(exchange.getContext(), exchange, endpoint, timeTaken);
                }
                // we only have to handle async completion of the routing slip
                if (doneSync) {
                    return;
                }
                // continue processing the multicast asynchronously
                Exchange subExchange = exchange;
                // Decide whether to continue with the multicast or not; similar logic to the Pipeline
                // remember to test for stop on exception and aggregate before copying back results
                boolean continueProcessing = PipelineHelper.continueProcessing(subExchange, "Sequential processing failed for number " + total.get(), LOG);
                if (stopOnException && !continueProcessing) {
                    if (subExchange.getException() != null) {
                        // wrap in exception to explain where it failed
                        subExchange.setException(new CamelExchangeException("Sequential processing failed for number " + total, subExchange, subExchange.getException()));
                    } else {
                        // we want to stop on exception, and the exception was handled by the error handler
                        // this is similar to what the pipeline does, so we should do the same to not surprise end users
                        // so we should set the failed exchange as the result and be done
                        result.set(subExchange);
                    }
                    // and do the done work
                    doDone(original, subExchange, pairs, callback, false, true);
                    return;
                }
                try {
                    if (parallelAggregate) {
                        doAggregateInternal(getAggregationStrategy(subExchange), result, subExchange);
                    } else {
                        doAggregate(getAggregationStrategy(subExchange), result, subExchange);
                    }
                } catch (Throwable e) {
                    // wrap in exception to explain where it failed
                    subExchange.setException(new CamelExchangeException("Sequential processing failed for number " + total, subExchange, e));
                    // and do the done work
                    doDone(original, subExchange, pairs, callback, false, true);
                    return;
                }
                total.incrementAndGet();
                // maybe there are more processors to multicast
                while (it.hasNext()) {
                    // prepare and run the next
                    ProcessorExchangePair pair = it.next();
                    subExchange = pair.getExchange();
                    updateNewExchange(subExchange, total.get(), pairs, it);
                    boolean sync = doProcessSequential(original, result, pairs, it, pair, callback, total);
                    if (!sync) {
                        LOG.trace("Processing exchangeId: {} is continued being processed asynchronously", original.getExchangeId());
                        return;
                    }
                    // Decide whether to continue with the multicast or not; similar logic to the Pipeline
                    // remember to test for stop on exception and aggregate before copying back results
                    continueProcessing = PipelineHelper.continueProcessing(subExchange, "Sequential processing failed for number " + total.get(), LOG);
                    if (stopOnException && !continueProcessing) {
                        if (subExchange.getException() != null) {
                            // wrap in exception to explain where it failed
                            subExchange.setException(new CamelExchangeException("Sequential processing failed for number " + total, subExchange, subExchange.getException()));
                        } else {
                            // we want to stop on exception, and the exception was handled by the error handler
                            // this is similar to what the pipeline does, so we should do the same to not surprise end users
                            // so we should set the failed exchange as the result and be done
                            result.set(subExchange);
                        }
                        // and do the done work
                        doDone(original, subExchange, pairs, callback, false, true);
                        return;
                    }
                    // must catch any exceptions from aggregation
                    try {
                        if (parallelAggregate) {
                            doAggregateInternal(getAggregationStrategy(subExchange), result, subExchange);
                        } else {
                            doAggregate(getAggregationStrategy(subExchange), result, subExchange);
                        }
                    } catch (Throwable e) {
                        // wrap in exception to explain where it failed
                        subExchange.setException(new CamelExchangeException("Sequential processing failed for number " + total, subExchange, e));
                        // and do the done work
                        doDone(original, subExchange, pairs, callback, false, true);
                        return;
                    }
                    total.incrementAndGet();
                }
                // do the done work
                subExchange = result.get() != null ? result.get() : null;
                doDone(original, subExchange, pairs, callback, false, true);
            }
        });
    } finally {
        // pop the block so by next round we have the same staring point and thus the tracing looks accurate
        if (traced != null) {
            traced.popBlock();
        }
    }
    return sync;
}
Also used : CamelExchangeException(org.apache.camel.CamelExchangeException) AsyncProcessor(org.apache.camel.AsyncProcessor) Processor(org.apache.camel.Processor) AsyncCallback(org.apache.camel.AsyncCallback) StopWatch(org.apache.camel.util.StopWatch) AtomicExchange(org.apache.camel.util.concurrent.AtomicExchange) Exchange(org.apache.camel.Exchange) Producer(org.apache.camel.Producer) Endpoint(org.apache.camel.Endpoint) AsyncProcessor(org.apache.camel.AsyncProcessor) TracedRouteNodes(org.apache.camel.spi.TracedRouteNodes)

Example 4 with TracedRouteNodes

use of org.apache.camel.spi.TracedRouteNodes in project camel by apache.

the class TraceInterceptor method process.

@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);
    }
    // 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;
}
Also used : CatchDefinition(org.apache.camel.model.CatchDefinition) AsyncCallback(org.apache.camel.AsyncCallback) OnCompletionDefinition(org.apache.camel.model.OnCompletionDefinition) OnExceptionDefinition(org.apache.camel.model.OnExceptionDefinition) AggregateDefinition(org.apache.camel.model.AggregateDefinition) TracedRouteNodes(org.apache.camel.spi.TracedRouteNodes) DefaultRouteNode(org.apache.camel.impl.DefaultRouteNode) InterceptDefinition(org.apache.camel.model.InterceptDefinition)

Example 5 with TracedRouteNodes

use of org.apache.camel.spi.TracedRouteNodes in project camel by apache.

the class DefaultTraceEventMessage method extractFromNode.

private static String extractFromNode(Exchange exchange) {
    if (exchange.getUnitOfWork() != null) {
        TracedRouteNodes traced = exchange.getUnitOfWork().getTracedRouteNodes();
        RouteNode last = traced.getSecondLastNode();
        return last != null ? last.getLabel(exchange) : null;
    }
    return null;
}
Also used : RouteNode(org.apache.camel.RouteNode) TracedRouteNodes(org.apache.camel.spi.TracedRouteNodes)

Aggregations

TracedRouteNodes (org.apache.camel.spi.TracedRouteNodes)6 RouteNode (org.apache.camel.RouteNode)3 AsyncCallback (org.apache.camel.AsyncCallback)2 AsyncProcessor (org.apache.camel.AsyncProcessor)2 Endpoint (org.apache.camel.Endpoint)2 Exchange (org.apache.camel.Exchange)2 Processor (org.apache.camel.Processor)2 Producer (org.apache.camel.Producer)2 StopWatch (org.apache.camel.util.StopWatch)2 AtomicExchange (org.apache.camel.util.concurrent.AtomicExchange)2 CamelExchangeException (org.apache.camel.CamelExchangeException)1 DefaultRouteNode (org.apache.camel.impl.DefaultRouteNode)1 AggregateDefinition (org.apache.camel.model.AggregateDefinition)1 CatchDefinition (org.apache.camel.model.CatchDefinition)1 InterceptDefinition (org.apache.camel.model.InterceptDefinition)1 OnCompletionDefinition (org.apache.camel.model.OnCompletionDefinition)1 OnExceptionDefinition (org.apache.camel.model.OnExceptionDefinition)1