diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java index ca177c14e7fb..fd7b48db6e9f 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java @@ -33,29 +33,37 @@ @EnableConfigurationProperties(SamplerProperties.class) public class OpenTelemetryAutoConfiguration { - @Bean - @ConditionalOnMissingBean - public OpenTelemetry openTelemetry( - SamplerProperties samplerProperties, - ObjectProvider propagatorsProvider, - ObjectProvider> spanExportersProvider) { - SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder(); - - spanExportersProvider.getIfAvailable(Collections::emptyList).stream() - // todo SimpleSpanProcessor...is that really what we want here? - .map(SimpleSpanProcessor::create) - .forEach(tracerProviderBuilder::addSpanProcessor); - - SdkTracerProvider tracerProvider = - tracerProviderBuilder - .setSampler(Sampler.traceIdRatioBased(samplerProperties.getProbability())) - .build(); - - ContextPropagators propagators = propagatorsProvider.getIfAvailable(ContextPropagators::noop); - - return OpenTelemetrySdk.builder() - .setTracerProvider(tracerProvider) - .setPropagators(propagators) - .build(); + @Configuration + @ConditionalOnMissingBean(OpenTelemetry.class) + public static class OpenTelemetryBeanConfig { + + @Bean(destroyMethod = "close") + @ConditionalOnMissingBean + public SdkTracerProvider sdkTracerProvider( + SamplerProperties samplerProperties, + ObjectProvider> spanExportersProvider) { + SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder(); + + spanExportersProvider.getIfAvailable(Collections::emptyList).stream() + // todo SimpleSpanProcessor...is that really what we want here? + .map(SimpleSpanProcessor::create) + .forEach(tracerProviderBuilder::addSpanProcessor); + + return tracerProviderBuilder + .setSampler(Sampler.traceIdRatioBased(samplerProperties.getProbability())) + .build(); + } + + @Bean + public OpenTelemetry openTelemetry( + ObjectProvider propagatorsProvider, SdkTracerProvider tracerProvider) { + + ContextPropagators propagators = propagatorsProvider.getIfAvailable(ContextPropagators::noop); + + return OpenTelemetrySdk.builder() + .setTracerProvider(tracerProvider) + .setPropagators(propagators) + .build(); + } } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfigurationTest.java index 2dd8fccfcda8..c7671717082b 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfigurationTest.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.sdk.trace.SdkTracerProvider; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -37,23 +38,42 @@ void tearDown() { @Test @DisplayName( "when Application Context contains OpenTelemetry bean should NOT initialize openTelemetry") - void customTracer() { + void customOpenTelemetry() { this.contextRunner .withUserConfiguration(CustomTracerConfiguration.class) .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)) .run( - context -> { - assertThat(context.containsBean("customOpenTelemetry")).isTrue(); - assertThat(context.containsBean("openTelemetry")).isFalse(); - }); + context -> + assertThat(context) + .hasBean("customOpenTelemetry") + .doesNotHaveBean("openTelemetry") + .doesNotHaveBean("sdkTracerProvider")); } @Test @DisplayName( "when Application Context DOES NOT contain OpenTelemetry bean should initialize openTelemetry") - void initializeTracer() { + void initializeTracerProviderAndOpenTelemetry() { this.contextRunner .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)) - .run(context -> assertThat(context.containsBean("openTelemetry")).isTrue()); + .run(context -> assertThat(context).hasBean("openTelemetry").hasBean("sdkTracerProvider")); + } + + @Test + @DisplayName( + "when Application Context DOES NOT contain OpenTelemetry bean but TracerProvider should initialize openTelemetry") + void initializeOpenTelemetry() { + this.contextRunner + .withBean( + "customTracerProvider", + SdkTracerProvider.class, + () -> SdkTracerProvider.builder().build()) + .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)) + .run( + context -> + assertThat(context) + .hasBean("openTelemetry") + .hasBean("customTracerProvider") + .doesNotHaveBean("sdkTracerProvider")); } }