Auto-configures OpenTelemetry instrumentation for spring-web , spring-webmvc, and spring-webflux. Leverages Spring Aspect Oriented Programming, dependency injection, and bean post-processing to trace spring applications. To include all features listed below use the opentelemetry-spring-boot-starter.
Replace OPENTELEMETRY_VERSION
with the latest stable release.
1.17.0
For Maven, add to your pom.xml
dependencies:
<dependencies>
<!-- opentelemetry -->
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-spring-boot</artifactId>
<version>OPENTELEMETRY_VERSION</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>OPENTELEMETRY_VERSION</version>
</dependency>
<!-- simple span exporter -->
<!-- outputs spans to console -->
<!-- provides opentelemetry-sdk artifact -->
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-logging</artifactId>
<version>OPENTELEMETRY_VERSION</version>
</dependency>
</dependencies>
For Gradle, add to your dependencies:
//opentelemetry spring auto-configuration
implementation("io.opentelemetry.instrumentation:opentelemetry-spring-boot:OPENTELEMETRY_VERSION")
//opentelemetry
implementation("io.opentelemetry:opentelemetry-api:OPENTELEMETRY_VERSION")
//opentelemetry exporter
implementation("io.opentelemetry:opentelemetry-exporters-otlp:OPENTELEMETRY_VERSION")
The following dependencies are optional but are required to use the corresponding features.
Replace SPRING_VERSION
with the version of spring you're using.
3.1
Replace SPRING_WEBFLUX_VERSION
with the version of spring-webflux you're using.
5.0
For Maven, add to your pom.xml
dependencies:
<dependencies>
<!-- opentelemetry exporters-->
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-jaeger</artifactId>
<version>OPENTELEMETRY_VERSION</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-zipkin</artifactId>
<version>OPENTELEMETRY_VERSION</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
<version>OPENTELEMETRY_VERSION</version>
</dependency>
<!-- Used to autoconfigure spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>SPRING_VERSION</version>
</dependency>
<!-- Used to autoconfigure spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>SPRING_VERSION</version>
</dependency>
<!-- Used to autoconfigure spring-webflux -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<version>SPRING_WEBFLUX_VERSION</version>
</dependency>
<!-- Used to enable instrumentation using @WithSpan -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>SPRING_VERSION</version>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-extension-annotations</artifactId>
<version>OPENTELEMETRY_VERSION</version>
</dependency>
</dependencies>
For Gradle, add to your dependencies:
//opentelemetry exporter
implementation("io.opentelemetry:opentelemetry-exporter-jaeger:OPENTELEMETRY_VERSION")
implementation("io.opentelemetry:opentelemetry-exporter-zipkin:OPENTELEMETRY_VERSION")
implementation("io.opentelemetry:opentelemetry-exporter-otlp:OPENTELEMETRY_VERSION")
//Used to autoconfigure spring-web
implementation("org.springframework:spring-web:SPRING_VERSION")
//Used to autoconfigure spring-webmvc
implementation("org.springframework:spring-webmvc:SPRING_VERSION")
//Used to autoconfigure spring-webflux
implementation("org.springframework:spring-webflux:SPRING_WEBFLUX_VERSION")
//Enables instrumentation using @WithSpan
implementation("org.springframework:spring-aop:SPRING_VERSION")
implementation("io.opentelemetry:opentelemetry-extension-annotations:OPENTELEMETRY_VERSION")
Provides a OpenTelemetry tracer bean (io.opentelemetry.api.trace.Tracer
) if one does not exist in the application context of the spring project. This tracer bean will be used in all configurations listed below. Feel free to declare your own Opentelemetry tracer bean to overwrite this configuration.
Provides auto-configuration for the OpenTelemetry RestTemplate trace interceptor defined in opentelemetry-spring-web-3.1. This auto-configuration instruments all requests sent using Spring RestTemplate beans by applying a RestTemplate bean post processor. This feature is supported for spring web versions 3.1+ and can be disabled by adding opentelemetry.trace.httpclients.enabled=false
to your resources/applications.properties
file. Spring Web - RestTemplate Client Span show cases a sample client span generated by this auto-configuration. Check out opentelemetry-spring-web-3.1 to learn more about the OpenTelemetry RestTemplateInterceptor.
This feature autoconfigures instrumentation for Spring WebMVC controllers by adding
a telemetry producing servlet Filter
bean to the application context. This filter decorates the request execution with an OpenTelemetry
server span, propagating the incoming tracing context if received in the HTTP request. Check
out opentelemetry-spring-webmvc-5.3
instrumentation library
to learn more about the OpenTelemetry Spring WebMVC instrumentation.
Provides auto-configurations for the OpenTelemetry WebClient ExchangeFilter defined
in opentelemetry-spring-webflux-5.3. This auto-configuration
instruments all outgoing http requests sent using Spring's WebClient and WebClient Builder beans by
applying a bean post processor. This feature is supported for spring webflux versions 5.0+ and can
be disabled by adding opentelemetry.trace.httpclients.enabled=false
to
your resources/applications.properties
file. Spring Web-Flux - WebClient Span showcases a sample span
generated by the WebClientFilter. Check
out opentelemetry-spring-webflux-5.3 to learn more about the
OpenTelemetry WebClientFilter.
This feature uses spring-aop to wrap methods annotated with @WithSpan
in a span. The arguments
to the method can be captured as attributed on the created span by annotating the method
parameters with @SpanAttribute
.
Note - This annotation can only be applied to bean methods managed by the spring application context. Check out spring-aop to learn more about aspect weaving in spring.
import org.springframework.stereotype.Component;
import io.opentelemetry.instrumentation.annotations.SpanAttribute;
import io.opentelemetry.instrumentation.annotations.WithSpan;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
/**
* Test WithSpan
*/
@Component
public class TracedClass {
@WithSpan
public void tracedMethod() {
}
@WithSpan(value="span name")
public void tracedMethodWithName() {
Span currentSpan = Span.current();
currentSpan.addEvent("ADD EVENT TO tracedMethodWithName SPAN");
currentSpan.setAttribute("isTestAttribute", true);
}
@WithSpan(kind = SpanKind.CLIENT)
public void tracedClientSpan() {
}
public void tracedMethodWithAttribute(@SpanAttribute("attributeName") String parameter) {
}
}
The traces below were exported using Zipkin.
{
"traceId":"0371febbbfa76b2e285a08b53a055d17",
"id":"9b782243ad7df179",
"kind":"SERVER",
"name":"webmvctracingfilter.dofilterinteral",
"timestamp":1596841405866633,
"duration":355648,
"localEndpoint":{
"serviceName":"sample_trace",
"ipv4":"XXX.XXX.X.XXX"
},
"tags":{
"http.client_ip":"0:0:0:0:0:0:0:1",
"http.flavor":"1.1",
"http.method":"GET",
"http.status_code":"200",
"http.url":"/spring-webmvc/sample",
"http.user_agent":"PostmanRuntime/7.26.2",
"net.sock.peer.addr":"0:0:0:0:0:0:0:1",
"net.sock.peer.port":"33916",
"net.sock.family":"inet6"
"sampling.probability":"1.0"
}
}
{
"traceId": "0371febbbfa76b2e285a08b53a055d17",
"parentId": "9b782243ad7df179",
"id": "43990118a8bdbdf5",
"kind": "CLIENT",
"name": "http get",
"timestamp": 1596841405949825,
"duration": 21288,
"localEndpoint": {
"serviceName": "sample_trace",
"ipv4": "XXX.XXX.X.XXX"
},
"tags": {
"http.method": "GET",
"http.status_code": "200",
"http.url": "/spring-web/sample/rest-template",
"net.peer.name": "localhost",
"net.peer.port": "8081"
}
}
{
"traceId": "0371febbbfa76b2e285a08b53a055d17",
"parentId": "9b782243ad7df179",
"id": "1b14a2fc89d7a762",
"kind": "CLIENT",
"name": "http post",
"timestamp": 1596841406109125,
"duration": 25137,
"localEndpoint": {
"serviceName": "sample_trace",
"ipv4": "XXX.XXX.X.XXX"
},
"tags": {
"http.method": "POST",
"http.status_code": "200",
"http.url": "/spring-webflux/sample/web-client",
"net.peer.name": "localhost",
"net.peer.port": "8082"
}
}
[
{
"traceId":"0371febbbfa76b2e285a08b53a055d17",
"parentId":"9b782243ad7df179",
"id":"c3ef24b9bff5901c",
"name":"tracedclass.withspanmethod",
"timestamp":1596841406165439,
"duration":6912,
"localEndpoint":{
"serviceName":"sample_trace",
"ipv4":"XXX.XXX.X.XXX"
},
"tags":{
"test.type":"@WithSpan annotation",
"test.case":'@WithSpan',
"test.hasEvent":'true',
}
},
{
"traceId":"0371febbbfa76b2e285a08b53a055d17",
"parentId":"9b782243ad7df179",
"id":"1a6cb395a8a33cc0",
"name":"@withspan set span name",
"timestamp":1596841406182759,
"duration":2187,
"localEndpoint":{
"serviceName":"sample_trace",
"ipv4":"XXX.XXX.X.XXX"
},
"annotations":[
{
"timestamp":1596841406182920,
"value":"ADD EVENT TO tracedMethodWithName SPAN"
}
],
"tags":{
"test.type":"@WithSpan annotation",
"test.case":'@WithSpan(value="@withspan set span name")',
"test.hasEvent":'true',
}
},
{
"traceId":"0371febbbfa76b2e285a08b53a055d17",
"parentId":"9b782243ad7df179",
"id":"74dd19a8a9883f80",
"kind":"CLIENT",
"name":"tracedClientSpan",
"timestamp":1596841406194210,
"duration":130,
"localEndpoint":{
"serviceName":"sample_trace",
"ipv4":"XXX.XXX.X.XXX"
}
"tags":{
"test.type":"@WithSpan annotation",
"test.case":"@WithSpan(kind=SpanKind.Client)",
}
},
]
Auto-configuration is natively supported by Springboot applications. To enable these features in "vanilla" use @EnableOpenTelemetry
to complete a component scan of this package.
import io.opentelemetry.instrumentation.spring.autoconfigure.EnableOpenTelemetry;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableOpenTelemetry
public class OpenTelemetryConfig {}
This package provides auto configurations for OTLP, Jaeger, Zipkin, and Logging Span Exporters.
If an exporter is present in the classpath during runtime and a spring bean of the exporter is missing from the spring application context. An exporter bean is initialized and added to a simple span processor in the active tracer provider. Check out the implementation here.
Feature | Property | Default Value | ConditionalOnClass |
---|---|---|---|
spring-web | otel.springboot.httpclients.enabled | true |
RestTemplate |
spring-webmvc | otel.springboot.httpclients.enabled | true |
OncePerRequestFilter |
spring-webflux | otel.springboot.httpclients.enabled | true |
WebClient |
@WithSpan | otel.springboot.aspects.enabled | true |
WithSpan, Aspect |
Otlp Exporter | otel.exporter.otlp.enabled | true |
OtlpGrpcSpanExporter |
Jaeger Exporter | otel.exporter.jaeger.enabled | true |
JaegerGrpcSpanExporter |
Zipkin Exporter | otel.exporter.zipkin.enabled | true |
ZipkinSpanExporter |
Logging Exporter | otel.exporter.logging.enabled | true |
LoggingSpanExporter |
Feature | Property | Default Value |
---|---|---|
Resource | otel.springboot.resource.enabled | true |
otel.springboot.resource.attributes.service.name | unknown_service:java |
|
otel.springboot.resource.attributes | empty map |
unknown_service:java
will be used as the service-name if no value has been specified to the
property spring.application.name
or otel.springboot.resource.attributes.service.name
(which has
the highest priority)
otel.springboot.resource.attributes
supports a pattern-based resource configuration in the
application.properties like this:
otel.springboot.resource.attributes.environment=dev
otel.springboot.resource.attributes.xyz=foo
Feature | Property | Default Value |
---|---|---|
Otlp Exporter | otel.exporter.otlp.endpoint | localhost:4317 |
otel.exporter.otlp.timeout | 1s |
|
Jaeger Exporter | otel.exporter.jaeger.endpoint | localhost:14250 |
otel.exporter.jaeger.timeout | 1s |
|
Zipkin Exporter | otel.exporter.jaeger.endpoint | http://localhost:9411/api/v2/spans |
Feature | Property | Default Value |
---|---|---|
Tracer | otel.traces.sampler.probability | 1.0 |
Check out OpenTelemetry Manual Instrumentation to learn more about using the OpenTelemetry API to instrument your code.