You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2020/07/20 06:53:18 UTC

[camel] branch master updated: CAMEL-15260 - Adds tracing strategy to enable spans for each processor (#4001)

This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new d556723  CAMEL-15260 - Adds tracing strategy to enable spans for each processor (#4001)
d556723 is described below

commit d55672303f89e8e5d42c95dc069b1bd6339a44a7
Author: Jose Montoya <ja...@users.noreply.github.com>
AuthorDate: Mon Jul 20 01:53:00 2020 -0500

    CAMEL-15260 - Adds tracing strategy to enable spans for each processor (#4001)
    
    * opentracing: refactor to create single server span, add tracing strategy
    
    refactored to not create multiple client-server spans
    adds a tracing strategy that adds spans for each processor and opens
    scopes between processors to enable other instrumentation
    
    * checkstyle
    
    * opentracing: reintroduces event notifier
    
    Reintroduces the event notifier but skips creating client spans for
    internal endpoints
    
    * opentracing: cleanup
    
    moves members to original order
    
    * opentracing: activates processor spans in exchange
    
    Uses ActiveSpanManager to keep track of active processor spans. This
    allows to create trees of processors and other span creation to be made
    under the active processor directly and not the route.
    
    * opentracing: remove server tag from in-process endpoints
    
    * opentracing: camel prefix on processor component tag
    
    * opentracing: ability to exclude processors from tracing
    
    * opentracing: delete old byteman rule
    
    The Java agent no longer use byteman rules
    
    * opentracing: update doc to reference specialagent
    
    * opentracing: refactor exclusing processors
    
    * opentracing: match error logs
    
    * opentracing: fixes processors test
    
    * opentracing: adapt to junit 5
---
 components/camel-opentracing/pom.xml               |  14 +++
 .../src/main/docs/opentracing.adoc                 |   2 +-
 .../camel/opentracing/NoopTracingStrategy.java     |  32 ++++++
 .../camel/opentracing/OpenTracingTracer.java       |  50 ++++++++-
 .../opentracing/OpenTracingTracingStrategy.java    | 119 +++++++++++++++++++++
 .../src/main/resources/otarules.btm                |  32 ------
 .../org/apache/camel/opentracing/ABCRouteTest.java |  16 +--
 .../opentracing/CamelOpenTracingTestSupport.java   |  47 ++++++--
 .../opentracing/ClientRecipientListRouteTest.java  |  15 +--
 .../opentracing/CustomComponentNameRouteTest.java  |  15 +--
 .../opentracing/EIPTracingActiveSpanTest.java      |  80 ++++++++++++++
 .../camel/opentracing/EIPTracingRouteTest.java     | 102 ++++++++++++++++++
 .../opentracing/MulticastParallelRouteTest.java    |  15 +--
 .../camel/opentracing/MulticastRouteTest.java      |  15 +--
 .../OpentracingSpanCollectorInRegistryTest.java    |   7 ++
 .../camel/opentracing/RouteConcurrentTest.java     |   9 +-
 .../camel/opentracing/SpanProcessorsTest.java      |  15 +--
 .../SpringOpenTracingSimpleRouteTest.java          |   4 +-
 ...va => TracingClientRecipientListRouteTest.java} |  49 +++++----
 .../TracingMulticastParallelRouteTest.java         |  99 +++++++++++++++++
 .../apache/camel/opentracing/TwoServiceTest.java   |   7 +-
 .../opentracing/TwoServiceWithExcludeTest.java     |   3 -
 22 files changed, 590 insertions(+), 157 deletions(-)

diff --git a/components/camel-opentracing/pom.xml b/components/camel-opentracing/pom.xml
index daea749..df3e2e6 100644
--- a/components/camel-opentracing/pom.xml
+++ b/components/camel-opentracing/pom.xml
@@ -45,6 +45,12 @@
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-support</artifactId>
         </dependency>
+        <!-- added to bypass LogProcessor -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-base</artifactId>
+            <scope>provided</scope>
+        </dependency>
 
         <!-- OpenTracing -->
         <dependency>
@@ -54,6 +60,13 @@
         </dependency>
         <dependency>
             <groupId>io.opentracing</groupId>
+            <artifactId>opentracing-util</artifactId>
+            <version>${opentracing-version}</version>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>io.opentracing</groupId>
             <artifactId>opentracing-noop</artifactId>
             <version>${opentracing-version}</version>
         </dependency>
@@ -75,6 +88,7 @@
             <artifactId>opentracing-util</artifactId>
             <version>${opentracing-version}</version>
             <scope>test</scope>
+            <type>test-jar</type>
         </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
diff --git a/components/camel-opentracing/src/main/docs/opentracing.adoc b/components/camel-opentracing/src/main/docs/opentracing.adoc
index e66884b..17f69a8 100644
--- a/components/camel-opentracing/src/main/docs/opentracing.adoc
+++ b/components/camel-opentracing/src/main/docs/opentracing.adoc
@@ -83,7 +83,7 @@ The OpenTracing Java Agent is associated with the following dependency:
 ---------------------------------------------------------------------------------------------------------
     <dependency>
       <groupId>io.opentracing.contrib</groupId>
-      <artifactId>opentracing-agent</artifactId>
+      <artifactId>opentracing-specialagent</artifactId>
     </dependency>
 ---------------------------------------------------------------------------------------------------------
 
diff --git a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/NoopTracingStrategy.java b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/NoopTracingStrategy.java
new file mode 100644
index 0000000..6cbc051
--- /dev/null
+++ b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/NoopTracingStrategy.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.opentracing;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.NamedNode;
+import org.apache.camel.Processor;
+import org.apache.camel.spi.InterceptStrategy;
+import org.apache.camel.support.processor.DelegateAsyncProcessor;
+
+public class NoopTracingStrategy implements InterceptStrategy {
+
+    @Override
+    public Processor wrapProcessorInInterceptors(CamelContext camelContext, NamedNode processorDefinition,
+                                                 Processor target, Processor nextTarget) throws Exception {
+        return new DelegateAsyncProcessor(target);
+    }
+}
diff --git a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/OpenTracingTracer.java b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/OpenTracingTracer.java
index 822b654..5e3b259 100644
--- a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/OpenTracingTracer.java
+++ b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/OpenTracingTracer.java
@@ -40,10 +40,12 @@ import org.apache.camel.Route;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.StaticService;
 import org.apache.camel.api.management.ManagedResource;
+import org.apache.camel.opentracing.decorators.AbstractInternalSpanDecorator;
 import org.apache.camel.spi.CamelEvent;
 import org.apache.camel.spi.CamelEvent.ExchangeSendingEvent;
 import org.apache.camel.spi.CamelEvent.ExchangeSentEvent;
 import org.apache.camel.spi.CamelLogger;
+import org.apache.camel.spi.InterceptStrategy;
 import org.apache.camel.spi.LogListener;
 import org.apache.camel.spi.RoutePolicy;
 import org.apache.camel.spi.RoutePolicyFactory;
@@ -79,7 +81,8 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact
     private final OpenTracingLogListener logListener = new OpenTracingLogListener();
     private Tracer tracer;
     private CamelContext camelContext;
-    private Set<String> excludePatterns = new HashSet<>();
+    private Set<String> excludePatterns = new HashSet<>(0);
+    private InterceptStrategy tracingStrategy;
     private boolean encoding;
 
     static {
@@ -137,6 +140,25 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact
         this.camelContext = camelContext;
     }
 
+    /**
+     * Returns the currently used tracing strategy which is responsible for tracking invoked EIP or
+     * beans.
+     *
+     * @return The currently used tracing strategy
+     */
+    public InterceptStrategy getTracingStrategy() {
+        return tracingStrategy;
+    }
+
+    /**
+     * Specifies the instance responsible for tracking invoked EIP and beans with OpenTracing.
+     *
+     * @param tracingStrategy The instance which tracks invoked EIP and beans
+     */
+    public void setTracingStrategy(InterceptStrategy tracingStrategy) {
+        this.tracingStrategy = tracingStrategy;
+    }
+
     public Set<String> getExcludePatterns() {
         return excludePatterns;
     }
@@ -181,6 +203,10 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact
         }
         camelContext.adapt(ExtendedCamelContext.class).addLogListener(logListener);
 
+        if (tracingStrategy != null) {
+            camelContext.adapt(ExtendedCamelContext.class).addInterceptStrategy(tracingStrategy);
+        }
+
         if (tracer == null) {
             Set<Tracer> tracers = camelContext.getRegistry().findByType(Tracer.class);
             if (tracers.size() == 1) {
@@ -198,6 +224,14 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact
         }
 
         ServiceHelper.startService(eventNotifier);
+
+        if (tracer != null) {
+            try { // Take care NOT to import GlobalTracer as it is an optional dependency and may not be on the classpath.
+                io.opentracing.util.GlobalTracer.registerIfAbsent(tracer);
+            } catch (NoClassDefFoundError globalTracerNotInClasspath) {
+                LOG.trace("GlobalTracer is not found on the classpath.");
+            }
+        }
     }
 
     @Override
@@ -255,7 +289,7 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact
                 if (event instanceof ExchangeSendingEvent) {
                     ExchangeSendingEvent ese = (ExchangeSendingEvent)event;
                     SpanDecorator sd = getSpanDecorator(ese.getEndpoint());
-                    if (!sd.newSpan() || isExcluded(ese.getExchange(), ese.getEndpoint())) {
+                    if (sd instanceof AbstractInternalSpanDecorator || !sd.newSpan() || isExcluded(ese.getExchange(), ese.getEndpoint())) {
                         return;
                     }
                     Span parent = ActiveSpanManager.getSpan(ese.getExchange());
@@ -277,7 +311,7 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact
                 } else if (event instanceof ExchangeSentEvent) {
                     ExchangeSentEvent ese = (ExchangeSentEvent)event;
                     SpanDecorator sd = getSpanDecorator(ese.getEndpoint());
-                    if (!sd.newSpan() || isExcluded(ese.getExchange(), ese.getEndpoint())) {
+                    if (sd instanceof AbstractInternalSpanDecorator || !sd.newSpan() || isExcluded(ese.getExchange(), ese.getEndpoint())) {
                         return;
                     }
                     Span span = ActiveSpanManager.getSpan(ese.getExchange());
@@ -321,9 +355,15 @@ public class OpenTracingTracer extends ServiceSupport implements RoutePolicyFact
                     return;
                 }
                 SpanDecorator sd = getSpanDecorator(route.getEndpoint());
+                Span parent = ActiveSpanManager.getSpan(exchange);
                 Span span = tracer.buildSpan(sd.getOperationName(exchange, route.getEndpoint()))
-                    .asChildOf(tracer.extract(Format.Builtin.TEXT_MAP, sd.getExtractAdapter(exchange.getIn().getHeaders(), encoding)))
-                    .withTag(Tags.SPAN_KIND.getKey(), sd.getReceiverSpanKind()).start();
+                    .asChildOf(parent)
+                    .start();
+
+                if (parent == null && !(sd instanceof AbstractInternalSpanDecorator)) {
+                    span.setTag(Tags.SPAN_KIND.getKey(), sd.getReceiverSpanKind());
+                }
+
                 sd.pre(span, exchange, route.getEndpoint());
                 ActiveSpanManager.activate(exchange, span);
                 if (LOG.isTraceEnabled()) {
diff --git a/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/OpenTracingTracingStrategy.java b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/OpenTracingTracingStrategy.java
new file mode 100644
index 0000000..2112e4c
--- /dev/null
+++ b/components/camel-opentracing/src/main/java/org/apache/camel/opentracing/OpenTracingTracingStrategy.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.opentracing;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import io.opentracing.Scope;
+import io.opentracing.Span;
+import io.opentracing.tag.Tags;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.NamedNode;
+import org.apache.camel.Processor;
+import org.apache.camel.processor.LogProcessor;
+import org.apache.camel.spi.InterceptStrategy;
+import org.apache.camel.support.PatternHelper;
+import org.apache.camel.support.processor.DelegateAsyncProcessor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class OpenTracingTracingStrategy implements InterceptStrategy {
+
+    private static final Logger LOG = LoggerFactory.getLogger(OpenTracingTracingStrategy.class);
+    private static final String UNNAMED = "unnamed";
+    private final OpenTracingTracer tracer;
+
+    public OpenTracingTracingStrategy(OpenTracingTracer tracer) {
+        this.tracer = tracer;
+    }
+
+    @Override
+    public Processor wrapProcessorInInterceptors(CamelContext camelContext,
+                                                 NamedNode processorDefinition, Processor target, Processor nextTarget)
+            throws Exception {
+        if (!shouldTrace(processorDefinition)) {
+            return new DelegateAsyncProcessor(target);
+        }
+
+        return new DelegateAsyncProcessor((Exchange exchange) -> {
+            Span span = ActiveSpanManager.getSpan(exchange);
+            if (span == null) {
+                target.process(exchange);
+                return;
+            }
+
+            final Span processorSpan = tracer.getTracer().buildSpan(getOperationName(processorDefinition))
+                    .asChildOf(span)
+                    .withTag(Tags.COMPONENT, getComponentName(processorDefinition))
+                    .start();
+
+            boolean activateExchange = !(target instanceof LogProcessor
+                    || target instanceof TagProcessor
+                    || target instanceof GetBaggageProcessor
+                    || target instanceof SetBaggageProcessor);
+
+            if (activateExchange) {
+                ActiveSpanManager.activate(exchange, processorSpan);
+            }
+
+            try (final Scope inScope = tracer.getTracer().activateSpan(processorSpan)) {
+                target.process(exchange);
+            } catch (Exception ex) {
+                processorSpan.log(errorLogs(ex));
+                throw ex;
+            } finally {
+                if (activateExchange) {
+                    ActiveSpanManager.deactivate(exchange);
+                }
+
+                processorSpan.finish();
+            }
+        });
+    }
+    
+    private static String getComponentName(NamedNode processorDefinition) {
+        return SpanDecorator.CAMEL_COMPONENT + processorDefinition.getShortName();
+    }
+
+    private static String getOperationName(NamedNode processorDefinition) {
+        final String name = processorDefinition.getId();
+        return name == null ? UNNAMED : name;
+    }
+
+    private static Map<String, Object> errorLogs(final Throwable t) {
+        final Map<String, Object> logEvent = new HashMap<>(3);
+        logEvent.put("event", Tags.ERROR.getKey());
+        logEvent.put("error.kind", "Exception");
+        logEvent.put("message", t.getMessage());
+        return logEvent;
+    }
+
+    // Adapted from org.apache.camel.impl.engine.DefaultTracer.shouldTrace
+    // org.apache.camel.impl.engine.DefaultTracer.shouldTracePattern
+    private boolean shouldTrace(NamedNode definition) {
+        for (String pattern : tracer.getExcludePatterns()) {
+            // use matchPattern method from endpoint helper that has a good matcher we use in Camel
+            if (PatternHelper.matchPattern(definition.getId(), pattern)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+}
diff --git a/components/camel-opentracing/src/main/resources/otarules.btm b/components/camel-opentracing/src/main/resources/otarules.btm
deleted file mode 100644
index 609153b..0000000
--- a/components/camel-opentracing/src/main/resources/otarules.btm
+++ /dev/null
@@ -1,32 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-#  this work for additional information regarding copyright ownership.
-#  The ASF licenses this file to You under the Apache License, Version 2.0
-#  (the "License"); you may not use this file except in compliance with
-#  the License.  You may obtain a copy of the License at
-#
-#       http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-#
-
-# State 0 - camel context not initialized
-# State 1 - camel context initialized
-
-RULE apache-camel: Install OpenTracing tracer
-CLASS org.apache.camel.impl.DefaultCamelContext
-METHOD startRouteDefinitions
-HELPER io.opentracing.contrib.agent.OpenTracingHelper
-BIND
-  ottracer:org.apache.camel.opentracing.OpenTracingTracer = new org.apache.camel.opentracing.OpenTracingTracer();
-AT ENTRY
-IF getState($0) == 0
-DO
-  ottracer.init($0);
-  setState($0, 1);
-ENDRULE
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ABCRouteTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ABCRouteTest.java
index 20d9ff3..9e9ad8d 100644
--- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ABCRouteTest.java
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ABCRouteTest.java
@@ -19,27 +19,19 @@ package org.apache.camel.opentracing;
 import io.opentracing.tag.Tags;
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spi.InterceptStrategy;
 import org.junit.jupiter.api.Test;
 
 public class ABCRouteTest extends CamelOpenTracingTestSupport {
 
     private static SpanTestData[] testdata = {
         new SpanTestData().setLabel("seda:b server").setUri("seda://b").setOperation("b")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(1).addLogMessage("routing at b"),
-        new SpanTestData().setLabel("seda:b client").setUri("seda://b").setOperation("b")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4),
+            .setParentId(2).addLogMessage("routing at b"),
         new SpanTestData().setLabel("seda:c server").setUri("seda://c").setOperation("c")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(3).addLogMessage("Exchange[ExchangePattern: InOut, BodyType: String, Body: Hello]"),
-        new SpanTestData().setLabel("seda:c client").setUri("seda://c").setOperation("c")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4),
+            .setParentId(2).addLogMessage("Exchange[ExchangePattern: InOut, BodyType: String, Body: Hello]"),
         new SpanTestData().setLabel("seda:a server").setUri("seda://a").setOperation("a")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(5).addLogMessage("routing at a").addLogMessage("End of routing"),
-        new SpanTestData().setLabel("seda:a client").setUri("seda://a").setOperation("a")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(6),
+            .setParentId(3).addLogMessage("routing at a").addLogMessage("End of routing"),
         new SpanTestData().setLabel("direct:start server").setUri("direct://start").setOperation("start")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(7),
-        new SpanTestData().setLabel("direct:start client").setUri("direct://start").setOperation("start")
-            .setKind(Tags.SPAN_KIND_CLIENT)
     };
 
     public ABCRouteTest() {
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/CamelOpenTracingTestSupport.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/CamelOpenTracingTestSupport.java
index 84df2b6..9c598e3 100644
--- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/CamelOpenTracingTestSupport.java
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/CamelOpenTracingTestSupport.java
@@ -32,6 +32,7 @@ import io.opentracing.mock.MockTracer;
 import io.opentracing.mock.MockTracer.Propagator;
 import io.opentracing.tag.Tags;
 import org.apache.camel.CamelContext;
+import org.apache.camel.spi.InterceptStrategy;
 import org.apache.camel.test.junit5.CamelTestSupport;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -40,8 +41,8 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class CamelOpenTracingTestSupport extends CamelTestSupport {
 
+    protected OpenTracingTracer ottracer;
     private MockTracer tracer;
-
     private SpanTestData[] testdata;
 
     public CamelOpenTracingTestSupport(SpanTestData[] testdata) {
@@ -59,9 +60,10 @@ public class CamelOpenTracingTestSupport extends CamelTestSupport {
 
         tracer = new MockTracer(Propagator.TEXT_MAP);
 
-        OpenTracingTracer ottracer = new OpenTracingTracer();
+        this.ottracer = new OpenTracingTracer();
         ottracer.setTracer(tracer);
         ottracer.setExcludePatterns(getExcludePatterns());
+        ottracer.setTracingStrategy(getTracingStrategy());
 
         ottracer.init(context);
 
@@ -81,14 +83,24 @@ public class CamelOpenTracingTestSupport extends CamelTestSupport {
     }
 
     protected void verify(boolean async) {
+        List<MockSpan> spans = tracer.finishedSpans();
+        spans.forEach(mockSpan -> {
+            System.out.println("Span: " + mockSpan);
+            System.out.println("\tComponent: " + mockSpan.tags().get(Tags.COMPONENT.getKey()));
+            System.out.println("\tTags: " + mockSpan.tags());
+            System.out.println("\tLogs: ");
+            for (final MockSpan.LogEntry logEntry : mockSpan.logEntries()) {
+                System.out.println("\t" + logEntry.fields());
+            }
+        });
+
         assertEquals(testdata.length, tracer.finishedSpans().size(), "Incorrect number of spans");
 
         verifySameTrace();
 
-        List<MockSpan> spans = tracer.finishedSpans();
         if (async) {
             final List<MockSpan> unsortedSpans = spans;
-            spans = Arrays.asList(testdata).stream()
+            spans = Arrays.stream(testdata)
                     .map(td -> findSpan(td, unsortedSpans)).distinct().collect(Collectors.toList());
             assertEquals(testdata.length, spans.size(), "Incorrect number of spans after sorting");
         }
@@ -99,18 +111,32 @@ public class CamelOpenTracingTestSupport extends CamelTestSupport {
     }
 
     protected MockSpan findSpan(SpanTestData testdata, List<MockSpan> spans) {
-        return spans.stream().filter(s -> s.operationName().equals(testdata.getOperation())
-                && s.tags().get("camel.uri").equals(testdata.getUri())
-                && s.tags().get(Tags.SPAN_KIND.getKey()).equals(testdata.getKind())).findFirst().orElse(null);
+        return spans.stream().filter(s -> {
+            boolean matched = s.operationName().equals(testdata.getOperation());
+
+            if (s.tags().containsKey("camel-uri")) {
+                matched = matched && s.tags().get("camel.uri").equals(testdata.getUri());
+            }
+
+            if (s.tags().containsKey(Tags.SPAN_KIND.getKey())) {
+                matched = matched && s.tags().get(Tags.SPAN_KIND.getKey()).equals(testdata.getKind());
+            }
+
+            return matched;
+        }).findFirst().orElse(null);
     }
 
     protected void verifySpan(int index, SpanTestData[] testdata, List<MockSpan> spans) {
         MockSpan span = spans.get(index);
         SpanTestData td = testdata[index];
 
+
         String component = (String) span.tags().get(Tags.COMPONENT.getKey());
         assertNotNull(component);
-        assertEquals(SpanDecorator.CAMEL_COMPONENT + URI.create(td.getUri()).getScheme(), component, td.getLabel());
+
+        if (td.getUri() != null) {
+            assertEquals(SpanDecorator.CAMEL_COMPONENT + URI.create(td.getUri()).getScheme(), component, td.getLabel());
+        }
         assertEquals(td.getUri(), span.tags().get("camel.uri"), td.getLabel());
 
         // If span associated with TestSEDASpanDecorator, check that pre/post tags have been defined
@@ -128,7 +154,7 @@ public class CamelOpenTracingTestSupport extends CamelTestSupport {
         }
 
         if (!td.getLogMessages().isEmpty()) {
-            assertEquals(td.getLogMessages().size(), span.logEntries().size(), "Number of log messages");
+            assertEquals(td.getLogMessages().size(), span.logEntries().size(), td.getLabel());
             for (int i = 0; i < td.getLogMessages().size(); i++) {
                 assertEquals(td.getLogMessages().get(i), span.logEntries().get(i).fields().get("message"));
             }
@@ -171,4 +197,7 @@ public class CamelOpenTracingTestSupport extends CamelTestSupport {
         }
     }
 
+    protected InterceptStrategy getTracingStrategy() {
+        return new NoopTracingStrategy();
+    }
 }
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ClientRecipientListRouteTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ClientRecipientListRouteTest.java
index 3ef2549..c5f7cb9 100644
--- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ClientRecipientListRouteTest.java
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ClientRecipientListRouteTest.java
@@ -25,21 +25,12 @@ public class ClientRecipientListRouteTest extends CamelOpenTracingTestSupport {
 
     private static SpanTestData[] testdata = {
         new SpanTestData().setLabel("seda:a server").setUri("seda://a").setOperation("a")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(1),
-        new SpanTestData().setLabel("seda:a client").setUri("seda://a").setOperation("a")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(6),
+            .setParentId(3),
         new SpanTestData().setLabel("seda:b server").setUri("seda://b").setOperation("b")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(3),
-        new SpanTestData().setLabel("seda:b client").setUri("seda://b").setOperation("b")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(6),
+            .setParentId(3),
         new SpanTestData().setLabel("seda:c server").setUri("seda://c").setOperation("c")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(5),
-        new SpanTestData().setLabel("seda:c client").setUri("seda://c").setOperation("c")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(6),
+            .setParentId(3),
         new SpanTestData().setLabel("direct:start server").setUri("direct://start").setOperation("start")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(7),
-        new SpanTestData().setLabel("direct:start client").setUri("direct://start").setOperation("start")
-            .setKind(Tags.SPAN_KIND_CLIENT)
     };
 
     public ClientRecipientListRouteTest() {
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/CustomComponentNameRouteTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/CustomComponentNameRouteTest.java
index c9dc292..8912d05 100644
--- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/CustomComponentNameRouteTest.java
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/CustomComponentNameRouteTest.java
@@ -25,21 +25,12 @@ public class CustomComponentNameRouteTest extends CamelOpenTracingTestSupport {
 
     private static SpanTestData[] testdata = {
         new SpanTestData().setLabel("myseda:b server").setUri("myseda://b").setOperation("b")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(1).addLogMessage("routing at b"),
-        new SpanTestData().setLabel("myseda:b client").setUri("myseda://b").setOperation("b")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4),
+            .setParentId(2).addLogMessage("routing at b"),
         new SpanTestData().setLabel("myseda:c server").setUri("myseda://c").setOperation("c")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(3).addLogMessage("Exchange[ExchangePattern: InOut, BodyType: String, Body: Hello]"),
-        new SpanTestData().setLabel("myseda:c client").setUri("myseda://c").setOperation("c")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4),
+            .setParentId(2).addLogMessage("Exchange[ExchangePattern: InOut, BodyType: String, Body: Hello]"),
         new SpanTestData().setLabel("myseda:a server").setUri("myseda://a").setOperation("a")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(5).addLogMessage("routing at a").addLogMessage("End of routing"),
-        new SpanTestData().setLabel("myseda:a client").setUri("myseda://a").setOperation("a")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(6),
+            .setParentId(3).addLogMessage("routing at a").addLogMessage("End of routing"),
         new SpanTestData().setLabel("direct:start server").setUri("direct://start").setOperation("start")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(7),
-        new SpanTestData().setLabel("direct:start client").setUri("direct://start").setOperation("start")
-            .setKind(Tags.SPAN_KIND_CLIENT)
     };
 
     public CustomComponentNameRouteTest() {
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/EIPTracingActiveSpanTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/EIPTracingActiveSpanTest.java
new file mode 100644
index 0000000..3586757
--- /dev/null
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/EIPTracingActiveSpanTest.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.opentracing;
+
+import io.opentracing.tag.Tags;
+import io.opentracing.util.GlobalTracer;
+import io.opentracing.util.GlobalTracerTestUtil;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spi.InterceptStrategy;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+public class EIPTracingActiveSpanTest extends CamelOpenTracingTestSupport {
+
+    private static SpanTestData[] testdata = {
+        new SpanTestData().setLabel("active-span server").setOperation("using-active-span")
+            .setParentId(1),
+        new SpanTestData().setLabel("process server").setOperation("direct-processor")
+            .setParentId(2),
+        new SpanTestData().setLabel("direct:start server").setUri("direct://start").setOperation("start")
+    };
+
+    public EIPTracingActiveSpanTest() {
+        super(testdata);
+    }
+
+    @BeforeAll
+    public void setUp() throws Exception {
+        GlobalTracerTestUtil.resetGlobalTracer();
+    }
+
+    @Test
+    public void testRoute() throws Exception {
+        template.requestBody("direct:start", "Hello");
+
+        verify();
+    }
+
+    @Override
+    protected InterceptStrategy getTracingStrategy() {
+        return new OpenTracingTracingStrategy(ottracer);
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start").routeId("start").process(new Processor() {
+                    @Override
+                    public void process(Exchange exchange) throws Exception {
+                        // here you can use GlobalTracer if it's in your classpath or
+                        // use the exchange context to look for a tracer in the registry
+                        GlobalTracer.get().buildSpan("using-active-span")
+                                .withTag(Tags.COMPONENT, "custom-component")
+                                .asChildOf(GlobalTracer.get().activeSpan())
+                                .start().finish();
+                    }
+                }).id("direct-processor");
+            }
+        };
+    }
+}
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/EIPTracingRouteTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/EIPTracingRouteTest.java
new file mode 100644
index 0000000..5310b4c
--- /dev/null
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/EIPTracingRouteTest.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.opentracing;
+
+import io.opentracing.Span;
+import io.opentracing.tag.Tags;
+import io.opentracing.util.GlobalTracer;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spi.InterceptStrategy;
+import org.junit.jupiter.api.Test;
+
+public class EIPTracingRouteTest extends CamelOpenTracingTestSupport {
+
+    private static SpanTestData[] testdata = {
+        new SpanTestData().setLabel("a-log-1 server").setOperation("a-log-1")
+            .setParentId(11),
+        new SpanTestData().setLabel("b-log server").setOperation("b-log")
+            .setParentId(3),
+        new SpanTestData().setLabel("b-delay server").setOperation("b-delay")
+            .setParentId(3),
+        new SpanTestData().setLabel("seda:b server").setUri("seda://b").setOperation("b")
+            .setParentId(4).addLogMessage("routing at b"),
+        new SpanTestData().setLabel("a-to-1 server").setOperation("a-to-1")
+            .setParentId(11),
+        new SpanTestData().setLabel("a-delay server").setOperation("a-delay")
+            .setParentId(11),
+        new SpanTestData().setLabel("c-to server").setOperation("c-to")
+            .setParentId(8).addLogMessage("Exchange[ExchangePattern: InOut, BodyType: String, Body: Hello]"),
+        new SpanTestData().setLabel("c-delay server").setOperation("c-delay")
+            .setParentId(8),
+        new SpanTestData().setLabel("seda:c server").setUri("seda://c").setOperation("c")
+            .setParentId(9),
+        new SpanTestData().setLabel("a-to-2 server").setOperation("a-to-2")
+            .setParentId(11),
+        new SpanTestData().setLabel("a-log-2 server").setOperation("a-log-2")
+            .setParentId(11),
+        new SpanTestData().setLabel("seda:a server").setUri("seda://a").setOperation("a")
+            .setParentId(12).addLogMessage("routing at a").addLogMessage("End of routing"),
+        new SpanTestData().setLabel("direct-to server").setOperation("direct-to")
+            .setParentId(13),
+        new SpanTestData().setLabel("direct:start server").setUri("direct://start").setOperation("start")
+    };
+
+    public EIPTracingRouteTest() {
+        super(testdata);
+    }
+
+    @Test
+    public void testRoute() throws Exception {
+        template.requestBody("direct:start", "Hello");
+
+        verify();
+    }
+
+    @Override
+    protected InterceptStrategy getTracingStrategy() {
+        return new OpenTracingTracingStrategy(ottracer);
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start").routeId("start")
+                        .to("seda:a").id("direct-to");
+
+                from("seda:a").routeId("a")
+                    .log("routing at ${routeId}").id("a-log-1")
+                    .to("seda:b").id("a-to-1")
+                    .delay(2000).id("a-delay")
+                    .to("seda:c").id("a-to-2")
+                    .log("End of routing").id("a-log-2");
+
+                from("seda:b").routeId("b")
+                    .log("routing at ${routeId}").id("b-log")
+                    .delay(simple("${random(1000,2000)}")).id("b-delay");
+
+                from("seda:c").routeId("c")
+                    .to("log:test").id("c-to")
+                    .delay(simple("${random(0,100)}")).id("c-delay");
+            }
+        };
+    }
+}
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/MulticastParallelRouteTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/MulticastParallelRouteTest.java
index ba914bb..90c394e 100644
--- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/MulticastParallelRouteTest.java
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/MulticastParallelRouteTest.java
@@ -25,21 +25,12 @@ public class MulticastParallelRouteTest extends CamelOpenTracingTestSupport {
 
     private static SpanTestData[] testdata = {
         new SpanTestData().setLabel("seda:b server").setUri("seda://b").setOperation("b")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(1).addLogMessage("routing at b"),
-        new SpanTestData().setLabel("seda:b client").setUri("seda://b").setOperation("b")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4),
+            .setParentId(2).addLogMessage("routing at b"),
         new SpanTestData().setLabel("seda:c server").setUri("seda://c").setOperation("c")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(3).addLogMessage("routing at c"),
-        new SpanTestData().setLabel("seda:c client").setUri("seda://c").setOperation("c")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4),
+            .setParentId(2).addLogMessage("routing at c"),
         new SpanTestData().setLabel("seda:a server").setUri("seda://a").setOperation("a")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(5).addLogMessage("routing at a").addLogMessage("End of routing"),
-        new SpanTestData().setLabel("seda:a client").setUri("seda://a").setOperation("a")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(6),
+            .setParentId(3).addLogMessage("routing at a").addLogMessage("End of routing"),
         new SpanTestData().setLabel("direct:start server").setUri("direct://start").setOperation("start")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(7),
-        new SpanTestData().setLabel("direct:start client").setUri("direct://start").setOperation("start")
-            .setKind(Tags.SPAN_KIND_CLIENT)
     };
 
     public MulticastParallelRouteTest() {
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/MulticastRouteTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/MulticastRouteTest.java
index 4ca5031..1bee543 100644
--- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/MulticastRouteTest.java
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/MulticastRouteTest.java
@@ -25,21 +25,12 @@ public class MulticastRouteTest extends CamelOpenTracingTestSupport {
 
     private static SpanTestData[] testdata = {
         new SpanTestData().setLabel("seda:b server").setUri("seda://b").setOperation("b")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(1),
-        new SpanTestData().setLabel("seda:b client").setUri("seda://b").setOperation("b")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4),
+            .setParentId(2),
         new SpanTestData().setLabel("seda:c server").setUri("seda://c").setOperation("c")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(3),
-        new SpanTestData().setLabel("seda:c client").setUri("seda://c").setOperation("c")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4),
+            .setParentId(2),
         new SpanTestData().setLabel("seda:a server").setUri("seda://a").setOperation("a")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(5),
-        new SpanTestData().setLabel("seda:a client").setUri("seda://a").setOperation("a")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(6),
+            .setParentId(3),
         new SpanTestData().setLabel("direct:start server").setUri("direct://start").setOperation("start")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(7),
-        new SpanTestData().setLabel("direct:start client").setUri("direct://start").setOperation("start")
-            .setKind(Tags.SPAN_KIND_CLIENT)
     };
 
     public MulticastRouteTest() {
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/OpentracingSpanCollectorInRegistryTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/OpentracingSpanCollectorInRegistryTest.java
index fe12c39..e9dcfc9 100644
--- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/OpentracingSpanCollectorInRegistryTest.java
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/OpentracingSpanCollectorInRegistryTest.java
@@ -18,9 +18,11 @@ package org.apache.camel.opentracing;
 
 import io.opentracing.noop.NoopTracer;
 import io.opentracing.noop.NoopTracerFactory;
+import io.opentracing.util.GlobalTracerTestUtil;
 import org.apache.camel.BindToRegistry;
 import org.apache.camel.CamelContext;
 import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -32,6 +34,11 @@ public class OpentracingSpanCollectorInRegistryTest extends CamelTestSupport {
     @BindToRegistry("tracer")
     private NoopTracer c = NoopTracerFactory.create();
 
+    @BeforeAll
+    public void setUp() throws Exception {
+        GlobalTracerTestUtil.resetGlobalTracer();
+    }
+
     @Override
     protected CamelContext createCamelContext() throws Exception {
         CamelContext context = super.createCamelContext();
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/RouteConcurrentTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/RouteConcurrentTest.java
index abc0c57..aa0a927 100644
--- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/RouteConcurrentTest.java
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/RouteConcurrentTest.java
@@ -29,14 +29,9 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
 public class RouteConcurrentTest extends CamelOpenTracingTestSupport {
 
     private static SpanTestData[] testdata = {
-        new SpanTestData().setLabel("seda:foo client").setUri("seda://foo").setOperation("foo")
-            .setKind(Tags.SPAN_KIND_CLIENT),
-        new SpanTestData().setLabel("seda:bar client").setUri("seda://bar").setOperation("bar")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(2),
-        new SpanTestData().setLabel("seda:foo server").setUri("seda://foo?concurrentConsumers=5").setOperation("foo")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(0),
+        new SpanTestData().setLabel("seda:foo server").setUri("seda://foo?concurrentConsumers=5").setOperation("foo"),
         new SpanTestData().setLabel("seda:bar server").setUri("seda://bar?concurrentConsumers=5").setOperation("bar")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(1)
+            .setParentId(0)
     };
 
     public RouteConcurrentTest() {
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/SpanProcessorsTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/SpanProcessorsTest.java
index ae4952f..52a6b82 100644
--- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/SpanProcessorsTest.java
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/SpanProcessorsTest.java
@@ -29,23 +29,14 @@ public class SpanProcessorsTest extends CamelOpenTracingTestSupport {
 
     private static final SpanTestData[] TEST_DATA = {
             new SpanTestData().setLabel("seda:b server").setUri("seda://b").setOperation("b")
-                    .setKind(Tags.SPAN_KIND_SERVER).setParentId(1).addLogMessage("routing at b")
+                    .setParentId(2).addLogMessage("routing at b")
                     .addTag("b-tag", "request-header-value"),
-            new SpanTestData().setLabel("seda:b client").setUri("seda://b").setOperation("b")
-                    .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4),
             new SpanTestData().setLabel("seda:c server").setUri("seda://c").setOperation("c")
-                    .setKind(Tags.SPAN_KIND_SERVER).setParentId(3).addLogMessage("Exchange[ExchangePattern: InOut, BodyType: String, Body: Hello]"),
-            new SpanTestData().setLabel("seda:c client").setUri("seda://c").setOperation("c")
-                    .setKind(Tags.SPAN_KIND_CLIENT).setParentId(4),
+                    .setParentId(2).addLogMessage("Exchange[ExchangePattern: InOut, BodyType: String, Body: Hello]"),
             new SpanTestData().setLabel("seda:a server").setUri("seda://a").setOperation("a")
-                    .setKind(Tags.SPAN_KIND_SERVER).setParentId(5).addLogMessage("routing at a").addLogMessage("End of routing")
+                    .setParentId(3).addLogMessage("routing at a").addLogMessage("End of routing")
                     .addBaggage("a-baggage", "request-header-value"),
-            new SpanTestData().setLabel("seda:a client").setUri("seda://a").setOperation("a")
-                    .setKind(Tags.SPAN_KIND_CLIENT).setParentId(6),
             new SpanTestData().setLabel("direct:start server").setUri("direct://start").setOperation("start")
-                    .setKind(Tags.SPAN_KIND_SERVER).setParentId(7),
-            new SpanTestData().setLabel("direct:start client").setUri("direct://start").setOperation("start")
-                    .setKind(Tags.SPAN_KIND_CLIENT)
     };
 
     public SpanProcessorsTest() {
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/SpringOpenTracingSimpleRouteTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/SpringOpenTracingSimpleRouteTest.java
index 5640618..b5c62e3 100644
--- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/SpringOpenTracingSimpleRouteTest.java
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/SpringOpenTracingSimpleRouteTest.java
@@ -47,7 +47,7 @@ public class SpringOpenTracingSimpleRouteTest extends CamelSpringTestSupport {
 
         MockTracer tracer = (MockTracer) context().getRegistry().lookupByName("mockTracer");
 
-        // Four spans per invocation, one for client, two for dude route (server and client to), one for car route
-        assertEquals(20, tracer.finishedSpans().size());
+        // Two spans per invocation, one for server dude route, one for car route
+        assertEquals(10, tracer.finishedSpans().size());
     }
 }
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ClientRecipientListRouteTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TracingClientRecipientListRouteTest.java
similarity index 58%
copy from components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ClientRecipientListRouteTest.java
copy to components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TracingClientRecipientListRouteTest.java
index 3ef2549..c5d1245 100644
--- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/ClientRecipientListRouteTest.java
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TracingClientRecipientListRouteTest.java
@@ -19,30 +19,34 @@ package org.apache.camel.opentracing;
 import io.opentracing.tag.Tags;
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spi.InterceptStrategy;
 import org.junit.jupiter.api.Test;
 
-public class ClientRecipientListRouteTest extends CamelOpenTracingTestSupport {
+public class TracingClientRecipientListRouteTest extends CamelOpenTracingTestSupport {
 
     private static SpanTestData[] testdata = {
+        new SpanTestData().setLabel("a: log").setOperation("a-log-1")
+            .setParentId(1),
         new SpanTestData().setLabel("seda:a server").setUri("seda://a").setOperation("a")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(1),
-        new SpanTestData().setLabel("seda:a client").setUri("seda://a").setOperation("a")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(6),
+            .setParentId(8),
+        new SpanTestData().setLabel("b: log").setOperation("b-log-2")
+            .setParentId(4),
+        new SpanTestData().setLabel("b: delay").setOperation("b-delay-1")
+            .setParentId(4),
         new SpanTestData().setLabel("seda:b server").setUri("seda://b").setOperation("b")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(3),
-        new SpanTestData().setLabel("seda:b client").setUri("seda://b").setOperation("b")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(6),
+            .setParentId(8),
+        new SpanTestData().setLabel("c: log").setOperation("c-log-3")
+            .setParentId(7),
+        new SpanTestData().setLabel("c: delay").setOperation("c-delay-2")
+            .setParentId(7),
         new SpanTestData().setLabel("seda:c server").setUri("seda://c").setOperation("c")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(5),
-        new SpanTestData().setLabel("seda:c client").setUri("seda://c").setOperation("c")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(6),
+            .setParentId(8),
+        new SpanTestData().setLabel("a: recipientList").setOperation("direct-recipientList-1")
+            .setParentId(9),
         new SpanTestData().setLabel("direct:start server").setUri("direct://start").setOperation("start")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(7),
-        new SpanTestData().setLabel("direct:start client").setUri("direct://start").setOperation("start")
-            .setKind(Tags.SPAN_KIND_CLIENT)
     };
 
-    public ClientRecipientListRouteTest() {
+    public TracingClientRecipientListRouteTest() {
         super(testdata);
     }
 
@@ -58,19 +62,24 @@ public class ClientRecipientListRouteTest extends CamelOpenTracingTestSupport {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                from("direct:start").recipientList(constant("seda:a,seda:b,seda:c")).routeId("start");
+                from("direct:start").recipientList(constant("seda:a,seda:b,seda:c")).id("direct-recipientList-1").routeId("start");
 
                 from("seda:a").routeId("a")
-                    .log("routing at ${routeId}");
+                    .log("routing at ${routeId}").id("a-log-1");
 
                 from("seda:b").routeId("b")
-                    .log("routing at ${routeId}")
-                    .delay(simple("${random(1000,2000)}"));
+                    .log("routing at ${routeId}").id("b-log-2")
+                    .delay(simple("${random(1000,2000)}")).id("b-delay-1");
 
                 from("seda:c").routeId("c")
-                    .log("routing at ${routeId}")
-                    .delay(simple("${random(0,100)}"));
+                    .log("routing at ${routeId}").id("c-log-3")
+                    .delay(simple("${random(0,100)}")).id("c-delay-2");
             }
         };
     }
+
+    @Override
+    protected InterceptStrategy getTracingStrategy() {
+        return new OpenTracingTracingStrategy(ottracer);
+    }
 }
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TracingMulticastParallelRouteTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TracingMulticastParallelRouteTest.java
new file mode 100644
index 0000000..ade81c0
--- /dev/null
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TracingMulticastParallelRouteTest.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.opentracing;
+
+import io.opentracing.tag.Tags;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spi.InterceptStrategy;
+import org.junit.jupiter.api.Test;
+
+public class TracingMulticastParallelRouteTest extends CamelOpenTracingTestSupport {
+
+    private static SpanTestData[] testdata = {
+        new SpanTestData().setLabel("a: a-log-1").setOperation("a-log-1")
+            .setParentId(11),
+        new SpanTestData().setLabel("b: b-log-3").setOperation("b-log-3")
+            .setParentId(7),
+        new SpanTestData().setLabel("c: c-log-4").setOperation("c-log-4")
+            .setParentId(4),
+        new SpanTestData().setLabel("c: c-delay-2").setOperation("c-delay-2")
+            .setParentId(4),
+        new SpanTestData().setLabel("seda:c server").setUri("seda://c").setOperation("c")
+            .setParentId(5).addLogMessage("routing at c"),
+        new SpanTestData().setLabel("a:multicast: a-to-3").setOperation("a-to-3")
+            .setParentId(9),
+        new SpanTestData().setLabel("b: b-delay-1").setOperation("b-delay-1")
+            .setParentId(7),
+        new SpanTestData().setLabel("seda:b server").setUri("seda://b").setOperation("b")
+            .setParentId(8).addLogMessage("routing at b"),
+        new SpanTestData().setLabel("a:multicast: a-to-2").setOperation("a-to-2")
+            .setParentId(9),
+        new SpanTestData().setLabel("a: multicast").setOperation("a-multicast-1")
+            .setParentId(11),
+        new SpanTestData().setLabel("a: a-log-2").setOperation("a-log-2")
+            .setParentId(11),
+        new SpanTestData().setLabel("seda:a server").setUri("seda://a").setOperation("a")
+            .setParentId(12).addLogMessage("routing at a").addLogMessage("End of routing"),
+        new SpanTestData().setLabel("direct:start server").setOperation("direct-to-1")
+            .setParentId(13),
+        new SpanTestData().setLabel("direct:start server").setUri("direct://start").setOperation("start")
+    };
+
+    public TracingMulticastParallelRouteTest() {
+        super(testdata);
+    }
+
+    @Test
+    public void testRoute() throws Exception {
+        template.requestBody("direct:start", "Hello");
+
+        verify(true);
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("direct:start").to("seda:a").id("direct-to-1").routeId("start");
+
+                from("seda:a").routeId("a")
+                    .log("routing at ${routeId}").id("a-log-1")
+                    .multicast().parallelProcessing().id("a-multicast-1")
+                    // to(String...) only sets the .id(String) on the first element, others will be dynamic
+                    .to("seda:b").id("a-to-2")
+                    .to("seda:c").id("a-to-3")
+                    .end()
+                    .log("End of routing").id("a-log-2");
+
+                from("seda:b").routeId("b")
+                    .log("routing at ${routeId}").id("b-log-3")
+                    .delay(simple("${random(1000,2000)}")).id("b-delay-1");
+
+                from("seda:c").routeId("c")
+                    .log("routing at ${routeId}").id("c-log-4")
+                    .delay(simple("${random(0,100)}")).id("c-delay-2");
+            }
+        };
+    }
+
+    @Override
+    protected InterceptStrategy getTracingStrategy() {
+        return new OpenTracingTracingStrategy(ottracer);
+    }
+}
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TwoServiceTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TwoServiceTest.java
index 8cb70a5..497dcae 100644
--- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TwoServiceTest.java
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TwoServiceTest.java
@@ -25,13 +25,8 @@ public class TwoServiceTest extends CamelOpenTracingTestSupport {
 
     private static SpanTestData[] testdata = {
         new SpanTestData().setLabel("ServiceB server").setUri("direct://ServiceB").setOperation("ServiceB")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(1),
-        new SpanTestData().setLabel("ServiceB client").setUri("direct://ServiceB").setOperation("ServiceB")
-            .setKind(Tags.SPAN_KIND_CLIENT).setParentId(2),
+            .setParentId(1),
         new SpanTestData().setLabel("ServiceA server").setUri("direct://ServiceA").setOperation("ServiceA")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(3),
-        new SpanTestData().setLabel("ServiceA client").setUri("direct://ServiceA").setOperation("ServiceA")
-            .setKind(Tags.SPAN_KIND_CLIENT)
     };
 
     public TwoServiceTest() {
diff --git a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TwoServiceWithExcludeTest.java b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TwoServiceWithExcludeTest.java
index 0da4061..497dc95 100644
--- a/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TwoServiceWithExcludeTest.java
+++ b/components/camel-opentracing/src/test/java/org/apache/camel/opentracing/TwoServiceWithExcludeTest.java
@@ -28,9 +28,6 @@ public class TwoServiceWithExcludeTest extends CamelOpenTracingTestSupport {
 
     private static SpanTestData[] testdata = {
         new SpanTestData().setLabel("ServiceA server").setUri("direct://ServiceA").setOperation("ServiceA")
-            .setKind(Tags.SPAN_KIND_SERVER).setParentId(1),
-        new SpanTestData().setLabel("ServiceA client").setUri("direct://ServiceA").setOperation("ServiceA")
-            .setKind(Tags.SPAN_KIND_CLIENT)
     };
 
     public TwoServiceWithExcludeTest() {