Spring starter should support otel.propagators (#10408)

This commit is contained in:
Gregor Zeitlinger 2024-02-13 19:02:07 +01:00 committed by GitHub
parent 3d2ca02ee6
commit 76ab93780e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 143 additions and 13 deletions

View File

@ -8,6 +8,7 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.propagators;
import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
@ -24,6 +25,7 @@ import org.springframework.context.annotation.Configuration;
@EnableConfigurationProperties(PropagationProperties.class) @EnableConfigurationProperties(PropagationProperties.class)
@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class) @AutoConfigureBefore(OpenTelemetryAutoConfiguration.class)
@ConditionalOnProperty(prefix = "otel.propagation", name = "enabled", matchIfMissing = true) @ConditionalOnProperty(prefix = "otel.propagation", name = "enabled", matchIfMissing = true)
@SuppressWarnings("deprecation")
public class PropagationAutoConfiguration { public class PropagationAutoConfiguration {
@Bean @Bean
@ -41,9 +43,11 @@ public class PropagationAutoConfiguration {
@Bean @Bean
TextMapPropagator compositeTextMapPropagator( TextMapPropagator compositeTextMapPropagator(
BeanFactory beanFactory, PropagationProperties properties) { BeanFactory beanFactory,
PropagationProperties properties,
ConfigProperties configProperties) {
return CompositeTextMapPropagatorFactory.getCompositeTextMapPropagator( return CompositeTextMapPropagatorFactory.getCompositeTextMapPropagator(
beanFactory, properties.getType()); beanFactory, configProperties.getList("otel.propagators", properties.getType()));
} }
} }
} }

View File

@ -11,6 +11,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
/** Configuration for propagators. */ /** Configuration for propagators. */
@ConfigurationProperties(prefix = "otel.propagation") @ConfigurationProperties(prefix = "otel.propagation")
@Deprecated // use otel.propagators instead
public final class PropagationProperties { public final class PropagationProperties {
private List<String> type = Arrays.asList("tracecontext", "baggage"); private List<String> type = Arrays.asList("tracecontext", "baggage");

View File

@ -71,7 +71,8 @@ public class SpringConfigProperties implements ConfigProperties {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public List<String> getList(String name) { public List<String> getList(String name) {
return (List<String>) environment.getProperty(name, List.class); List<String> value = environment.getProperty(name, List.class);
return value == null ? Collections.emptyList() : value;
} }
@Nullable @Nullable

View File

@ -197,6 +197,30 @@
"description": "The Zipkin endpoint to connect to.<br/>Currently only HTTP is supported.", "description": "The Zipkin endpoint to connect to.<br/>Currently only HTTP is supported.",
"defaultValue": "http://localhost:9411/api/v2/spans" "defaultValue": "http://localhost:9411/api/v2/spans"
}, },
{
"name": "otel.instrumentation.annotations.enabled",
"type": "java.lang.Boolean",
"description": "Enable the <code>@WithSpan</code> annotation.",
"defaultValue": true
},
{
"name": "otel.instrumentation.kafka.enabled",
"type": "java.lang.Boolean",
"description": "Enable the Kafka instrumentation.",
"defaultValue": true
},
{
"name": "otel.instrumentation.log4j-appender.enabled",
"type": "java.lang.Boolean",
"description": "Enable the Log4J2 appender instrumentation.",
"defaultValue": true
},
{
"name": "otel.instrumentation.logback-appender.enabled",
"type": "java.lang.Boolean",
"description": "Enable the Logback appender instrumentation.",
"defaultValue": true
},
{ {
"name": "otel.instrumentation.logback-appender.experimental.capture-code-attributes", "name": "otel.instrumentation.logback-appender.experimental.capture-code-attributes",
"type": "java.lang.Boolean", "type": "java.lang.Boolean",
@ -229,13 +253,37 @@
}, },
{ {
"name": "otel.instrumentation.logback-appender.experimental.capture-mdc-attributes", "name": "otel.instrumentation.logback-appender.experimental.capture-mdc-attributes",
"type": "java.lang.String", "type": "java.util.List<java.lang.String>",
"description": "Comma separated list of MDC attributes to capture. Use the wildcard character <code>*</code> to capture all attributes." "description": "MDC attributes to capture. Use the wildcard character <code>*</code> to capture all attributes."
},
{
"name": "otel.instrumentation.micrometer.enabled",
"type": "java.lang.Boolean",
"description": "Enable the Micrometer instrumentation.",
"defaultValue": false
},
{
"name": "otel.instrumentation.spring-web.enabled",
"type": "java.lang.Boolean",
"description": "Enable the RestTemplate instrumentation.",
"defaultValue": true
},
{
"name": "otel.instrumentation.spring-webflux.enabled",
"type": "java.lang.Boolean",
"description": "Enable the WebClient instrumentation.",
"defaultValue": true
},
{
"name": "otel.instrumentation.spring-webmvc.enabled",
"type": "java.lang.Boolean",
"description": "Enable the Servlet instrumentation.",
"defaultValue": true
}, },
{ {
"name": "otel.logs.exporter", "name": "otel.logs.exporter",
"type": "java.lang.String", "type": "java.util.List<java.lang.String>",
"description": "List of exporters to be used for logs, separated by commas.", "description": "List of exporters to be used for logs.",
"defaultValue": "otlp" "defaultValue": "otlp"
}, },
{ {
@ -246,14 +294,37 @@
}, },
{ {
"name": "otel.metrics.exporter", "name": "otel.metrics.exporter",
"type": "java.lang.String", "type": "java.util.List<java.lang.String>",
"description": "List of exporters to be used for metrics, separated by commas.", "description": "List of exporters to be used for metrics.",
"defaultValue": "otlp" "defaultValue": "otlp"
}, },
{
"name": "otel.propagators",
"type": "java.util.List<java.lang.String>",
"description": "List of propagators to be used for context propagation.",
"defaultValue": "tracecontext,baggage"
},
{
"name": "otel.resource.attributes",
"type": "java.util.Map<java.lang.String, java.lang.String>",
"description": "Resource attributes to be added to all spans. In addition to these attributes, the resource will also include attributes discovered from the runtime, such as <code>host.name</code> and <code>process.id</code>."
},
{
"name": "otel.sdk.disabled",
"type": "java.lang.Boolean",
"description": "Disable the OpenTelemetry Spring Starter.",
"defaultValue": false
},
{
"name": "otel.springboot.resource.enabled",
"type": "java.lang.Boolean",
"description": "Enable the resource auto-configuration.",
"defaultValue": true
},
{ {
"name": "otel.traces.exporter", "name": "otel.traces.exporter",
"type": "java.lang.String", "type": "java.util.List<java.lang.String>",
"description": "List of exporters to be used for tracing, separated by commas.", "description": "List of exporters to be used for tracing.",
"defaultValue": "otlp" "defaultValue": "otlp"
}, },
{ {
@ -339,6 +410,10 @@
{ {
"name": "otel.logs.exporter", "name": "otel.logs.exporter",
"values": [ "values": [
{
"value": "logging",
"description": "The logging exporter prints exported logs to stdout. It's mainly used for testing and debugging."
},
{ {
"value": "none", "value": "none",
"description": "No autoconfigured exporter." "description": "No autoconfigured exporter."
@ -366,6 +441,39 @@
} }
] ]
}, },
{
"name": "otel.propagators",
"values": [
{
"value": "baggage",
"description": "The Baggage propagator propagates baggage using the W3C Baggage format. See https://www.w3.org/TR/baggage/."
},
{
"value": "b3",
"description": "The B3 propagator propagates trace context using the B3 single-header format: See https://github.com/openzipkin/b3-propagation#single-header."
},
{
"value": "b3multi",
"description": "The B3 propagator propagates trace context using the B3 multi-header format: See https://github.com/openzipkin/b3-propagation#multiple-headers."
},
{
"value": "jaeger",
"description": "The Jaeger propagator propagates trace context using the Jaeger format. See https://www.jaegertracing.io/docs/1.21/client-libraries/#propagation-format."
},
{
"value": "ottrace",
"description": "The OpenTelemetry Trace Context propagator propagates trace context using the OpenTelemetry format. See https://github.com/opentracing/specification/blob/master/rfc/trace_identifiers.md."
},
{
"value": "tracecontext",
"description": "The Trace Context propagator propagates trace context using the W3C Trace Context format (add `baggage` as well to include W3C baggage). See https://www.w3.org/TR/trace-context/."
},
{
"value": "xray",
"description": "The AWS X-Ray propagator propagates trace context using the AWS X-Ray format. See https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader."
}
]
},
{ {
"name": "otel.traces.exporter", "name": "otel.traces.exporter",
"values": [ "values": [

View File

@ -92,8 +92,9 @@ class PropagationAutoConfigurationTest {
} }
@Test @Test
@DisplayName("when propagation is set to some values should contain only supported values") @DisplayName(
void shouldContainOnlySupported() { "when propagation is set to some values should contain only supported values - deprecated")
void shouldContainOnlySupportedDeprecated() {
this.contextRunner this.contextRunner
.withPropertyValues("otel.propagation.type=invalid,b3") .withPropertyValues("otel.propagation.type=invalid,b3")
.run( .run(
@ -104,4 +105,18 @@ class PropagationAutoConfigurationTest {
assertThat(compositePropagator.fields()).containsExactly("b3"); assertThat(compositePropagator.fields()).containsExactly("b3");
}); });
} }
@Test
@DisplayName("when propagation is set to some values should contain only supported values")
void shouldContainOnlySupported() {
this.contextRunner
.withPropertyValues("otel.propagators=invalid,b3")
.run(
context -> {
TextMapPropagator compositePropagator =
context.getBean("compositeTextMapPropagator", TextMapPropagator.class);
assertThat(compositePropagator.fields()).containsExactly("b3");
});
}
} }

View File

@ -14,6 +14,7 @@ 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;
@SuppressWarnings("deprecation") // test for deprecated code
public class PropagationPropertiesTest { public class PropagationPropertiesTest {
private final ApplicationContextRunner contextRunner = private final ApplicationContextRunner contextRunner =