[[opentracing-other]]
= OpenTracing Component
:docTitle: OpenTracing
:artifactId: camel-opentracing
:description: Distributed tracing using OpenTracing
:since: 2.19
:supportLevel: Stable
include::{cq-version}@camel-quarkus:ROOT:partial$reference/others/opentracing.adoc[opts=optional]

*Since Camel {since}*

The OpenTracing component is used for tracing and timing incoming and
outgoing Camel messages using http://opentracing.io/[OpenTracing].

Events (spans) are captured for incoming and outgoing messages being sent
to/from Camel.

See the http://opentracing.io/[OpenTracing] website for a list of supported tracers.

== Configuration

The configuration properties for the OpenTracing tracer are:

[width="100%",cols="10%,10%,80%",options="header",]
|=======================================================================
|Option |Default |Description

|excludePatterns |  | Sets exclude pattern(s) that will disable tracing for Camel
messages that matches the pattern. The content is a Set<String> where the key is a pattern. The pattern
uses the rules from Intercept.
|encoding |false| Sets whether the header keys need to be encoded (connector specific) or not. The value is a boolean.
Dashes need for instances to be encoded for JMS property keys.
|setTracingStrategy | NoopTracingStrategy | Allows a custom Camel `InterceptStrategy` to be provided in order to
augment the default Spans with data from each processor in a route. `OpenTracingTracingStrategy` will create spans for each
processor, except for Camel log and OpenTracing processors, and activate a Scope in order to enable third-party instrumentation
in processors through the default ScopeManager. Processor spans can be excluded through the exludePatterns set, these
will be matched using the processor's ID.

|=======================================================================

There are three ways in which an OpenTracing tracer can be configured to provide distributed tracing for a Camel application:

=== Explicit

Include the `camel-opentracing` component in your POM, along with any specific dependencies associated with the chosen OpenTracing compliant Tracer.

To explicitly configure OpenTracing support, instantiate the `OpenTracingTracer` and initialize the camel
context. You can optionally specify a `Tracer`, or alternatively it can be implicitly discovered using the
`Registry` or `ServiceLoader`.

[source,java]
--------------------------------------------------------------------------------------------------
OpenTracingTracer ottracer = new OpenTracingTracer();
// By default it uses a Noop Tracer, but you can override it with a specific OpenTracing implementation.
ottracer.setTracer(...);
// And then initialize the context
ottracer.init(camelContext);
--------------------------------------------------------------------------------------------------

To use OpenTracingTracer in XML, all you need to do is to define the
OpenTracing tracer beans. Camel will automatically discover and use them.

[source,xml]
---------------------------------------------------------------------------------------------------------
  <bean id="tracer" class="..."/>
  <bean id="ottracer" class="org.apache.camel.opentracing.OpenTracingTracer">
    <property name="tracer" ref="tracer"/>
  </bean>
---------------------------------------------------------------------------------------------------------

== Spring Boot

If you are using Spring Boot then you can add
the `camel-opentracing-starter` dependency, and turn on OpenTracing by annotating
the main class with `@CamelOpenTracing`.

The `Tracer` will be implicitly obtained from the camel context's `Registry`, or the `ServiceLoader`, unless
a `Tracer` bean has been defined by the application.

== Java Agent

The third approach is to use a Java Agent to automatically configure the OpenTracing support.

Include the `camel-opentracing` component in your POM, along with any specific dependencies associated with the chosen OpenTracing compliant Tracer.

The OpenTracing Java Agent is associated with the following dependency:

[source,xml]
---------------------------------------------------------------------------------------------------------
    <dependency>
      <groupId>io.opentracing.contrib</groupId>
      <artifactId>opentracing-specialagent</artifactId>
    </dependency>
---------------------------------------------------------------------------------------------------------

IMPORTANT: It is necessary to use an OpenTracing compliant tracer that is
compatible with OpenTracing Java API version 0.31 or higher.

The `Tracer` used will be implicitly loaded from the camel context `Registry` or using the `ServiceLoader`.

How this agent is used will be specific to how you execute your application. _Service2_ in the https://github.com/apache/camel-spring-boot-examples/tree/master/camel-example-spring-boot-opentracing[camel-example-spring-boot-opentracing] downloads the agent into a local folder and then uses the `exec-maven-plugin` to launch the service with the `-javaagent` command line option.

== Example

You can find an example demonstrating the three ways to configure OpenTracing here:
https://github.com/apache/camel-spring-boot-examples/tree/master/camel-example-spring-boot-opentracing[camel-example-spring-boot-opentracing]

include::camel-spring-boot::page$opentracing-starter.adoc[]

== Span Operations Processors

The OpenTracing Component exposes the Java API span operations as a set of Processors: `TagProcessor`, `SetBaggageProcessor`, and `GetBaggageProcessor`.

=== Example

[source,java]
---------------------------------------------------------------------------------------------------------
from("seda:a").routeId("a")
        .process(new SetBaggageProcessor("a-baggage", simple("${header.request-header}")))
        .to("seda:b")
        .to("seda:c");

from("seda:b").routeId("b")
        .process(new TagProcessor("b-tag", simple("${header.request-header}")));

from("seda:c").routeId("c")
        .process(new GetBaggageProcessor("a-baggage", "baggage-header"));
---------------------------------------------------------------------------------------------------------

Where the value of header "request-header" is "foo", the resulting trace from executing route "seda:a" would include:

* Span "a" with a baggage item named "a-baggage" of value "foo"
* Span "b" with a tag named "b-tag" of value "foo"

and the resulting message would contain:

* Header "baggage-header" of value "foo"
