From c543d9172c2675afd00ccfa852f33befe2dcfdde Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 19 Apr 2023 14:45:16 +0100 Subject: [PATCH] Polish "Add auto-configuration for OTLP span exporter" See gh-34508 --- .../tracing/otlp/OtlpAutoConfiguration.java | 9 ++++----- .../autoconfigure/tracing/otlp/OtlpProperties.java | 2 +- .../otlp/OtlpAutoConfigurationIntegrationTests.java | 11 ++++------- .../tracing/otlp/OtlpAutoConfigurationTests.java | 7 +++---- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfiguration.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfiguration.java index ac27a4c58e81..c9493f0d0d99 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfiguration.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfiguration.java @@ -22,6 +22,7 @@ import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; +import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.sdk.trace.SdkTracerProvider; import org.springframework.boot.actuate.autoconfigure.tracing.ConditionalOnEnabledTracing; @@ -41,7 +42,7 @@ * "https://github.com/open-telemetry/opentelemetry-java/issues/3651">opentelemetry-java#3651. * Because this class configures components from the OTel SDK, it can't support HTTP/JSON. * To keep things simple, we only auto-configure HTTP/protobuf. If you want to use gRPC, - * please disable this auto-configuration and create a bean. + * define an {@link OtlpGrpcSpanExporter} and this auto-configuration will back off. * * @author Jonatan Ivanov * @since 3.1.0 @@ -53,19 +54,17 @@ public class OtlpAutoConfiguration { @Bean - @ConditionalOnMissingBean + @ConditionalOnMissingBean(value = OtlpHttpSpanExporter.class, + type = "io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter") OtlpHttpSpanExporter otlpHttpSpanExporter(OtlpProperties properties) { OtlpHttpSpanExporterBuilder builder = OtlpHttpSpanExporter.builder() .setEndpoint(properties.getEndpoint()) .setTimeout(properties.getTimeout()) .setCompression(properties.getCompression().name().toLowerCase()); - for (Entry header : properties.getHeaders().entrySet()) { builder.addHeader(header.getKey(), header.getValue()); } - return builder.build(); - } } diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpProperties.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpProperties.java index f767ec44c0fa..d0270433c3f2 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpProperties.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpProperties.java @@ -23,7 +23,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties; /** - * Configuration properties for {@link OtlpAutoConfiguration}. + * Configuration properties for exporting traces using OTLP. * * @author Jonatan Ivanov * @since 3.1.0 diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfigurationIntegrationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfigurationIntegrationTests.java index c43efa049407..a6e853bd272d 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfigurationIntegrationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfigurationIntegrationTests.java @@ -54,11 +54,10 @@ class OtlpAutoConfigurationIntegrationTests { AutoConfigurations.of(ObservationAutoConfiguration.class, MicrometerTracingAutoConfiguration.class, OpenTelemetryAutoConfiguration.class, OtlpAutoConfiguration.class)); - private MockWebServer mockWebServer; + private final MockWebServer mockWebServer = new MockWebServer(); @BeforeEach void setUp() throws IOException { - this.mockWebServer = new MockWebServer(); this.mockWebServer.start(); } @@ -68,7 +67,7 @@ void tearDown() throws IOException { } @Test - void httpSpanExporterShouldUseProtoBufAndNoCompression() { + void httpSpanExporterShouldUseProtoBufAndNoCompressionByDefault() { this.mockWebServer.enqueue(new MockResponse()); this.contextRunner .withPropertyValues("management.otlp.tracing.endpoint=http://localhost:%d/v1/traces" @@ -77,7 +76,6 @@ void httpSpanExporterShouldUseProtoBufAndNoCompression() { context.getBean(Tracer.class).nextSpan().name("test").end(); assertThat(context.getBean(OtlpHttpSpanExporter.class).flush()) .isSameAs(CompletableResultCode.ofSuccess()); - RecordedRequest request = this.mockWebServer.takeRequest(10, TimeUnit.SECONDS); assertThat(request).isNotNull(); assertThat(request.getRequestLine()).contains("/v1/traces"); @@ -91,17 +89,16 @@ void httpSpanExporterShouldUseProtoBufAndNoCompression() { } @Test - void httpSpanExporterShouldUseProtoBufAndGzip() { + void httpSpanExporterCanBeConfiguredToUseGzipCompression() { this.mockWebServer.enqueue(new MockResponse()); this.contextRunner - .withPropertyValues("management.otlp.tracing.compression=GZIP", + .withPropertyValues("management.otlp.tracing.compression=gzip", "management.otlp.tracing.endpoint=http://localhost:%d/test".formatted(this.mockWebServer.getPort())) .run((context) -> { assertThat(context).hasSingleBean(OtlpHttpSpanExporter.class).hasSingleBean(SpanExporter.class); context.getBean(Tracer.class).nextSpan().name("test").end(); assertThat(context.getBean(OtlpHttpSpanExporter.class).flush()) .isSameAs(CompletableResultCode.ofSuccess()); - RecordedRequest request = this.mockWebServer.takeRequest(10, TimeUnit.SECONDS); assertThat(request).isNotNull(); assertThat(request.getRequestLine()).contains("/test"); diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfigurationTests.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfigurationTests.java index ede4f321c41f..5d75c06b5112 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/tracing/otlp/OtlpAutoConfigurationTests.java @@ -76,16 +76,15 @@ void shouldNotSupplyBeansIfExporterIsMissing() { } @Test - void shouldSupplyCustomHttpExporter() { + void shouldBackOffWhenCustomHttpExporterIsDefined() { this.contextRunner.withUserConfiguration(CustomHttpExporterConfiguration.class) .run((context) -> assertThat(context).hasBean("customOtlpHttpSpanExporter") .hasSingleBean(SpanExporter.class)); } @Test - void shouldSupplyCustomGrpcExporter() { - this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.exporter")) - .withUserConfiguration(CustomGrpcExporterConfiguration.class) + void shouldBackOffWhenCustomGrpcExporterIsDefined() { + this.contextRunner.withUserConfiguration(CustomGrpcExporterConfiguration.class) .run((context) -> assertThat(context).hasBean("customOtlpGrpcSpanExporter") .hasSingleBean(SpanExporter.class)); }