Spring Boot Starter

Spring Boot instrumentation for OpenTelemetry Java

The OpenTelemetry Java agent with byte code instrumentation can cover most of your needs when instrumenting Spring Boot applications.

Alternatively, the OpenTelemetry Spring Boot starter can help you in the following cases:

  • Spring Boot Native image applications for which the OpenTelemetry Java agent does not work
  • Startup overhead of the OpenTelemetry Java agent exceeds your requirements
  • OpenTelemetry Java agent might not work if your application already uses another Java monitoring agent

The opentelemetry-java-examples/spring-native repository contains an example of a Spring Boot Native image application instrumented using the OpenTelemetry Spring Boot starter.

The rest of this page documents the OpenTelemetry starter that works with Spring Boot 2.0 and 3.0.

Dependency management

A Bill of Material (BOM) ensures that versions of dependencies (including transitive ones) are aligned.

Importing the opentelemetry-bom and opentelemetry-instrumentation-bom-alpha BOMs when using the OpenTelemetry starter is important to ensure version alignment across all OpenTelemetry dependencies.

The following example shows how to import both BOMs using Maven:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-bom</artifactId>
            <version>1.34.1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry.instrumentation</groupId>
            <artifactId>opentelemetry-instrumentation-bom-alpha</artifactId>
            <version>2.0.0-alpha</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

With Gradle and Spring Boot, you have two ways to import a BOM.

You can use the Gradle’s native BOM support by adding dependencies:

plugins {
  id("java")
  id("org.springframework.boot") version "3.2.O"
}

dependencies {
  implementation(platform(SpringBootPlugin.BOM_COORDINATES))
  implementation(platform("io.opentelemetry:opentelemetry-bom:1.34.1"))
  implementation(platform("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha:2.0.0-alpha"))
}

The other way with Gradle is to use the io.spring.dependency-management plugin and to import the BOMs in dependencyManagement:

plugins {
  id("java")
  id("org.springframework.boot") version "3.2.O"
  id("io.spring.dependency-management") version "1.1.0"
}

dependencyManagement {
  imports {
    mavenBom("io.opentelemetry:opentelemetry-bom:1.34.1")
    mavenBom("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha:2.0.0-alpha")
  }
}

OpenTelemetry Starter dependency

Add the dependency given below to enable the OpenTelemetry starter.

The OpenTelemetry starter uses OpenTelemetry Spring Boot autoconfiguration. For details concerning supported libraries and features of the OpenTelemetry autoconfiguration, see the configuration README.

<dependencies>
	<dependency>
		<groupId>io.opentelemetry.instrumentation</groupId>
		<artifactId>opentelemetry-spring-boot-starter</artifactId>
	</dependency>
</dependencies>
dependencies {
	implementation("io.opentelemetry.instrumentation:opentelemetry-spring-boot-starter")
}

Disable data export

System property: otel.sdk.disabledEnvironment variable: OTEL_SDK_DISABLED

Description: Set the value to true to disable data export, e.g. for testing purposes.

OTLP Exporter

This package provides autoconfiguration for the OTLP and Logging Span Exporters.

As of 2.0.0+ the default protocol is http/protobuf. For more details on exporter configuration, see OTLP Exporter Configuration.

Enabling/Disabling Exporters

All exporters can be enabled or disabled as in the SDK autoconfiguration. This is the preferred way to enable/disable exporters and takes precedence over the properties below.

FeaturePropertyDefault ValueConditionalOnMissingBean
OTLP Exporterotel.exporter.otlp.enabledtrue-
OTLP Span Exporterotel.exporter.otlp.traces.enabledtrueOtlpHttpSpanExporter, OtlpGrpcSpanExporter
OTLP Metrics Exporterotel.exporter.otlp.metrics.enabledtrueOtlpHttpMetricExporter, OtlpGrpcMetricExporter
OTLP Logs Exporterotel.exporter.otlp.logs.enabledtrueOtlpHttpLogRecordExporter, OtlpGrpcLogRecordExporter
Logging Exporterotel.exporter.logging.enabledfalseLoggingSpanExporter

Tracer Properties

FeaturePropertyDefault Value
Tracerotel.traces.sampler.probability1.0

Resource Properties

FeaturePropertyDefault Value
Resourceotel.springboot.resource.enabledtrue
otel.resource.attributes (old: otel.springboot.resource.attributes)empty map

otel.resource.attributes supports a pattern-based resource configuration in the application.properties like this:

otel.resource.attributes.environment=dev
otel.resource.attributes.xyz=foo

It’s also possible to specify the resource attributes in application.yaml:

otel:
  resource:
    attributes:
      environment: dev
      xyz: foo

Finally, the resource attributes can be specified as a comma-separated list, as described in the specification:

export OTEL_RESOURCE_ATTRIBUTES="key1=value1,key2=value2"

The service name is determined by the following precedence rules, in accordance with the OpenTelemetry specification:

  1. otel.service.name spring property or OTEL_SERVICE_NAME environment variable (highest precedence)
  2. service.name in otel.resource.attributes system/spring property or OTEL_RESOURCE_ATTRIBUTES environment variable
  3. service.name in otel.springboot.resource.attributes system/spring property
  4. spring.application.name spring property
  5. The default value is unknown_service:java (lowest precedence)

Automatic instrumentation

Autoconfigures 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.

FeaturePropertyDefault ValueConditionalOnClass
spring-webotel.instrumentation.spring-webmvc.enabledtrueRestTemplate
spring-webmvcotel.instrumentation.spring-web.enabledtrueOncePerRequestFilter
spring-webfluxotel.instrumentation.spring-webflux.enabledtrueWebClient

Spring Web Autoconfiguration

Provides autoconfiguration for the RestTemplate trace interceptor defined in opentelemetry-spring-web-3.1. This autoconfiguration 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+. To learn more about the OpenTelemetry RestTemplate interceptor, see opentelemetry-spring-web-3.1.

Spring Web MVC Autoconfiguration

This feature autoconfigures instrumentation for Spring WebMVC controllers by adding a telemetry producing servlet Filter bean to the application context. The filter decorates the request execution with a server span, propagating the incoming tracing context if received in the HTTP request. To learn more about the OpenTelemetry Spring WebMVC instrumentation, see the opentelemetry-spring-webmvc-5.3 instrumentation library.

Spring WebFlux Autoconfiguration

Provides autoconfigurations for the OpenTelemetry WebClient ExchangeFilter defined in opentelemetry-spring-webflux-5.3. This autoconfiguration 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+. For details, see opentelemetry-spring-webflux-5.3.

Additional Instrumentations

JDBC Instrumentation

You have two ways to enable the JDBC instrumentation with the OpenTelemetry starter.

If your application does not declare DataSource bean, you can update your application.properties file to have the data source URL starting with jdbc:otel: and set the driver class to io.opentelemetry.instrumentation.jdbc.OpenTelemetryDriver.

spring.datasource.url=jdbc:otel:h2:mem:db
spring.datasource.driver-class-name=io.opentelemetry.instrumentation.jdbc.OpenTelemetryDriver

You can also wrap the DataSource bean in an io.opentelemetry.instrumentation.jdbc.datasource.OpenTelemetryDataSource:

import io.opentelemetry.instrumentation.jdbc.datasource.JdbcTelemetry;

@Configuration
public class DataSourceConfig {

	@Bean
	public DataSource dataSource(OpenTelemetry openTelemetry) {
		DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
		//Data source configurations
		DataSource dataSource = dataSourceBuilder.build();
		return JdbcTelemetry.create(openTelemetry).wrap(dataSource);
	}

}

With the datasource configuration, you need to add the following dependency:

<dependencies>
	<dependency>
		<groupId>io.opentelemetry.instrumentation</groupId>
		<artifactId>opentelemetry-jdbc</artifactId>
	</dependency>
</dependencies>
dependencies {
	implementation("io.opentelemetry.instrumentation:opentelemetry-jdbc")
}

Logging Instrumentation

To enable the logging instrumentation for Logback you have to add the OpenTelemetry appender in your logback.xml or logback-spring.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>
				%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
			</pattern>
		</encoder>
	</appender>
	<appender name="OpenTelemetry"
		class="io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender">
	</appender>
	<root level="INFO">
		<appender-ref ref="console"/>
		<appender-ref ref="OpenTelemetry"/>
	</root>
</configuration>

For Log4j 2, you have to add the OpenTelemetry appender to your log4j2.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" packages="io.opentelemetry.instrumentation.log4j.appender.v2_17">
	<Appenders>
		<OpenTelemetry name="OpenTelemetryAppender"/>
	</Appenders>
	<Loggers>
		<Root>
			<AppenderRef ref="OpenTelemetryAppender" level="All"/>
		</Root>
	</Loggers>
</Configuration>

You can find more configuration options for the OpenTelemetry appender in the documentation of the Logback and Log4j instrumentation libraries.

Instrumentation Annotations

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. To learn more about aspect weaving in spring, see spring-aop.

FeaturePropertyDefault ValueConditionalOnClass
@WithSpanotel.instrumentation.annotations.enabledtrueWithSpan, Aspect

Dependency

<dependencies>
  <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>1.34.1</version>
  </dependency>
</dependencies>
dependencies {
  implementation("org.springframework:spring-aop:SPRING_VERSION")
  implementation("io.opentelemetry:opentelemetry-extension-annotations:1.34.1")
}

Usage

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) {
    }
}

OpenTelemetry instrumentations libraries

You can configure other instrumentations with OpenTelemetry instrumentations libraries.

Other configurations

Instead of using the OpenTelemetry Spring starter, you can use the OpenTelemetry autoconfiguration features with an annotation or the Zipkin starter.

Spring support

Autoconfiguration is natively supported by Spring Boot 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 {}

Zipkin starter

OpenTelemetry Zipkin Exporter Starter is a starter package that includes the opentelemetry-api, opentelemetry-sdk, opentelemetry-extension-annotations, opentelemetry-logging-exporter, opentelemetry-spring-boot-autoconfigurations and spring framework starters required to setup distributed tracing. It also provides the opentelemetry-exporters-zipkin artifact and corresponding exporter autoconfiguration. Check out opentelemetry-spring-boot-autoconfigure for the list of supported libraries and features.

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.

<dependencies>
  <dependency>
    <groupId>io.opentelemetry</groupId>
    <artifactId>opentelemetry-exporter-zipkin</artifactId>
    <version>1.34.1</version>
  </dependency>
</dependencies>
dependencies {
  implementation("io.opentelemetry:opentelemetry-exporter-zipkin:1.34.1")
}

Configurations

PropertyDefault ValueConditionalOnClass
otel.exporter.zipkin.enabledtrueZipkinSpanExporter
Last modified February 6, 2024: Update spring-boot.md (#3946) (11d55a76)