SDK configuration

This spring starter supports configuration metadata, which means that you can see and autocomplete all available properties in your IDE.

General configuration

The OpenTelemetry Starter supports all the SDK Autoconfiguration (since 2.2.0).

You can update the configuration with properties in the application.properties or the application.yaml file, or with environment variables.

application.properties example:

otel.propagators=tracecontext,b3
otel.resource.attributes.deployment.environment=dev
otel.resource.attributes.service.name=cart
otel.resource.attributes.service.namespace=shop

application.yaml example:

otel:
  propagators:
    - tracecontext
    - b3
  resource:
    attributes:
      deployment.environment: dev
      service:
        name: cart
        namespace: shop

Environment variables example:

export OTEL_PROPAGATORS="tracecontext,b3"
export OTEL_RESOURCE_ATTRIBUTES="deployment.environment=dev,service.name=cart,service.namespace=shop"

Overriding Resource Attributes

As usual in Spring Boot, you can override properties in the application.properties and application.yaml files with environment variables.

For example, you can set or override the deployment.environment resource attribute (not changing service.name or service.namespace) by setting the standard OTEL_RESOURCE_ATTRIBUTES environment variable:

export OTEL_RESOURCE_ATTRIBUTES="deployment.environment=prod"

Alternatively, you can use the OTEL_RESOURCE_ATTRIBUTES_DEPLOYMENT_ENVIRONMENT environment variable to set or override a single resource attribute:

export OTEL_RESOURCE_ATTRIBUTES_DEPLOYMENT_ENVIRONMENT="prod"

The second option supports SpEL expressions.

Note that DEPLOYMENT_ENVIRONMENT gets converted to deployment.environment by Spring Boot’s Relaxed Binding.

Disable the OpenTelemetry Starter

System property: otel.sdk.disabledEnvironment variable: OTEL_SDK_DISABLED

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

Programmatic configuration

You can use the AutoConfigurationCustomizerProvider for programmatic configuration. Programmatic configuration is recommended for advanced use cases, which are not configurable using properties.

Exclude actuator endpoints from tracing

As an example, you can customize the sampler to exclude health check endpoints from tracing:

<dependencies>
  <dependency>
    <groupId>io.opentelemetry.contrib</groupId>
    <artifactId>opentelemetry-samplers</artifactId>
    <version>1.33.0-alpha</version>
  </dependency>
</dependencies>
dependencies {
  implementation("io.opentelemetry.contrib:opentelemetry-samplers:1.33.0-alpha")
}
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.contrib.sampler.RuleBasedRoutingSampler;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
import io.opentelemetry.semconv.SemanticAttributes;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class OpenTelemetryConfig {

  @Bean
  public AutoConfigurationCustomizerProvider otelCustomizer() {
    return p ->
        p.addSamplerCustomizer(
            (fallback, config) ->
                RuleBasedRoutingSampler.builder(SpanKind.SERVER, fallback)
                    .drop(SemanticAttributes.URL_PATH, "^/actuator")
                    .build());
  }
}

Configure the exporter programmatically

You can also configure OTLP exporters programmatically. This configuration replaces the default OTLP exporter and adds a custom header to the requests.

import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
import java.util.Collections;
import java.util.Map;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class OpenTelemetryConfig {

  @Bean
  public AutoConfigurationCustomizerProvider otelCustomizer() {
    return p ->
        p.addSpanExporterCustomizer(
            (exporter, config) -> {
              if (exporter instanceof OtlpHttpSpanExporter) {
                return ((OtlpHttpSpanExporter) exporter)
                    .toBuilder().setHeaders(this::headers).build();
              }
              return exporter;
            });
  }

  private Map<String, String> headers() {
    return Collections.singletonMap("Authorization", "Bearer " + refreshToken());
  }

  private String refreshToken() {
    // e.g. read the token from a kubernetes secret
    return "token";
  }
}

Resource Providers

The OpenTelemetry Starter includes the same resource providers as the Java agent:

In addition, the OpenTelemetry Starter includes the following Spring Boot specific resource providers:

Distribution Resource Provider

FQN: io.opentelemetry.instrumentation.spring.autoconfigure.resources.DistroVersionResourceProvider

AttributeValue
telemetry.distro.nameopentelemetry-spring-boot-starter
telemetry.distro.versionversion of the starter

Spring Resource Provider

FQN: io.opentelemetry.instrumentation.spring.autoconfigure.resources.SpringResourceProvider

AttributeValue
service.namespring.application.name or build.version from build-info.properties (see Service name)
service.versionbuild.name from build-info.properties

Service name

Using these resource providers, 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. spring.application.name spring property
  4. build-info.properties
  5. Implementation-Title from META-INF/MANIFEST.MF
  6. The default value is unknown_service:java (lowest precedence)

Use the following snippet in your pom.xml file to generate the build-info.properties file:

<build>
    <finalName>${project.artifactId}</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>build-info</goal>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
springBoot {
  buildInfo {
  }
}