Change Spring starter default otlp protocol from gRPC to http/protobuf (#10212)

This commit is contained in:
Jean Bisutti 2024-01-11 22:09:17 +01:00 committed by GitHub
parent 478404539d
commit 32ea07c1bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 112 additions and 20 deletions

View File

@ -8,14 +8,17 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;
import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil;
import java.time.Duration; import java.time.Duration;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class OtlpExporterUtil { class OtlpExporterUtil {
private OtlpExporterUtil() {} private OtlpExporterUtil() {}
private static final Logger logger = LoggerFactory.getLogger(OtlpExporterUtil.class);
static <G, H, E> E applySignalProperties( static <G, H, E> E applySignalProperties(
String dataType, String dataType,
OtlpExporterProperties properties, OtlpExporterProperties properties,
@ -39,7 +42,18 @@ class OtlpExporterUtil {
G grpcBuilder = newGrpcBuilder.get(); G grpcBuilder = newGrpcBuilder.get();
H httpBuilder = newHttpBuilder.get(); H httpBuilder = newHttpBuilder.get();
boolean isHttpProtobuf = Objects.equals(protocol, OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF); boolean isHttpProtobuf = !"grpc".equals(protocol);
if (protocol != null
&& !OtlpConfigUtil.PROTOCOL_GRPC.equals(protocol)
&& !OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF.equals(protocol)) {
logger.warn(
"Unknown OTLP protocol '"
+ protocol
+ "', using '"
+ OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF
+ "'.");
}
String endpoint = signalProperties.getEndpoint(); String endpoint = signalProperties.getEndpoint();
if (endpoint == null) { if (endpoint == null) {

View File

@ -8,7 +8,7 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.exporters;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.exporter.logging.LoggingMetricExporter; import io.opentelemetry.exporter.logging.LoggingMetricExporter;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingMetricExporterAutoConfiguration; import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingMetricExporterAutoConfiguration;
import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpMetricExporterAutoConfiguration; import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpMetricExporterAutoConfiguration;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -28,7 +28,7 @@ class MetricExporterAutoConfigurationTest {
void defaultConfiguration() { void defaultConfiguration() {
contextRunner.run( contextRunner.run(
context -> { context -> {
assertThat(context.getBean("otelOtlpMetricExporter", OtlpGrpcMetricExporter.class)) assertThat(context.getBean("otelOtlpMetricExporter", OtlpHttpMetricExporter.class))
.as("OTLP exporter is enabled by default") .as("OTLP exporter is enabled by default")
.isNotNull(); .isNotNull();
assertThat(context.containsBean("otelLoggingMetricExporter")) assertThat(context.containsBean("otelLoggingMetricExporter"))
@ -43,7 +43,7 @@ class MetricExporterAutoConfigurationTest {
.withPropertyValues("otel.exporter.logging.enabled=true") .withPropertyValues("otel.exporter.logging.enabled=true")
.run( .run(
context -> { context -> {
assertThat(context.getBean("otelOtlpMetricExporter", OtlpGrpcMetricExporter.class)) assertThat(context.getBean("otelOtlpMetricExporter", OtlpHttpMetricExporter.class))
.as("OTLP exporter is present even with logging enabled") .as("OTLP exporter is present even with logging enabled")
.isNotNull(); .isNotNull();
assertThat(context.getBean("otelLoggingMetricExporter", LoggingMetricExporter.class)) assertThat(context.getBean("otelLoggingMetricExporter", LoggingMetricExporter.class))

View File

@ -8,7 +8,7 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.exporters;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.exporter.logging.LoggingSpanExporter; import io.opentelemetry.exporter.logging.LoggingSpanExporter;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingSpanExporterAutoConfiguration; import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingSpanExporterAutoConfiguration;
import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpSpanExporterAutoConfiguration; import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpSpanExporterAutoConfiguration;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -28,7 +28,7 @@ class SpanExporterAutoConfigurationTest {
void defaultConfiguration() { void defaultConfiguration() {
contextRunner.run( contextRunner.run(
context -> { context -> {
assertThat(context.getBean("otelOtlpSpanExporter", OtlpGrpcSpanExporter.class)) assertThat(context.getBean("otelOtlpSpanExporter", OtlpHttpSpanExporter.class))
.as("OTLP exporter is enabled by default") .as("OTLP exporter is enabled by default")
.isNotNull(); .isNotNull();
assertThat(context.containsBean("otelLoggingSpanExporter")) assertThat(context.containsBean("otelLoggingSpanExporter"))
@ -43,7 +43,7 @@ class SpanExporterAutoConfigurationTest {
.withPropertyValues("otel.exporter.logging.enabled=true") .withPropertyValues("otel.exporter.logging.enabled=true")
.run( .run(
context -> { context -> {
assertThat(context.getBean("otelOtlpSpanExporter", OtlpGrpcSpanExporter.class)) assertThat(context.getBean("otelOtlpSpanExporter", OtlpHttpSpanExporter.class))
.as("OTLP exporter is present even with logging enabled") .as("OTLP exporter is present even with logging enabled")
.isNotNull(); .isNotNull();
assertThat(context.getBean("otelLoggingSpanExporter", LoggingSpanExporter.class)) assertThat(context.getBean("otelLoggingSpanExporter", LoggingSpanExporter.class))

View File

@ -7,9 +7,11 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
import io.opentelemetry.sdk.logs.export.LogRecordExporter; import io.opentelemetry.sdk.logs.export.LogRecordExporter;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@ -64,11 +66,37 @@ class OtlpLogExporterAutoConfigurationTest {
} }
@Test @Test
void loggerPresentByDefault() { void otlpHttpUsedByDefault() {
runner.run( runner.run(
context -> context ->
assertThat( assertThat(
context.getBean("otelOtlpLogRecordExporter", OtlpGrpcLogRecordExporter.class)) context.getBean("otelOtlpLogRecordExporter", OtlpHttpLogRecordExporter.class))
.isNotNull()); .isNotNull());
} }
@Test
@DisplayName("use grpc when protocol set")
void useGrpc() {
runner
.withPropertyValues("otel.exporter.otlp.protocol=grpc")
.run(
context ->
assertThat(
context.getBean(
"otelOtlpLogRecordExporter", OtlpGrpcLogRecordExporter.class))
.isNotNull());
}
@Test
@DisplayName("use http when unknown protocol set")
void useHttpWhenAnUnknownProtocolIsSet() {
runner
.withPropertyValues("otel.exporter.otlp.protocol=unknown")
.run(
context ->
assertThat(
context.getBean(
"otelOtlpLogRecordExporter", OtlpHttpLogRecordExporter.class))
.isNotNull());
}
} }

View File

@ -7,8 +7,10 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@ -25,19 +27,41 @@ class OtlpMetricExporterAutoConfigurationTest {
void otlpEnabled() { void otlpEnabled() {
runner runner
.withPropertyValues("otel.exporter.otlp.enabled=true") .withPropertyValues("otel.exporter.otlp.enabled=true")
.run(
context ->
assertThat(context.getBean("otelOtlpMetricExporter", OtlpHttpMetricExporter.class))
.isNotNull());
}
@Test
@DisplayName("use grpc when protocol set")
void useGrpc() {
runner
.withPropertyValues("otel.exporter.otlp.protocol=grpc")
.run( .run(
context -> context ->
assertThat(context.getBean("otelOtlpMetricExporter", OtlpGrpcMetricExporter.class)) assertThat(context.getBean("otelOtlpMetricExporter", OtlpGrpcMetricExporter.class))
.isNotNull()); .isNotNull());
} }
@Test
@DisplayName("use http when unknown protocol set")
void useHttpWhenAnUnknownProtocolIsSet() {
runner
.withPropertyValues("otel.exporter.otlp.protocol=unknown")
.run(
context ->
assertThat(context.getBean("otelOtlpMetricExporter", OtlpHttpMetricExporter.class))
.isNotNull());
}
@Test @Test
void otlpMetricsEnabled() { void otlpMetricsEnabled() {
runner runner
.withPropertyValues("otel.exporter.otlp.metrics.enabled=true") .withPropertyValues("otel.exporter.otlp.metrics.enabled=true")
.run( .run(
context -> context ->
assertThat(context.getBean("otelOtlpMetricExporter", OtlpGrpcMetricExporter.class)) assertThat(context.getBean("otelOtlpMetricExporter", OtlpHttpMetricExporter.class))
.isNotNull()); .isNotNull());
} }
@ -63,10 +87,10 @@ class OtlpMetricExporterAutoConfigurationTest {
} }
@Test @Test
void exporterPresentByDefault() { void otlpHttpUsedByDefault() {
runner.run( runner.run(
context -> context ->
assertThat(context.getBean("otelOtlpMetricExporter", OtlpGrpcMetricExporter.class)) assertThat(context.getBean("otelOtlpMetricExporter", OtlpHttpMetricExporter.class))
.isNotNull()); .isNotNull());
} }
} }

View File

@ -8,6 +8,7 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp;
import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.exporter.logging.LoggingSpanExporter; import io.opentelemetry.exporter.logging.LoggingSpanExporter;
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.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.instrumentation.spring.autoconfigure.MapConverterTestAutoConfiguration; import io.opentelemetry.instrumentation.spring.autoconfigure.MapConverterTestAutoConfiguration;
@ -31,17 +32,16 @@ class OtlpSpanExporterAutoConfigurationTest {
AutoConfigurations.of( AutoConfigurations.of(
OpenTelemetryAutoConfiguration.class, OpenTelemetryAutoConfiguration.class,
OtlpSpanExporterAutoConfiguration.class, OtlpSpanExporterAutoConfiguration.class,
MapConverterTestAutoConfiguration.class)) MapConverterTestAutoConfiguration.class));
.withBean(OtlpHttpSpanExporterBuilder.class, () -> otlpHttpSpanExporterBuilder);
@Test @Test
@DisplayName("when exporters are ENABLED should initialize OtlpGrpcSpanExporter bean") @DisplayName("when exporters are ENABLED should initialize OtlpHttpSpanExporter bean")
void otlpEnabled() { void otlpEnabled() {
this.contextRunner this.contextRunner
.withPropertyValues("otel.exporter.otlp.enabled=true") .withPropertyValues("otel.exporter.otlp.enabled=true")
.run( .run(
context -> context ->
assertThat(context.getBean("otelOtlpSpanExporter", OtlpGrpcSpanExporter.class)) assertThat(context.getBean("otelOtlpSpanExporter", OtlpHttpSpanExporter.class))
.isNotNull()); .isNotNull());
Mockito.verifyNoMoreInteractions(otlpHttpSpanExporterBuilder); Mockito.verifyNoMoreInteractions(otlpHttpSpanExporterBuilder);
@ -53,7 +53,7 @@ class OtlpSpanExporterAutoConfigurationTest {
.withPropertyValues("otel.exporter.otlp.traces.enabled=true") .withPropertyValues("otel.exporter.otlp.traces.enabled=true")
.run( .run(
context -> context ->
assertThat(context.getBean("otelOtlpSpanExporter", OtlpGrpcSpanExporter.class)) assertThat(context.getBean("otelOtlpSpanExporter", OtlpHttpSpanExporter.class))
.isNotNull()); .isNotNull());
} }
@ -80,11 +80,11 @@ class OtlpSpanExporterAutoConfigurationTest {
} }
@Test @Test
@DisplayName("when otlp enabled property is MISSING should initialize OtlpGrpcSpanExporter bean") @DisplayName("when otlp enabled property is MISSING should initialize OtlpHttpSpanExporter bean")
void exporterPresentByDefault() { void exporterPresentByDefault() {
this.contextRunner.run( this.contextRunner.run(
context -> context ->
assertThat(context.getBean("otelOtlpSpanExporter", OtlpGrpcSpanExporter.class)) assertThat(context.getBean("otelOtlpSpanExporter", OtlpHttpSpanExporter.class))
.isNotNull()); .isNotNull());
} }
@ -92,6 +92,7 @@ class OtlpSpanExporterAutoConfigurationTest {
@DisplayName("use http/protobuf when protocol set") @DisplayName("use http/protobuf when protocol set")
void useHttp() { void useHttp() {
this.contextRunner this.contextRunner
.withBean(OtlpHttpSpanExporterBuilder.class, () -> otlpHttpSpanExporterBuilder)
.withPropertyValues( .withPropertyValues(
"otel.exporter.otlp.enabled=true", "otel.exporter.otlp.enabled=true",
"otel.exporter.otlp.protocol=http/protobuf", "otel.exporter.otlp.protocol=http/protobuf",
@ -113,6 +114,7 @@ class OtlpSpanExporterAutoConfigurationTest {
@DisplayName("use http/protobuf with environment variables for headers using the MapConverter") @DisplayName("use http/protobuf with environment variables for headers using the MapConverter")
void useHttpWithEnv() { void useHttpWithEnv() {
this.contextRunner this.contextRunner
.withBean(OtlpHttpSpanExporterBuilder.class, () -> otlpHttpSpanExporterBuilder)
.withPropertyValues( .withPropertyValues(
"otel.exporter.otlp.enabled=true", "otel.exporter.otlp.protocol=http/protobuf") "otel.exporter.otlp.enabled=true", "otel.exporter.otlp.protocol=http/protobuf")
// are similar to environment variables in that they use the same converters // are similar to environment variables in that they use the same converters
@ -125,6 +127,30 @@ class OtlpSpanExporterAutoConfigurationTest {
Mockito.verifyNoMoreInteractions(otlpHttpSpanExporterBuilder); Mockito.verifyNoMoreInteractions(otlpHttpSpanExporterBuilder);
} }
@Test
@DisplayName("use grpc when protocol set")
void useGrpc() {
this.contextRunner
.withPropertyValues("otel.exporter.otlp.protocol=grpc")
.run(
context ->
assertThat(context.getBean(OtlpGrpcSpanExporter.class))
.as("Should contain the gRPC span exporter when grpc is set")
.isNotNull());
}
@Test
@DisplayName("use http when unknown protocol set")
void useHttpWhenAnUnknownProtocolIsSet() {
this.contextRunner
.withPropertyValues("otel.exporter.otlp.protocol=unknown")
.run(
context ->
assertThat(context.getBean(OtlpHttpSpanExporter.class))
.as("Should contain the http span exporter when an unknown is set")
.isNotNull());
}
@Test @Test
@DisplayName("logging exporter can still be configured") @DisplayName("logging exporter can still be configured")
void loggingExporter() { void loggingExporter() {