Polish "Add auto-configuration for OTLP span exporter"
See gh-34508
This commit is contained in:
parent
ceaafeca0b
commit
c543d9172c
|
@ -22,6 +22,7 @@ import io.micrometer.tracing.otel.bridge.OtelTracer;
|
||||||
import io.opentelemetry.api.OpenTelemetry;
|
import io.opentelemetry.api.OpenTelemetry;
|
||||||
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
|
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
|
||||||
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder;
|
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder;
|
||||||
|
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
|
||||||
import io.opentelemetry.sdk.trace.SdkTracerProvider;
|
import io.opentelemetry.sdk.trace.SdkTracerProvider;
|
||||||
|
|
||||||
import org.springframework.boot.actuate.autoconfigure.tracing.ConditionalOnEnabledTracing;
|
import org.springframework.boot.actuate.autoconfigure.tracing.ConditionalOnEnabledTracing;
|
||||||
|
@ -41,7 +42,7 @@ import org.springframework.context.annotation.Bean;
|
||||||
* "https://github.com/open-telemetry/opentelemetry-java/issues/3651">opentelemetry-java#3651</a>.
|
* "https://github.com/open-telemetry/opentelemetry-java/issues/3651">opentelemetry-java#3651</a>.
|
||||||
* Because this class configures components from the OTel SDK, it can't support HTTP/JSON.
|
* 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,
|
* 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
|
* @author Jonatan Ivanov
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
|
@ -53,19 +54,17 @@ import org.springframework.context.annotation.Bean;
|
||||||
public class OtlpAutoConfiguration {
|
public class OtlpAutoConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean(value = OtlpHttpSpanExporter.class,
|
||||||
|
type = "io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter")
|
||||||
OtlpHttpSpanExporter otlpHttpSpanExporter(OtlpProperties properties) {
|
OtlpHttpSpanExporter otlpHttpSpanExporter(OtlpProperties properties) {
|
||||||
OtlpHttpSpanExporterBuilder builder = OtlpHttpSpanExporter.builder()
|
OtlpHttpSpanExporterBuilder builder = OtlpHttpSpanExporter.builder()
|
||||||
.setEndpoint(properties.getEndpoint())
|
.setEndpoint(properties.getEndpoint())
|
||||||
.setTimeout(properties.getTimeout())
|
.setTimeout(properties.getTimeout())
|
||||||
.setCompression(properties.getCompression().name().toLowerCase());
|
.setCompression(properties.getCompression().name().toLowerCase());
|
||||||
|
|
||||||
for (Entry<String, String> header : properties.getHeaders().entrySet()) {
|
for (Entry<String, String> header : properties.getHeaders().entrySet()) {
|
||||||
builder.addHeader(header.getKey(), header.getValue());
|
builder.addHeader(header.getKey(), header.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ import java.util.Map;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration properties for {@link OtlpAutoConfiguration}.
|
* Configuration properties for exporting traces using OTLP.
|
||||||
*
|
*
|
||||||
* @author Jonatan Ivanov
|
* @author Jonatan Ivanov
|
||||||
* @since 3.1.0
|
* @since 3.1.0
|
||||||
|
|
|
@ -54,11 +54,10 @@ class OtlpAutoConfigurationIntegrationTests {
|
||||||
AutoConfigurations.of(ObservationAutoConfiguration.class, MicrometerTracingAutoConfiguration.class,
|
AutoConfigurations.of(ObservationAutoConfiguration.class, MicrometerTracingAutoConfiguration.class,
|
||||||
OpenTelemetryAutoConfiguration.class, OtlpAutoConfiguration.class));
|
OpenTelemetryAutoConfiguration.class, OtlpAutoConfiguration.class));
|
||||||
|
|
||||||
private MockWebServer mockWebServer;
|
private final MockWebServer mockWebServer = new MockWebServer();
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setUp() throws IOException {
|
void setUp() throws IOException {
|
||||||
this.mockWebServer = new MockWebServer();
|
|
||||||
this.mockWebServer.start();
|
this.mockWebServer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +67,7 @@ class OtlpAutoConfigurationIntegrationTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void httpSpanExporterShouldUseProtoBufAndNoCompression() {
|
void httpSpanExporterShouldUseProtoBufAndNoCompressionByDefault() {
|
||||||
this.mockWebServer.enqueue(new MockResponse());
|
this.mockWebServer.enqueue(new MockResponse());
|
||||||
this.contextRunner
|
this.contextRunner
|
||||||
.withPropertyValues("management.otlp.tracing.endpoint=http://localhost:%d/v1/traces"
|
.withPropertyValues("management.otlp.tracing.endpoint=http://localhost:%d/v1/traces"
|
||||||
|
@ -77,7 +76,6 @@ class OtlpAutoConfigurationIntegrationTests {
|
||||||
context.getBean(Tracer.class).nextSpan().name("test").end();
|
context.getBean(Tracer.class).nextSpan().name("test").end();
|
||||||
assertThat(context.getBean(OtlpHttpSpanExporter.class).flush())
|
assertThat(context.getBean(OtlpHttpSpanExporter.class).flush())
|
||||||
.isSameAs(CompletableResultCode.ofSuccess());
|
.isSameAs(CompletableResultCode.ofSuccess());
|
||||||
|
|
||||||
RecordedRequest request = this.mockWebServer.takeRequest(10, TimeUnit.SECONDS);
|
RecordedRequest request = this.mockWebServer.takeRequest(10, TimeUnit.SECONDS);
|
||||||
assertThat(request).isNotNull();
|
assertThat(request).isNotNull();
|
||||||
assertThat(request.getRequestLine()).contains("/v1/traces");
|
assertThat(request.getRequestLine()).contains("/v1/traces");
|
||||||
|
@ -91,17 +89,16 @@ class OtlpAutoConfigurationIntegrationTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void httpSpanExporterShouldUseProtoBufAndGzip() {
|
void httpSpanExporterCanBeConfiguredToUseGzipCompression() {
|
||||||
this.mockWebServer.enqueue(new MockResponse());
|
this.mockWebServer.enqueue(new MockResponse());
|
||||||
this.contextRunner
|
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()))
|
"management.otlp.tracing.endpoint=http://localhost:%d/test".formatted(this.mockWebServer.getPort()))
|
||||||
.run((context) -> {
|
.run((context) -> {
|
||||||
assertThat(context).hasSingleBean(OtlpHttpSpanExporter.class).hasSingleBean(SpanExporter.class);
|
assertThat(context).hasSingleBean(OtlpHttpSpanExporter.class).hasSingleBean(SpanExporter.class);
|
||||||
context.getBean(Tracer.class).nextSpan().name("test").end();
|
context.getBean(Tracer.class).nextSpan().name("test").end();
|
||||||
assertThat(context.getBean(OtlpHttpSpanExporter.class).flush())
|
assertThat(context.getBean(OtlpHttpSpanExporter.class).flush())
|
||||||
.isSameAs(CompletableResultCode.ofSuccess());
|
.isSameAs(CompletableResultCode.ofSuccess());
|
||||||
|
|
||||||
RecordedRequest request = this.mockWebServer.takeRequest(10, TimeUnit.SECONDS);
|
RecordedRequest request = this.mockWebServer.takeRequest(10, TimeUnit.SECONDS);
|
||||||
assertThat(request).isNotNull();
|
assertThat(request).isNotNull();
|
||||||
assertThat(request.getRequestLine()).contains("/test");
|
assertThat(request.getRequestLine()).contains("/test");
|
||||||
|
|
|
@ -76,16 +76,15 @@ class OtlpAutoConfigurationTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldSupplyCustomHttpExporter() {
|
void shouldBackOffWhenCustomHttpExporterIsDefined() {
|
||||||
this.contextRunner.withUserConfiguration(CustomHttpExporterConfiguration.class)
|
this.contextRunner.withUserConfiguration(CustomHttpExporterConfiguration.class)
|
||||||
.run((context) -> assertThat(context).hasBean("customOtlpHttpSpanExporter")
|
.run((context) -> assertThat(context).hasBean("customOtlpHttpSpanExporter")
|
||||||
.hasSingleBean(SpanExporter.class));
|
.hasSingleBean(SpanExporter.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldSupplyCustomGrpcExporter() {
|
void shouldBackOffWhenCustomGrpcExporterIsDefined() {
|
||||||
this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.exporter"))
|
this.contextRunner.withUserConfiguration(CustomGrpcExporterConfiguration.class)
|
||||||
.withUserConfiguration(CustomGrpcExporterConfiguration.class)
|
|
||||||
.run((context) -> assertThat(context).hasBean("customOtlpGrpcSpanExporter")
|
.run((context) -> assertThat(context).hasBean("customOtlpGrpcSpanExporter")
|
||||||
.hasSingleBean(SpanExporter.class));
|
.hasSingleBean(SpanExporter.class));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue