This section provides answers to some common “how do I do that…?” questions that often arise when using Spring Cloud Sleuth OTel. Its coverage is not exhaustive, but it does cover quite a lot.
If you have a specific problem that we do not cover here, you might want to check out
stackoverflow.com to see if someone has already provided an answer.
Stack Overflow is also a great place to ask new questions (please use the spring-cloud-sleuth-otel
tag).
We are also more than happy to extend this section. If you want to add a “how-to”, send us a pull request.
1. How to Set Up Sleuth with OpenTelemetry?
Add the Sleuth starter, exclude Brave and add OpenTelemetry dependency to the classpath.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<!-- Provide the latest stable Spring Cloud release train version (e.g. 2020.0.0) -->
<version>${release.train.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel-dependencies</artifactId>
<!-- Provide the version of the Spring Cloud Sleuth OpenTelemetry project (e.g. 1.1.2) -->
<version>${spring-cloud-sleuth-otel.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel-autoconfigure</artifactId>
</dependency>
<!-- Add otlp specific exporter -->
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${releaseTrainVersion}"
mavenBom "org.springframework.cloud:spring-cloud-sleuth-otel-dependencies:${springCloudSleuthOtelVersion}"
}
}
dependencies {
implementation("org.springframework.cloud:spring-cloud-starter-sleuth") {
exclude group: 'org.springframework.cloud', module: 'spring-cloud-sleuth-brave'
}
implementation "org.springframework.cloud:spring-cloud-sleuth-otel-autoconfigure"
implementation "io.opentelemetry:opentelemetry-exporter-otlp"
}
Also make sure to set the otlp exporter’s endpoint via spring.otel.exporter.otlp.endpoint=http://collector-url:4317
.
2. How to Set Up Sleuth with OpenTelemetry & Zipkin via HTTP?
Add the Sleuth starter, exclude Brave, add OTel and Zipkin to the classpath.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<!-- Provide the latest stable Spring Cloud release train version (e.g. 2020.0.0) -->
<version>${release.train.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel-dependencies</artifactId>
<!-- Provide the version of the Spring Cloud Sleuth OpenTelemetry project (e.g. 1.1.2) -->
<version>${spring-cloud-sleuth-otel.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-zipkin</artifactId>
</dependency>
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${releaseTrainVersion}"
mavenBom "org.springframework.cloud:spring-cloud-sleuth-otel-dependencies:${springCloudSleuthOtelVersion}"
}
}
dependencies {
implementation("org.springframework.cloud:spring-cloud-starter-sleuth") {
exclude group: 'org.springframework.cloud', module: 'spring-cloud-sleuth-brave'
}
implementation "org.springframework.cloud:spring-cloud-sleuth-otel-autoconfigure"
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
implementation "io.opentelemetry:opentelemetry-exporter-zipkin"
}
3. How to Set Up Sleuth with OpenTelemetry & Zipkin via Messaging?
If you want to use RabbitMQ, Kafka or ActiveMQ instead of HTTP, add the spring-rabbit
, spring-kafka
or org.apache.activemq:activemq-client
dependency.
The default destination name is Zipkin
.
If using Kafka, you must add the Kafka dependency.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<!-- Provide the latest stable Spring Cloud release train version (e.g. 2020.0.0) -->
<version>${release.train.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel-dependencies</artifactId>
<!-- Provide the version of the Spring Cloud Sleuth OpenTelemetry project (e.g. 1.1.2) -->
<version>${spring-cloud-sleuth-otel.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${releaseTrainVersion}"
mavenBom "org.springframework.cloud:spring-cloud-sleuth-otel-dependencies:${springCloudSleuthOtelVersion}"
}
}
dependencies {
implementation("org.springframework.cloud:spring-cloud-starter-sleuth") {
exclude group: 'org.springframework.cloud', module: 'spring-cloud-sleuth-brave'
}
implementation "org.springframework.cloud:spring-cloud-sleuth-otel-autoconfigure"
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
implementation "org.springframework.kafka:spring-kafka"
}
Also, you need to set the property spring.zipkin.sender.type
property accordingly:
spring.zipkin.sender.type: kafka
If you want Sleuth over RabbitMQ, add the spring-cloud-sleuth-otel
(exclude spring-cloud-sleuth-brave
), spring-cloud-sleuth-zipkin
and spring-rabbit
dependencies.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<!-- Provide the latest stable Spring Cloud release train version (e.g. 2020.0.0) -->
<version>${release.train.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel-dependencies</artifactId>
<!-- Provide the version of the Spring Cloud Sleuth OpenTelemetry project (e.g. 1.1.2) -->
<version>${spring-cloud-sleuth-otel.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
</dependency>
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${releaseTrainVersion}"
mavenBom "org.springframework.cloud:spring-cloud-sleuth-otel-dependencies:${springCloudSleuthOtelVersion}"
}
}
dependencies {
implementation("org.springframework.cloud:spring-cloud-starter-sleuth") {
exclude group: 'org.springframework.cloud', module: 'spring-cloud-sleuth-brave'
}
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
implementation "org.springframework.amqp:spring-rabbit"
}
If you want Sleuth over RabbitMQ, add the spring-cloud-sleuth-otel
(exclude spring-cloud-sleuth-brave
), spring-cloud-sleuth-zipkin
and activemq-client
dependencies.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<!-- Provide the latest stable Spring Cloud release train version (e.g. 2020.0.0) -->
<version>${release.train.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel-dependencies</artifactId>
<!-- Provide the version of the Spring Cloud Sleuth OpenTelemetry project (e.g. 1.1.2) -->
<version>${spring-cloud-sleuth-otel.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-brave</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-otel-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-client</artifactId>
</dependency>
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${releaseTrainVersion}"
mavenBom "org.springframework.cloud:spring-cloud-sleuth-otel-dependencies:${springCloudSleuthOtelVersion}"
}
}
dependencies {
implementation("org.springframework.cloud:spring-cloud-starter-sleuth") {
exclude group: 'org.springframework.cloud', module: 'spring-cloud-sleuth-brave'
}
implementation "org.springframework.cloud:spring-cloud-sleuth-otel-autoconfigure"
implementation "org.springframework.cloud:spring-cloud-sleuth-zipkin"
implementation "org.apache.activemq:activemq-client"
}
Also, you need to set the property spring.zipkin.sender.type
property accordingly:
spring.zipkin.sender.type: activemq
4. How to Change The Context Propagation Mechanism?
To use the provided defaults you can set the spring.sleuth.propagation.type
property.
The value can be a list in which case you will propagate more tracing headers.
For OpenTelemetry we support AWS
, B3
, JAEGER
, OT_TRACER
and W3C
propagation types.
If you want to provide a custom propagation mechanism set the spring.sleuth.propagation.type
property to CUSTOM
and implement your own bean (Propagation.Factory
for Brave and TextMapPropagator
for OpenTelemetry).
Below you can find the examples:
@Component
class CustomPropagator implements TextMapPropagator {
@Override
public List<String> fields() {
return Arrays.asList("myCustomTraceId", "myCustomSpanId");
}
@Override
public <C> void inject(Context context, C carrier, TextMapSetter<C> setter) {
SpanContext spanContext = Span.fromContext(context).getSpanContext();
if (!spanContext.isValid()) {
return;
}
setter.set(carrier, "myCustomTraceId", spanContext.getTraceId());
setter.set(carrier, "myCustomSpanId", spanContext.getSpanId());
}
@Override
public <C> Context extract(Context context, C carrier, TextMapGetter<C> getter) {
String traceParent = getter.get(carrier, "myCustomTraceId");
if (traceParent == null) {
return Span.getInvalid().storeInContext(context);
}
String spanId = getter.get(carrier, "myCustomSpanId");
return Span.wrap(SpanContext.createFromRemoteParent(traceParent, spanId, TraceFlags.getSampled(),
TraceState.builder().build())).storeInContext(context);
}
}