diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-spring-boot-autoconfigure.txt b/docs/apidiffs/current_vs_latest/opentelemetry-spring-boot-autoconfigure.txt index d3e20fa534c7..6c7737054da6 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-spring-boot-autoconfigure.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-spring-boot-autoconfigure.txt @@ -1,2 +1,5 @@ Comparing source compatibility of opentelemetry-spring-boot-autoconfigure-2.22.0-SNAPSHOT.jar against opentelemetry-spring-boot-autoconfigure-2.21.0.jar -No changes. \ No newline at end of file +=== UNCHANGED CLASS: PUBLIC io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + --- REMOVED ANNOTATION: org.springframework.boot.context.properties.EnableConfigurationProperties + --- REMOVED ELEMENT: value=io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.OtlpExporterProperties,io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.OtelResourceProperties,io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.OtelSpringProperties (-) diff --git a/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts b/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts index c3010d5e8aff..e50680a20f74 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts +++ b/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("otel.library-instrumentation") + id("otel.nullaway-conventions") } base.archivesName.set("opentelemetry-spring-boot-autoconfigure") @@ -35,6 +36,9 @@ dependencies { annotationProcessor("org.springframework.boot:spring-boot-autoconfigure-processor:$springBootVersion") annotationProcessor("org.springframework.boot:spring-boot-configuration-processor:$springBootVersion") implementation("javax.validation:validation-api") + // snake yaml is already used by "spring-boot-resources" + // and less likely to cause problems compared to jackson + implementation("org.snakeyaml:snakeyaml-engine") implementation(project(":instrumentation-annotations-support")) implementation(project(":instrumentation:kafka:kafka-clients:kafka-clients-2.6:library")) @@ -65,7 +69,9 @@ dependencies { library("org.springframework.boot:spring-boot-starter-data-jdbc:$springBootVersion") implementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") + implementation("io.opentelemetry:opentelemetry-sdk-extension-incubator") implementation(project(":sdk-autoconfigure-support")) + implementation(project(":declarative-config-bridge")) compileOnly("io.opentelemetry:opentelemetry-extension-trace-propagators") compileOnly("io.opentelemetry.contrib:opentelemetry-aws-xray-propagator") compileOnly("io.opentelemetry:opentelemetry-exporter-logging") @@ -80,6 +86,7 @@ dependencies { testLibrary("org.springframework.boot:spring-boot-starter-test:$springBootVersion") { exclude("org.junit.vintage", "junit-vintage-engine") } + testImplementation("javax.servlet:javax.servlet-api:3.1.0") testImplementation("jakarta.servlet:jakarta.servlet-api:5.0.0") testRuntimeOnly("com.h2database:h2:1.4.197") @@ -173,6 +180,17 @@ testing { } } } + + val testDeclarativeConfig by registering(JvmTestSuite::class) { + dependencies { + implementation(project()) + implementation("io.opentelemetry:opentelemetry-sdk") + implementation("org.springframework.boot:spring-boot-starter-test:$springBootVersion") { + exclude("org.junit.vintage", "junit-vintage-engine") + } + implementation("org.springframework.boot:spring-boot-starter-web:$springBootVersion") + } + } } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/EmbeddedConfigFile.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/EmbeddedConfigFile.java new file mode 100644 index 000000000000..195782a2e1f1 --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/EmbeddedConfigFile.java @@ -0,0 +1,91 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.spring.autoconfigure; + +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.annotation.Nullable; +import org.snakeyaml.engine.v2.api.Dump; +import org.snakeyaml.engine.v2.api.DumpSettings; +import org.snakeyaml.engine.v2.api.Load; +import org.snakeyaml.engine.v2.api.LoadSettings; +import org.springframework.boot.env.OriginTrackedMapPropertySource; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.PropertySource; + +class EmbeddedConfigFile { + + private EmbeddedConfigFile() { + // Utility class + } + + private static final Pattern PATTERN = + Pattern.compile( + "^Config resource 'class path resource \\[(.+)]' via location 'optional:classpath:/'$"); + + static OpenTelemetryConfigurationModel extractModel(ConfigurableEnvironment environment) + throws IOException { + for (PropertySource propertySource : environment.getPropertySources()) { + if (propertySource instanceof OriginTrackedMapPropertySource) { + return getModel(environment, (OriginTrackedMapPropertySource) propertySource); + } + } + throw new IllegalStateException("No application.yaml file found."); + } + + private static OpenTelemetryConfigurationModel getModel( + ConfigurableEnvironment environment, OriginTrackedMapPropertySource source) + throws IOException { + Matcher matcher = PATTERN.matcher(source.getName()); + if (matcher.matches()) { + String file = matcher.group(1); + + try (InputStream resourceAsStream = + environment.getClass().getClassLoader().getResourceAsStream(file)) { + if (resourceAsStream != null) { + return extractOtelConfigFile(resourceAsStream); + } else { + throw new IllegalStateException("Unable to load " + file + " in the classpath."); + } + } + } else { + throw new IllegalStateException( + "No OpenTelemetry configuration found in the application.yaml file."); + } + } + + @Nullable + @SuppressWarnings("unchecked") + private static String parseOtelNode(InputStream in) { + Load load = new Load(LoadSettings.builder().build()); + Dump dump = new Dump(DumpSettings.builder().build()); + for (Object o : load.loadAllFromInputStream(in)) { + Map data = (Map) o; + Map> otel = (Map>) data.get("otel"); + if (otel != null) { + return dump.dumpToString(otel); + } + } + throw new IllegalStateException("No 'otel' configuration found in the YAML file."); + } + + private static OpenTelemetryConfigurationModel extractOtelConfigFile(InputStream content) { + String node = parseOtelNode(content); + if (node == null || node.isEmpty()) { + throw new IllegalStateException("otel node is empty or null in the YAML file."); + } + + return DeclarativeConfiguration.parse( + new ByteArrayInputStream(node.getBytes(StandardCharsets.UTF_8))); + } +} 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 b9a9bd7c9a2a..dd56151f8f9c 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 @@ -5,24 +5,43 @@ package io.opentelemetry.instrumentation.spring.autoconfigure; +import static java.util.Objects.requireNonNull; + import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.trace.TracerProvider; import io.opentelemetry.common.ComponentLoader; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; +import io.opentelemetry.instrumentation.config.bridge.DeclarativeConfigPropertiesBridgeBuilder; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.DeclarativeConfigDisabled; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.DeclarativeConfigEnabled; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.OtelDisabled; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.OtelEnabled; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.OtelMapConverter; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.OtelResourceProperties; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.OtelSpringProperties; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.OtlpExporterProperties; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.SpringConfigProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.resources.DistroComponentProvider; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.resources.DistroVersionResourceProvider; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.resources.ResourceCustomizerProvider; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.resources.SpringResourceProvider; +import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import io.opentelemetry.sdk.resources.Resource; +import java.io.IOException; import java.util.Collections; import java.util.List; import java.util.Optional; @@ -33,7 +52,6 @@ import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.ConfigurationPropertiesBinding; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.info.BuildProperties; @@ -41,7 +59,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.DependsOn; +import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.Environment; /** @@ -52,100 +70,156 @@ *

Updates the sampler probability for the configured {@link TracerProvider}. */ @Configuration -@EnableConfigurationProperties({ - OtlpExporterProperties.class, - OtelResourceProperties.class, - OtelSpringProperties.class -}) public class OpenTelemetryAutoConfiguration { private static final Logger logger = LoggerFactory.getLogger(OpenTelemetryAutoConfiguration.class); public OpenTelemetryAutoConfiguration() {} - @Bean - @ConfigurationPropertiesBinding - OtelMapConverter otelMapConverter() { - // This is needed for otlp exporter headers and OtelResourceProperties. - - // We need this converter, even if the SDK is disabled, - // because the properties are parsed before the SDK is disabled. - - // We also need this converter if the OpenTelemetry bean is user supplied, - // because the environment variables may still contain a value that needs to be converted, - // even if the SDK is disabled (and the value thus ignored). - return new OtelMapConverter(); - } - @Configuration - @Conditional(SdkEnabled.class) - @DependsOn("otelMapConverter") + @Conditional(OtelEnabled.class) @ConditionalOnMissingBean(OpenTelemetry.class) + @SuppressWarnings("OtelPrivateConstructorForUtilityClass") // spring uses reflection static class OpenTelemetrySdkConfig { - @Bean - public OpenTelemetrySdkComponentLoader openTelemetrySdkComponentLoader( - ApplicationContext applicationContext) { - return new OpenTelemetrySdkComponentLoader(applicationContext); - } + @Configuration + @EnableConfigurationProperties({ + OtlpExporterProperties.class, + OtelResourceProperties.class, + OtelSpringProperties.class + }) + @Conditional(DeclarativeConfigDisabled.class) + static class PropertiesConfig { - @Bean - public ResourceProvider otelSpringResourceProvider(Optional buildProperties) { - return new SpringResourceProvider(buildProperties); - } + @Bean + public ResourceProvider otelSpringResourceProvider( + Optional buildProperties) { + return new SpringResourceProvider(buildProperties); + } - @Bean - public ResourceProvider otelDistroVersionResourceProvider() { - return new DistroVersionResourceProvider(); - } + @Bean + public ResourceProvider otelDistroVersionResourceProvider() { + return new DistroVersionResourceProvider(); + } - @Bean - public AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk( - Environment env, - OtlpExporterProperties otlpExporterProperties, - OtelResourceProperties resourceProperties, - OtelSpringProperties otelSpringProperties, - OpenTelemetrySdkComponentLoader componentLoader) { - - return AutoConfigureUtil.setConfigPropertiesCustomizer( - AutoConfiguredOpenTelemetrySdk.builder().setComponentLoader(componentLoader), - c -> - SpringConfigProperties.create( - env, otlpExporterProperties, resourceProperties, otelSpringProperties, c)) - .build(); - } + @Bean + @ConfigurationPropertiesBinding + OtelMapConverter otelMapConverter() { + return new OtelMapConverter(); + } - @Bean - public OpenTelemetry openTelemetry( - AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) { - logger.info( - "OpenTelemetry Spring Boot starter ({}) has been started", - EmbeddedInstrumentationProperties.findVersion( - "io.opentelemetry.spring-boot-autoconfigure")); - - return autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk(); + @Bean + public AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk( + Environment env, + OtlpExporterProperties otlpExporterProperties, + OtelResourceProperties resourceProperties, + OtelSpringProperties otelSpringProperties, + ApplicationContext applicationContext) { + + return AutoConfigureUtil.setConfigPropertiesCustomizer( + AutoConfiguredOpenTelemetrySdk.builder() + .setComponentLoader(new OpenTelemetrySdkComponentLoader(applicationContext)), + c -> + SpringConfigProperties.create( + env, otlpExporterProperties, resourceProperties, otelSpringProperties, c)) + .build(); + } + + @Bean + public OpenTelemetry openTelemetry( + AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) { + logStart(); + return autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk(); + } + + @Bean + public InstrumentationConfig instrumentationConfig(ConfigProperties properties) { + return new ConfigPropertiesBridge(properties); + } + + /** + * Expose the {@link ConfigProperties} bean for use in other auto-configurations. + * + *

Not using spring boot properties directly in order to support {@link + * io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer#addPropertiesCustomizer(Function)} + * and {@link + * io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer#addPropertiesSupplier(Supplier)}. + */ + @Bean + public ConfigProperties otelProperties( + AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) { + return requireNonNull(AutoConfigureUtil.getConfig(autoConfiguredOpenTelemetrySdk)); + } } - /** - * Expose the {@link ConfigProperties} bean for use in other auto-configurations. - * - *

Not using spring boot properties directly in order to support {@link - * io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer#addPropertiesCustomizer(Function)} - * and {@link - * io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer#addPropertiesSupplier(Supplier)}. - */ - @Bean - public ConfigProperties otelProperties( - AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) { - return AutoConfigureUtil.getConfig(autoConfiguredOpenTelemetrySdk); + @Configuration + @Conditional(DeclarativeConfigEnabled.class) + static class EmbeddedConfigFileConfig { + + @Bean + public OpenTelemetryConfigurationModel openTelemetryConfigurationModel( + ConfigurableEnvironment environment) throws IOException { + return EmbeddedConfigFile.extractModel(environment); + } + + @Bean + public OpenTelemetry openTelemetry( + OpenTelemetryConfigurationModel model, ApplicationContext applicationContext) { + OpenTelemetrySdk sdk = + DeclarativeConfiguration.create( + model, new OpenTelemetrySdkComponentLoader(applicationContext)); + Runtime.getRuntime().addShutdownHook(new Thread(sdk::close)); + logStart(); + return sdk; + } + + @Bean + public ConfigProvider configProvider(OpenTelemetryConfigurationModel model) { + return SdkConfigProvider.create(model); + } + + /** + * Expose the {@link ConfigProperties} bean for use in other auto-configurations. + * + *

Not using spring boot properties directly, because declarative configuration does not + * integrate with spring boot properties. + */ + @Bean + public ConfigProperties otelProperties(ConfigProvider configProvider) { + return new DeclarativeConfigPropertiesBridgeBuilder() + .buildFromInstrumentationConfig(configProvider.getInstrumentationConfig()); + } + + @Bean + public InstrumentationConfig instrumentationConfig( + ConfigProperties properties, ConfigProvider configProvider) { + return new ConfigPropertiesBridge(properties, configProvider); + } + + @Bean + public DeclarativeConfigurationCustomizerProvider distroConfigurationCustomizerProvider() { + return new ResourceCustomizerProvider(); + } + + @Bean + public ComponentProvider distroComponentProvider() { + return new DistroComponentProvider(); + } } } + private static void logStart() { + logger.info( + "OpenTelemetry Spring Boot starter ({}) has been started", + EmbeddedInstrumentationProperties.findVersion( + "io.opentelemetry.spring-boot-autoconfigure")); + } + @Configuration - @DependsOn("otelMapConverter") @ConditionalOnMissingBean(OpenTelemetry.class) - @ConditionalOnProperty(name = "otel.sdk.disabled", havingValue = "true") + @Conditional(OtelDisabled.class) static class DisabledOpenTelemetrySdkConfig { + @Bean public OpenTelemetry openTelemetry() { logger.info("OpenTelemetry Spring Boot starter has been disabled"); @@ -157,6 +231,26 @@ public OpenTelemetry openTelemetry() { public ConfigProperties otelProperties() { return DefaultConfigProperties.createFromMap(Collections.emptyMap()); } + + @Bean + public InstrumentationConfig instrumentationConfig(ConfigProperties properties) { + return new ConfigPropertiesBridge(properties, null); + } + + @Configuration + @Conditional(DeclarativeConfigDisabled.class) + static class PropertiesConfig { + /** + * Is only added so that we have the same converters as with active OpenTelemetry SDK + * + *

In other words, don't break applications that (accidentally) use the {@link + * OtelMapConverter}. + */ + @Bean + OtelMapConverter otelMapConverter() { + return new OtelMapConverter(); + } + } } @Configuration @@ -170,6 +264,16 @@ public ConfigProperties otelProperties(ApplicationContext applicationContext) { } } + @Configuration + @ConditionalOnBean(OpenTelemetry.class) + @ConditionalOnMissingBean({InstrumentationConfig.class}) + static class FallbackInstrumentationConfig { + @Bean + public InstrumentationConfig instrumentationConfig(ConfigProperties properties) { + return new ConfigPropertiesBridge(properties, null); + } + } + /** * The {@link ComponentLoader} is used by the SDK autoconfiguration to load all components, e.g. * attributes = - metadata.getAnnotationAttributes(ConditionalOnEnabledInstrumentation.class.getName()); + Objects.requireNonNull( + metadata.getAnnotationAttributes(ConditionalOnEnabledInstrumentation.class.getName())); - String name = String.format("otel.instrumentation.%s.enabled", attributes.get("module")); - Boolean explicit = context.getEnvironment().getProperty(name, Boolean.class); - if (explicit != null) { - return explicit; - } - boolean defaultValue = (boolean) attributes.get("enabledByDefault"); - if (!defaultValue) { - return false; - } - return context - .getEnvironment() - .getProperty("otel.instrumentation.common.default-enabled", Boolean.class, true); + return EarlyConfig.isInstrumentationEnabled( + context.getEnvironment(), + requireNonNull(attributes.get("module")).toString(), + (boolean) requireNonNull(attributes.get("enabledByDefault"))); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/OtelDisabled.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/OtelDisabled.java new file mode 100644 index 000000000000..d521f76eb7ba --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/OtelDisabled.java @@ -0,0 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.spring.autoconfigure.internal; + +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.type.AnnotatedTypeMetadata; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class OtelDisabled implements Condition { + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + return !EarlyConfig.otelEnabled(context.getEnvironment()); + } +} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/OtelEnabled.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/OtelEnabled.java new file mode 100644 index 000000000000..a1b87384e8ce --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/OtelEnabled.java @@ -0,0 +1,21 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.spring.autoconfigure.internal; + +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.type.AnnotatedTypeMetadata; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class OtelEnabled implements Condition { + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + return EarlyConfig.otelEnabled(context.getEnvironment()); + } +} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/SdkEnabled.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/SdkEnabled.java deleted file mode 100644 index 082bdebc00b7..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/SdkEnabled.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.internal; - -import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; - -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ -public class SdkEnabled extends AnyNestedCondition { - public SdkEnabled() { - super(ConfigurationPhase.PARSE_CONFIGURATION); - } - - @ConditionalOnProperty(name = "otel.sdk.disabled", havingValue = "false", matchIfMissing = true) - static class NotDisabled {} -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/annotations/InstrumentationWithSpanAspect.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/annotations/InstrumentationWithSpanAspect.java index 90c8c2e229d5..c8b112aac60e 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/annotations/InstrumentationWithSpanAspect.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/annotations/InstrumentationWithSpanAspect.java @@ -10,6 +10,7 @@ import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.core.ParameterNameDiscoverer; +import javax.annotation.Nullable; @Aspect class InstrumentationWithSpanAspect extends WithSpanAspect { @@ -24,6 +25,7 @@ class InstrumentationWithSpanAspect extends WithSpanAspect { .InstrumentationAnnotationAttributeNameSupplier()); } + @Nullable @Override @Around("@annotation(io.opentelemetry.instrumentation.annotations.WithSpan)") public Object traceMethod(ProceedingJoinPoint pjp) throws Throwable { diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/annotations/WithSpanAspect.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/annotations/WithSpanAspect.java index 89ff79dd6ab9..6ee977a3c052 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/annotations/WithSpanAspect.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/annotations/WithSpanAspect.java @@ -18,6 +18,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.core.ParameterNameDiscoverer; +import javax.annotation.Nullable; /** * Uses Spring-AOP to wrap methods marked by {@link WithSpan} in a {@link Span}. @@ -64,6 +65,7 @@ private static Context parentContext( return request.inheritContext() ? parentContext : Context.root(); } + @Nullable public Object traceMethod(ProceedingJoinPoint pjp) throws Throwable { JoinPointRequest request = requestFactory.create(pjp); Context parentContext = Context.current(); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/jdbc/DataSourcePostProcessor.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/jdbc/DataSourcePostProcessor.java index cd8d7ca3d38b..8fe5589b7af8 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/jdbc/DataSourcePostProcessor.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/jdbc/DataSourcePostProcessor.java @@ -7,16 +7,17 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.jdbc.datasource.JdbcTelemetry; import io.opentelemetry.instrumentation.jdbc.datasource.JdbcTelemetryBuilder; import io.opentelemetry.instrumentation.jdbc.datasource.internal.Experimental; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.InstrumentationConfigUtil; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import java.io.PrintWriter; import java.sql.Connection; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.logging.Logger; +import javax.annotation.Nullable; import javax.sql.DataSource; import org.springframework.aop.SpringProxy; import org.springframework.aop.framework.AdvisedSupport; @@ -27,18 +28,20 @@ final class DataSourcePostProcessor implements BeanPostProcessor, Ordered { + @Nullable private static final Class ROUTING_DATA_SOURCE_CLASS = getRoutingDataSourceClass(); private final ObjectProvider openTelemetryProvider; - private final ObjectProvider configPropertiesProvider; + private final ObjectProvider configProvider; DataSourcePostProcessor( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { + ObjectProvider configProvider) { this.openTelemetryProvider = openTelemetryProvider; - this.configPropertiesProvider = configPropertiesProvider; + this.configProvider = configProvider; } + @Nullable private static Class getRoutingDataSourceClass() { try { return Class.forName("org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource"); @@ -59,32 +62,24 @@ public Object postProcessAfterInitialization(Object bean, String beanName) { && !isRoutingDatasource(bean) && !ScopedProxyUtils.isScopedTarget(beanName)) { DataSource dataSource = (DataSource) bean; + InstrumentationConfig config = configProvider.getObject(); JdbcTelemetryBuilder builder = JdbcTelemetry.builder(openTelemetryProvider.getObject()) .setStatementSanitizationEnabled( InstrumentationConfigUtil.isStatementSanitizationEnabled( - configPropertiesProvider.getObject(), - "otel.instrumentation.jdbc.statement-sanitizer.enabled")) + config, "otel.instrumentation.jdbc.statement-sanitizer.enabled")) .setCaptureQueryParameters( - configPropertiesProvider - .getObject() - .getBoolean( - "otel.instrumentation.jdbc.experimental.capture-query-parameters", false)) + config.getBoolean( + "otel.instrumentation.jdbc.experimental.capture-query-parameters", false)) .setTransactionInstrumenterEnabled( - configPropertiesProvider - .getObject() - .getBoolean( - "otel.instrumentation.jdbc.experimental.transaction.enabled", false)) + config.getBoolean( + "otel.instrumentation.jdbc.experimental.transaction.enabled", false)) .setDataSourceInstrumenterEnabled( - configPropertiesProvider - .getObject() - .getBoolean( - "otel.instrumentation.jdbc.experimental.datasource.enabled", false)); + config.getBoolean( + "otel.instrumentation.jdbc.experimental.datasource.enabled", false)); Experimental.setEnableSqlCommenter( builder, - configPropertiesProvider - .getObject() - .getBoolean("otel.instrumentation.jdbc.experimental.sqlcommenter.enabled", false)); + config.getBoolean("otel.instrumentation.jdbc.experimental.sqlcommenter.enabled", false)); DataSource otelDataSource = builder.build().wrap(dataSource); // wrap instrumented data source into a proxy that unwraps to the original data source diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/jdbc/JdbcInstrumentationAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/jdbc/JdbcInstrumentationAutoConfiguration.java index 3ec55a5a06c2..1732c3be178d 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/jdbc/JdbcInstrumentationAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/jdbc/JdbcInstrumentationAutoConfiguration.java @@ -6,8 +6,8 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.jdbc; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import javax.sql.DataSource; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; @@ -33,7 +33,7 @@ public JdbcInstrumentationAutoConfiguration() {} // static to avoid "is not eligible for getting processed by all BeanPostProcessors" warning static DataSourcePostProcessor dataSourcePostProcessor( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { - return new DataSourcePostProcessor(openTelemetryProvider, configPropertiesProvider); + ObjectProvider configProvider) { + return new DataSourcePostProcessor(openTelemetryProvider, configProvider); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/kafka/ConcurrentKafkaListenerContainerFactoryPostProcessor.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/kafka/ConcurrentKafkaListenerContainerFactoryPostProcessor.java index d26c2d684526..89f43e5ba4c7 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/kafka/ConcurrentKafkaListenerContainerFactoryPostProcessor.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/kafka/ConcurrentKafkaListenerContainerFactoryPostProcessor.java @@ -13,6 +13,7 @@ import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; import org.springframework.kafka.listener.BatchInterceptor; import org.springframework.kafka.listener.RecordInterceptor; +import javax.annotation.Nullable; class ConcurrentKafkaListenerContainerFactoryPostProcessor implements BeanPostProcessor { @@ -47,6 +48,7 @@ public Object postProcessAfterInitialization(Object bean, String beanName) { return listenerContainerFactory; } + @Nullable private static T readField(Object container, String filedName, Class fieldType) { try { Field field = AbstractKafkaListenerContainerFactory.class.getDeclaredField(filedName); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/kafka/KafkaInstrumentationAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/kafka/KafkaInstrumentationAutoConfiguration.java index 44f845e25ff1..4df611685733 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/kafka/KafkaInstrumentationAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/kafka/KafkaInstrumentationAutoConfiguration.java @@ -6,10 +6,10 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.kafka; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.kafkaclients.v2_6.KafkaTelemetry; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; import io.opentelemetry.instrumentation.spring.kafka.v2_7.SpringKafkaTelemetry; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -42,10 +42,10 @@ DefaultKafkaProducerFactoryCustomizer otelKafkaProducerFactoryCustomizer( @Bean static SpringKafkaTelemetry getTelemetry( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { + ObjectProvider configProvider) { return SpringKafkaTelemetry.builder(openTelemetryProvider.getObject()) .setCaptureExperimentalSpanAttributes( - configPropertiesProvider + configProvider .getObject() .getBoolean("otel.instrumentation.kafka.experimental-span-attributes", false)) .build(); @@ -60,8 +60,8 @@ static SpringKafkaTelemetry getTelemetry( static ConcurrentKafkaListenerContainerFactoryPostProcessor otelKafkaListenerContainerFactoryBeanPostProcessor( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { + ObjectProvider configProvider) { return new ConcurrentKafkaListenerContainerFactoryPostProcessor( - () -> getTelemetry(openTelemetryProvider, configPropertiesProvider)); + () -> getTelemetry(openTelemetryProvider, configProvider)); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LogbackAppenderInstaller.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LogbackAppenderInstaller.java index f6354622174c..55828481fb3c 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LogbackAppenderInstaller.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LogbackAppenderInstaller.java @@ -10,12 +10,14 @@ import ch.qos.logback.core.Appender; import io.opentelemetry.instrumentation.logback.appender.v1_0.OpenTelemetryAppender; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.DeprecatedConfigProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.EarlyConfig; import java.util.Iterator; import java.util.Optional; import org.slf4j.ILoggerFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent; +import org.springframework.core.env.ConfigurableEnvironment; class LogbackAppenderInstaller { @@ -41,25 +43,18 @@ static void install(ApplicationEnvironmentPreparedEvent applicationEnvironmentPr } } - private static boolean isLogbackAppenderAddable( - ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent) { - return isAppenderAddable( - applicationEnvironmentPreparedEvent, "otel.instrumentation.logback-appender.enabled"); + private static boolean isLogbackAppenderAddable(ApplicationEnvironmentPreparedEvent event) { + return isAppenderAddable(event, "logback-appender"); } - private static boolean isLogbackMdcAppenderAddable( - ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent) { - return isAppenderAddable( - applicationEnvironmentPreparedEvent, "otel.instrumentation.logback-mdc.enabled"); + private static boolean isLogbackMdcAppenderAddable(ApplicationEnvironmentPreparedEvent event) { + return isAppenderAddable(event, "logback-mdc"); } - private static boolean isAppenderAddable( - ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent, String property) { - boolean otelSdkDisabled = - evaluateBooleanProperty(applicationEnvironmentPreparedEvent, "otel.sdk.disabled", false); - boolean logbackInstrumentationEnabled = - evaluateBooleanProperty(applicationEnvironmentPreparedEvent, property, true); - return !otelSdkDisabled && logbackInstrumentationEnabled; + private static boolean isAppenderAddable(ApplicationEnvironmentPreparedEvent event, String name) { + ConfigurableEnvironment environment = event.getEnvironment(); + return EarlyConfig.otelEnabled(environment) + && EarlyConfig.isInstrumentationEnabled(environment, name, true); } private static void reInitializeOpenTelemetryAppender( @@ -236,18 +231,9 @@ private static void initializeMdcAppenderFromProperties( private static Boolean evaluateBooleanProperty( ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent, String property) { - return applicationEnvironmentPreparedEvent - .getEnvironment() - .getProperty(property, Boolean.class); - } - - private static boolean evaluateBooleanProperty( - ApplicationEnvironmentPreparedEvent applicationEnvironmentPreparedEvent, - String property, - boolean defaultValue) { - return applicationEnvironmentPreparedEvent - .getEnvironment() - .getProperty(property, Boolean.class, defaultValue); + ConfigurableEnvironment environment = applicationEnvironmentPreparedEvent.getEnvironment(); + return environment.getProperty( + EarlyConfig.translatePropertyName(environment, property), Boolean.class); } private static Optional findAppender(Class appenderClass) { diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LoggingExporterAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LoggingExporterAutoConfiguration.java index 0638941a18af..a72a9db38d6f 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LoggingExporterAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/logging/LoggingExporterAutoConfiguration.java @@ -8,7 +8,7 @@ import static java.util.Collections.emptyList; import io.opentelemetry.exporter.logging.LoggingSpanExporter; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.OtelEnabled; import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; @@ -23,7 +23,7 @@ * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. */ -@Conditional(SdkEnabled.class) +@Conditional(OtelEnabled.class) // to match "otel.javaagent.debug" system property @ConditionalOnProperty(name = "otel.spring-starter.debug", havingValue = "true") @ConditionalOnClass(LoggingSpanExporter.class) diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/mongo/MongoClientInstrumentationAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/mongo/MongoClientInstrumentationAutoConfiguration.java index 3685b6db2cab..fcc3bc46a315 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/mongo/MongoClientInstrumentationAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/mongo/MongoClientInstrumentationAutoConfiguration.java @@ -7,10 +7,10 @@ import com.mongodb.MongoClientSettings; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.mongo.v3_1.MongoTelemetry; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.InstrumentationConfigUtil; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.mongo.MongoClientSettingsBuilderCustomizer; import org.springframework.context.annotation.Bean; @@ -27,7 +27,7 @@ public class MongoClientInstrumentationAutoConfiguration { @Bean MongoClientSettingsBuilderCustomizer customizer( - OpenTelemetry openTelemetry, ConfigProperties config) { + OpenTelemetry openTelemetry, InstrumentationConfig config) { return builder -> builder.addCommandListener( MongoTelemetry.builder(openTelemetry) diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/r2dbc/R2dbcInstrumentationAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/r2dbc/R2dbcInstrumentationAutoConfiguration.java index e1bc89ace3d0..4dcddb592aca 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/r2dbc/R2dbcInstrumentationAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/r2dbc/R2dbcInstrumentationAutoConfiguration.java @@ -6,8 +6,8 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.r2dbc; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.r2dbc.spi.ConnectionFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -29,7 +29,7 @@ public R2dbcInstrumentationAutoConfiguration() {} // static to avoid "is not eligible for getting processed by all BeanPostProcessors" warning static R2dbcInstrumentingPostProcessor r2dbcInstrumentingPostProcessor( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { - return new R2dbcInstrumentingPostProcessor(openTelemetryProvider, configPropertiesProvider); + ObjectProvider configProvider) { + return new R2dbcInstrumentingPostProcessor(openTelemetryProvider, configProvider); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/r2dbc/R2dbcInstrumentingPostProcessor.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/r2dbc/R2dbcInstrumentingPostProcessor.java index 5d75b28946ef..09849deef13b 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/r2dbc/R2dbcInstrumentingPostProcessor.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/r2dbc/R2dbcInstrumentingPostProcessor.java @@ -6,9 +6,9 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.r2dbc; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.r2dbc.v1_0.internal.shaded.R2dbcTelemetry; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.InstrumentationConfigUtil; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.r2dbc.spi.ConnectionFactory; import io.r2dbc.spi.ConnectionFactoryOptions; import org.springframework.aop.scope.ScopedProxyUtils; @@ -19,13 +19,13 @@ class R2dbcInstrumentingPostProcessor implements BeanPostProcessor { private final ObjectProvider openTelemetryProvider; - private final ObjectProvider configPropertiesProvider; + private final ObjectProvider configProvider; R2dbcInstrumentingPostProcessor( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { + ObjectProvider configProvider) { this.openTelemetryProvider = openTelemetryProvider; - this.configPropertiesProvider = configPropertiesProvider; + this.configProvider = configProvider; } @Override @@ -35,7 +35,7 @@ public Object postProcessAfterInitialization(Object bean, String beanName) { return R2dbcTelemetry.builder(openTelemetryProvider.getObject()) .setStatementSanitizationEnabled( InstrumentationConfigUtil.isStatementSanitizationEnabled( - configPropertiesProvider.getObject(), + configProvider.getObject(), "otel.instrumentation.r2dbc.statement-sanitizer.enabled")) .build() .wrapConnectionFactory(connectionFactory, getConnectionFactoryOptions(connectionFactory)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java17RuntimeMetricsProvider.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java17RuntimeMetricsProvider.java index 8f258004a853..2699d35dc8f3 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java17RuntimeMetricsProvider.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java17RuntimeMetricsProvider.java @@ -11,6 +11,7 @@ import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RuntimeMetricsConfigUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nullable; /** * Configures runtime metrics collection for Java 17+. @@ -26,6 +27,7 @@ public int minJavaVersion() { return 17; } + @Nullable @Override public AutoCloseable start(OpenTelemetry openTelemetry, InstrumentationConfig config) { logger.debug("Use runtime metrics instrumentation for Java 17+"); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java8RuntimeMetricsProvider.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java8RuntimeMetricsProvider.java index fbb10d9e935b..23f48bacdce7 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java8RuntimeMetricsProvider.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java8RuntimeMetricsProvider.java @@ -11,6 +11,7 @@ import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.RuntimeMetricsConfigUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nullable; /** * Configures runtime metrics collection for Java 8. @@ -26,6 +27,7 @@ public int minJavaVersion() { return 8; } + @Nullable @Override public AutoCloseable start(OpenTelemetry openTelemetry, InstrumentationConfig config) { logger.debug("Use runtime metrics instrumentation for Java 8"); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/RuntimeMetricsAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/RuntimeMetricsAutoConfiguration.java index f58f4da5f217..c2a1350c6a7a 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/RuntimeMetricsAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/RuntimeMetricsAutoConfiguration.java @@ -6,11 +6,11 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import java.util.Comparator; import java.util.Optional; +import javax.annotation.Nullable; import javax.annotation.PreDestroy; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,6 +32,7 @@ public class RuntimeMetricsAutoConfiguration { private static final Logger logger = LoggerFactory.getLogger(RuntimeMetricsAutoConfiguration.class); + @Nullable private AutoCloseable closeable; @PreDestroy @@ -45,8 +46,7 @@ public void stopMetrics() throws Exception { public void handleApplicationReadyEvent(ApplicationReadyEvent event) { ConfigurableApplicationContext applicationContext = event.getApplicationContext(); OpenTelemetry openTelemetry = applicationContext.getBean(OpenTelemetry.class); - ConfigPropertiesBridge config = - new ConfigPropertiesBridge(applicationContext.getBean(ConfigProperties.class)); + InstrumentationConfig config = applicationContext.getBean(InstrumentationConfig.class); double version = Math.max(8, Double.parseDouble(System.getProperty("java.specification.version"))); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SpringSchedulingInstrumentationAspect.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SpringSchedulingInstrumentationAspect.java index 5dfec2280e8e..6d84cde77985 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SpringSchedulingInstrumentationAspect.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SpringSchedulingInstrumentationAspect.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.api.incubator.semconv.code.CodeAttributesExtractor; import io.opentelemetry.instrumentation.api.incubator.semconv.code.CodeAttributesGetter; import io.opentelemetry.instrumentation.api.incubator.semconv.code.CodeSpanNameExtractor; @@ -16,7 +17,6 @@ import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @@ -43,7 +43,7 @@ final class SpringSchedulingInstrumentationAspect { private final Instrumenter instrumenter; public SpringSchedulingInstrumentationAspect( - OpenTelemetry openTelemetry, ConfigProperties configProperties) { + OpenTelemetry openTelemetry, InstrumentationConfig config) { CodeAttributesGetter codedAttributesGetter = ClassAndMethod.codeAttributesGetter(); InstrumenterBuilder builder = @@ -52,7 +52,7 @@ public SpringSchedulingInstrumentationAspect( INSTRUMENTATION_NAME, CodeSpanNameExtractor.create(codedAttributesGetter)) .addAttributesExtractor(CodeAttributesExtractor.create(codedAttributesGetter)); - if (configProperties.getBoolean( + if (config.getBoolean( "otel.instrumentation.spring-scheduling.experimental-span-attributes", false)) { builder.addAttributesExtractor( AttributesExtractor.constant(AttributeKey.stringKey("job.system"), "spring_scheduling")); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SpringSchedulingInstrumentationAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SpringSchedulingInstrumentationAutoConfiguration.java index c65ea90ac4b1..85a54625e455 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SpringSchedulingInstrumentationAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SpringSchedulingInstrumentationAutoConfiguration.java @@ -6,8 +6,8 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.scheduling; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import org.aspectj.lang.annotation.Aspect; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Bean; @@ -26,7 +26,7 @@ class SpringSchedulingInstrumentationAutoConfiguration { @Bean SpringSchedulingInstrumentationAspect springSchedulingInstrumentationAspect( - OpenTelemetry openTelemetry, ConfigProperties configProperties) { - return new SpringSchedulingInstrumentationAspect(openTelemetry, configProperties); + OpenTelemetry openTelemetry, InstrumentationConfig config) { + return new SpringSchedulingInstrumentationAspect(openTelemetry, config); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestTemplateBeanPostProcessor.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestTemplateBeanPostProcessor.java index 0cda4b63d686..4db9b873fece 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestTemplateBeanPostProcessor.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestTemplateBeanPostProcessor.java @@ -6,7 +6,7 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.web; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.web.client.RestTemplate; @@ -15,13 +15,13 @@ final class RestTemplateBeanPostProcessor implements BeanPostProcessor { private final ObjectProvider openTelemetryProvider; - private final ObjectProvider configPropertiesProvider; + private final ObjectProvider configProvider; RestTemplateBeanPostProcessor( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { + ObjectProvider configProvider) { this.openTelemetryProvider = openTelemetryProvider; - this.configPropertiesProvider = configPropertiesProvider; + this.configProvider = configProvider; } @Override @@ -31,8 +31,6 @@ public Object postProcessAfterInitialization(Object bean, String beanName) { } return RestTemplateInstrumentation.addIfNotPresent( - (RestTemplate) bean, - openTelemetryProvider.getObject(), - configPropertiesProvider.getObject()); + (RestTemplate) bean, openTelemetryProvider.getObject(), configProvider.getObject()); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestTemplateInstrumentation.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestTemplateInstrumentation.java index 9465c534d0ce..ca4c0c97c466 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestTemplateInstrumentation.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestTemplateInstrumentation.java @@ -7,10 +7,10 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.spring.web.v3_1.SpringWebTelemetry; import io.opentelemetry.instrumentation.spring.web.v3_1.internal.WebTelemetryUtil; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import java.util.List; import org.springframework.http.client.ClientHttpRequestInterceptor; import org.springframework.web.client.RestTemplate; @@ -21,7 +21,7 @@ private RestTemplateInstrumentation() {} @CanIgnoreReturnValue static RestTemplate addIfNotPresent( - RestTemplate restTemplate, OpenTelemetry openTelemetry, ConfigProperties config) { + RestTemplate restTemplate, OpenTelemetry openTelemetry, InstrumentationConfig config) { ClientHttpRequestInterceptor instrumentationInterceptor = InstrumentationConfigUtil.configureClientBuilder( diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/SpringWebInstrumentationAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/SpringWebInstrumentationAutoConfiguration.java index 21a18ec8db2b..97d5bd9b52d5 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/SpringWebInstrumentationAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/SpringWebInstrumentationAutoConfiguration.java @@ -6,8 +6,8 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.web; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.web.client.RestTemplateCustomizer; @@ -34,16 +34,16 @@ public SpringWebInstrumentationAutoConfiguration() {} @Bean static RestTemplateBeanPostProcessor otelRestTemplateBeanPostProcessor( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { - return new RestTemplateBeanPostProcessor(openTelemetryProvider, configPropertiesProvider); + ObjectProvider configProvider) { + return new RestTemplateBeanPostProcessor(openTelemetryProvider, configProvider); } @Bean RestTemplateCustomizer otelRestTemplateCustomizer( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { + ObjectProvider configProvider) { return restTemplate -> RestTemplateInstrumentation.addIfNotPresent( - restTemplate, openTelemetryProvider.getObject(), configPropertiesProvider.getObject()); + restTemplate, openTelemetryProvider.getObject(), configProvider.getObject()); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfiguration.java index ff6d8f9a5d0b..79bacde3ccc2 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfiguration.java @@ -6,8 +6,8 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.webflux; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Bean; @@ -34,12 +34,12 @@ public SpringWebfluxInstrumentationAutoConfiguration() {} @Bean static WebClientBeanPostProcessor otelWebClientBeanPostProcessor( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { - return new WebClientBeanPostProcessor(openTelemetryProvider, configPropertiesProvider); + ObjectProvider configProvider) { + return new WebClientBeanPostProcessor(openTelemetryProvider, configProvider); } @Bean - WebFilter telemetryFilter(OpenTelemetry openTelemetry, ConfigProperties config) { + WebFilter telemetryFilter(OpenTelemetry openTelemetry, InstrumentationConfig config) { return WebClientBeanPostProcessor.getWebfluxServerTelemetry(openTelemetry, config) .createWebFilterAndRegisterReactorHook(); } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessor.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessor.java index 13a74048d3eb..9b501c410be3 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessor.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessor.java @@ -6,11 +6,11 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.webflux; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.spring.webflux.v5_3.SpringWebfluxClientTelemetry; import io.opentelemetry.instrumentation.spring.webflux.v5_3.SpringWebfluxServerTelemetry; import io.opentelemetry.instrumentation.spring.webflux.v5_3.internal.SpringWebfluxBuilderUtil; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.web.reactive.function.client.WebClient; @@ -23,17 +23,17 @@ final class WebClientBeanPostProcessor implements BeanPostProcessor { private final ObjectProvider openTelemetryProvider; - private final ObjectProvider configPropertiesProvider; + private final ObjectProvider configProvider; WebClientBeanPostProcessor( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { + ObjectProvider configProvider) { this.openTelemetryProvider = openTelemetryProvider; - this.configPropertiesProvider = configPropertiesProvider; + this.configProvider = configProvider; } static SpringWebfluxClientTelemetry getWebfluxClientTelemetry( - OpenTelemetry openTelemetry, ConfigProperties config) { + OpenTelemetry openTelemetry, InstrumentationConfig config) { return InstrumentationConfigUtil.configureClientBuilder( config, SpringWebfluxClientTelemetry.builder(openTelemetry), @@ -42,7 +42,7 @@ static SpringWebfluxClientTelemetry getWebfluxClientTelemetry( } static SpringWebfluxServerTelemetry getWebfluxServerTelemetry( - OpenTelemetry openTelemetry, ConfigProperties config) { + OpenTelemetry openTelemetry, InstrumentationConfig config) { return InstrumentationConfigUtil.configureServerBuilder( config, SpringWebfluxServerTelemetry.builder(openTelemetry), @@ -64,8 +64,7 @@ public Object postProcessAfterInitialization(Object bean, String beanName) { private WebClient.Builder wrapBuilder(WebClient.Builder webClientBuilder) { SpringWebfluxClientTelemetry instrumentation = - getWebfluxClientTelemetry( - openTelemetryProvider.getObject(), configPropertiesProvider.getObject()); + getWebfluxClientTelemetry(openTelemetryProvider.getObject(), configProvider.getObject()); return webClientBuilder.filters(instrumentation::addFilter); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvc5InstrumentationAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvc5InstrumentationAutoConfiguration.java index 8d971c9d4890..73d3f657504c 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvc5InstrumentationAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvc5InstrumentationAutoConfiguration.java @@ -6,11 +6,11 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.webmvc; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.spring.webmvc.v5_3.SpringWebMvcTelemetry; import io.opentelemetry.instrumentation.spring.webmvc.v5_3.internal.SpringMvcBuilderUtil; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import javax.servlet.Filter; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Bean; @@ -28,7 +28,7 @@ public class SpringWebMvc5InstrumentationAutoConfiguration { @Bean - Filter otelWebMvcFilter(OpenTelemetry openTelemetry, ConfigProperties config) { + Filter otelWebMvcFilter(OpenTelemetry openTelemetry, InstrumentationConfig config) { return InstrumentationConfigUtil.configureServerBuilder( config, SpringWebMvcTelemetry.builder(openTelemetry), diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java index 047d2ee809ea..dbabca731486 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java @@ -5,8 +5,12 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties; +import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; +import static java.util.Objects.requireNonNull; + import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; @@ -24,9 +28,16 @@ public final class ConfigPropertiesBridge implements InstrumentationConfig { private final ConfigProperties configProperties; + @Nullable private final ConfigProvider configProvider; public ConfigPropertiesBridge(ConfigProperties configProperties) { + this(configProperties, null); + } + + public ConfigPropertiesBridge( + ConfigProperties configProperties, @Nullable ConfigProvider configProvider) { this.configProperties = configProperties; + this.configProvider = configProvider; } @Nullable @@ -113,19 +124,23 @@ public Map getMap(String name, Map defaultValue) @Override public boolean isDeclarative() { - return false; + return configProvider != null; } @Override public DeclarativeConfigProperties getDeclarativeConfig(String node) { - throw new IllegalStateException( - "Declarative configuration is not supported in spring boot autoconfigure yet"); + DeclarativeConfigProperties config = + InstrumentationConfigUtil.javaInstrumentationConfig(requireNonNull(configProvider), node); + if (config == null) { + // there is no declarative config for this node + return empty(); + } + return config; } @Nullable @Override public ConfigProvider getConfigProvider() { - // declarative config support will be added in the future - return null; + return configProvider; } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/InstrumentationConfigUtil.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/InstrumentationConfigUtil.java index fb5e582bfaa5..683529a18b29 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/InstrumentationConfigUtil.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/InstrumentationConfigUtil.java @@ -9,7 +9,7 @@ import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpClientInstrumenterBuilder; import io.opentelemetry.instrumentation.api.incubator.builder.internal.DefaultHttpServerInstrumenterBuilder; import io.opentelemetry.instrumentation.api.incubator.config.internal.CommonConfig; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import java.util.function.Function; /** @@ -21,7 +21,7 @@ private InstrumentationConfigUtil() {} @CanIgnoreReturnValue public static T configureClientBuilder( - ConfigProperties config, + InstrumentationConfig config, T builder, Function> getBuilder) { getBuilder.apply(builder).configure(getConfig(config)); @@ -30,18 +30,18 @@ public static T configureClientBuilder( @CanIgnoreReturnValue public static T configureServerBuilder( - ConfigProperties config, + InstrumentationConfig config, T builder, Function> getBuilder) { getBuilder.apply(builder).configure(getConfig(config)); return builder; } - private static CommonConfig getConfig(ConfigProperties config) { - return new CommonConfig(new ConfigPropertiesBridge(config)); + private static CommonConfig getConfig(InstrumentationConfig config) { + return new CommonConfig(config); } - public static boolean isStatementSanitizationEnabled(ConfigProperties config, String key) { + public static boolean isStatementSanitizationEnabled(InstrumentationConfig config, String key) { return config.getBoolean( key, config.getBoolean("otel.instrumentation.common.db-statement-sanitizer.enabled", true)); } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringConfigProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringConfigProperties.java index 4f0412ef023b..fbb9bc857447 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringConfigProperties.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringConfigProperties.java @@ -5,6 +5,8 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties; +import static java.util.Collections.emptyList; + import io.opentelemetry.api.internal.ConfigUtil; import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; import io.opentelemetry.instrumentation.resources.internal.ResourceProviderPropertiesCustomizer; @@ -210,7 +212,12 @@ public List getList(String name) { } } - return or(environment.getProperty(normalizedName, List.class), otelSdkProperties.getList(name)); + List result = + or(environment.getProperty(normalizedName, List.class), otelSdkProperties.getList(name)); + if (result == null) { + return emptyList(); + } + return result; } @Nullable diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/resources/DistroComponentProvider.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/resources/DistroComponentProvider.java new file mode 100644 index 000000000000..ad1a669067cd --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/resources/DistroComponentProvider.java @@ -0,0 +1,33 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.spring.autoconfigure.internal.resources; + +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.resources.Resource; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +@SuppressWarnings("rawtypes") +public class DistroComponentProvider implements ComponentProvider { + + @Override + public Class getType() { + return Resource.class; + } + + @Override + public String getName() { + return "opentelemetry-spring-boot-starter"; + } + + @Override + public Resource create(DeclarativeConfigProperties config) { + return DistroVersionResourceProvider.get(); + } +} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/resources/DistroVersionResourceProvider.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/resources/DistroVersionResourceProvider.java index 8ba185f97b98..5b23edebc9a7 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/resources/DistroVersionResourceProvider.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/resources/DistroVersionResourceProvider.java @@ -12,14 +12,16 @@ import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; import io.opentelemetry.sdk.resources.Resource; +import static java.util.Objects.requireNonNull; + /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. */ public class DistroVersionResourceProvider implements ResourceProvider { - public static final String VERSION = - EmbeddedInstrumentationProperties.findVersion("io.opentelemetry.spring-boot-autoconfigure"); + public static final String VERSION = requireNonNull( + EmbeddedInstrumentationProperties.findVersion("io.opentelemetry.spring-boot-autoconfigure")); private static final AttributeKey TELEMETRY_DISTRO_NAME = AttributeKey.stringKey("telemetry.distro.name"); @@ -28,6 +30,10 @@ public class DistroVersionResourceProvider implements ResourceProvider { @Override public Resource createResource(ConfigProperties config) { + return get(); + } + + static Resource get() { return Resource.create( Attributes.of( TELEMETRY_DISTRO_NAME, diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/resources/ResourceCustomizerProvider.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/resources/ResourceCustomizerProvider.java new file mode 100644 index 000000000000..1bbd1af4f5d2 --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/resources/ResourceCustomizerProvider.java @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.spring.autoconfigure.internal.resources; + +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizer; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectionModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectorModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class ResourceCustomizerProvider implements DeclarativeConfigurationCustomizerProvider { + + // opentelemetry-javaagent-distribution: adds "distro.name" and "distro.version" attributes + // (DistroComponentProvider in this package) + private static final List REQUIRED_DETECTORS = + Collections.singletonList("opentelemetry-spring-boot-starter"); + + @Override + public void customize(DeclarativeConfigurationCustomizer customizer) { + customizer.addModelCustomizer( + model -> { + ResourceModel resource = model.getResource(); + if (resource == null) { + resource = new ResourceModel(); + model.withResource(resource); + } + ExperimentalResourceDetectionModel detectionModel = resource.getDetectionDevelopment(); + if (detectionModel == null) { + detectionModel = new ExperimentalResourceDetectionModel(); + resource.withDetectionDevelopment(detectionModel); + } + List detectors = + Objects.requireNonNull(detectionModel.getDetectors()); + Set names = + detectors.stream() + .flatMap(detector -> detector.getAdditionalProperties().keySet().stream()) + .collect(Collectors.toSet()); + + for (String name : REQUIRED_DETECTORS) { + if (!names.contains(name)) { + ExperimentalResourceDetectorModel detector = new ExperimentalResourceDetectorModel(); + detector.getAdditionalProperties().put(name, null); + // add first (the least precedence) + // so that the user can add a differently named detector that takes precedence + detectors.add(0, detector); + } + } + return model; + }); + } +} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/javaSpring3/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientBeanPostProcessor.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/javaSpring3/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientBeanPostProcessor.java index 8ebefdd655f6..9ef5b7f19194 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/javaSpring3/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientBeanPostProcessor.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/javaSpring3/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientBeanPostProcessor.java @@ -6,10 +6,10 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.web; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.spring.web.v3_1.SpringWebTelemetry; import io.opentelemetry.instrumentation.spring.web.v3_1.internal.WebTelemetryUtil; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.http.client.ClientHttpRequestInterceptor; @@ -18,26 +18,26 @@ final class RestClientBeanPostProcessor implements BeanPostProcessor { private final ObjectProvider openTelemetryProvider; - private final ObjectProvider configPropertiesProvider; + private final ObjectProvider configProvider; public RestClientBeanPostProcessor( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { + ObjectProvider configProvider) { this.openTelemetryProvider = openTelemetryProvider; - this.configPropertiesProvider = configPropertiesProvider; + this.configProvider = configProvider; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) { if (bean instanceof RestClient restClient) { return addRestClientInterceptorIfNotPresent( - restClient, openTelemetryProvider.getObject(), configPropertiesProvider.getObject()); + restClient, openTelemetryProvider.getObject(), configProvider.getObject()); } return bean; } private static RestClient addRestClientInterceptorIfNotPresent( - RestClient restClient, OpenTelemetry openTelemetry, ConfigProperties config) { + RestClient restClient, OpenTelemetry openTelemetry, InstrumentationConfig config) { ClientHttpRequestInterceptor instrumentationInterceptor = getInterceptor(openTelemetry, config); return restClient @@ -55,7 +55,7 @@ private static RestClient addRestClientInterceptorIfNotPresent( } static ClientHttpRequestInterceptor getInterceptor( - OpenTelemetry openTelemetry, ConfigProperties config) { + OpenTelemetry openTelemetry, InstrumentationConfig config) { return InstrumentationConfigUtil.configureClientBuilder( config, SpringWebTelemetry.builder(openTelemetry), diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/javaSpring3/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/javaSpring3/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfiguration.java index a0fad74b0a35..72c83ef5d5ad 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/javaSpring3/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/javaSpring3/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfiguration.java @@ -6,8 +6,8 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.web; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -34,17 +34,17 @@ public class RestClientInstrumentationAutoConfiguration { @Bean static RestClientBeanPostProcessor otelRestClientBeanPostProcessor( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { - return new RestClientBeanPostProcessor(openTelemetryProvider, configPropertiesProvider); + ObjectProvider configProvider) { + return new RestClientBeanPostProcessor(openTelemetryProvider, configProvider); } @Bean RestClientCustomizer otelRestClientCustomizer( ObjectProvider openTelemetryProvider, - ObjectProvider configPropertiesProvider) { + ObjectProvider configProvider) { return builder -> builder.requestInterceptor( RestClientBeanPostProcessor.getInterceptor( - openTelemetryProvider.getObject(), configPropertiesProvider.getObject())); + openTelemetryProvider.getObject(), configProvider.getObject())); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/javaSpring3/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvc6InstrumentationAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/javaSpring3/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvc6InstrumentationAutoConfiguration.java index 2dc83966bc5f..b8653d4d3936 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/javaSpring3/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvc6InstrumentationAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/javaSpring3/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvc6InstrumentationAutoConfiguration.java @@ -6,11 +6,11 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.webmvc; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.spring.webmvc.v6_0.SpringWebMvcTelemetry; import io.opentelemetry.instrumentation.spring.webmvc.v6_0.internal.SpringMvcBuilderUtil; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import jakarta.servlet.Filter; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.context.annotation.Bean; @@ -28,7 +28,7 @@ public class SpringWebMvc6InstrumentationAutoConfiguration { @Bean - Filter otelWebMvcFilter(OpenTelemetry openTelemetry, ConfigProperties config) { + Filter otelWebMvcFilter(OpenTelemetry openTelemetry, InstrumentationConfig config) { return InstrumentationConfigUtil.configureServerBuilder( config, SpringWebMvcTelemetry.builder(openTelemetry), 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 1e1a04bb5f10..be29f798f579 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 @@ -26,7 +26,7 @@ /** Spring Boot auto configuration test for {@link OpenTelemetryAutoConfiguration}. */ class OpenTelemetryAutoConfigurationTest { @TestConfiguration - static class CustomTracerConfiguration { + static class CustomOtelConfiguration { @Bean public OpenTelemetry customOpenTelemetry() { return OpenTelemetry.noop(); @@ -48,7 +48,7 @@ public OpenTelemetry customOpenTelemetry() { "when Application Context contains OpenTelemetry bean should NOT initialize openTelemetry") void customOpenTelemetry() { this.contextRunner - .withUserConfiguration(CustomTracerConfiguration.class) + .withUserConfiguration(CustomOtelConfiguration.class) .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)) .run( context -> @@ -152,10 +152,8 @@ void shouldInitializeSdkWhenNotDisabled() { .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)) .withPropertyValues("otel.sdk.disabled=false") .run( - context -> { - assertThat(context).getBean("openTelemetry").isInstanceOf(OpenTelemetrySdk.class); - assertThat(context).hasBean("openTelemetry"); - }); + context -> + assertThat(context).getBean("openTelemetry").isInstanceOf(OpenTelemetrySdk.class)); } @Test diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/jdbc/JdbcInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/jdbc/JdbcInstrumentationAutoConfigurationTest.java index e269ea83693c..a81051228f98 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/jdbc/JdbcInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/jdbc/JdbcInstrumentationAutoConfigurationTest.java @@ -10,8 +10,9 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import java.sql.Connection; import java.sql.Statement; @@ -33,8 +34,10 @@ class JdbcInstrumentationAutoConfigurationTest { private final ApplicationContextRunner runner = new ApplicationContextRunner() .withBean( - ConfigProperties.class, - () -> DefaultConfigProperties.createFromMap(Collections.emptyMap())) + InstrumentationConfig.class, + () -> + new ConfigPropertiesBridge( + DefaultConfigProperties.createFromMap(Collections.emptyMap()))) .withConfiguration( AutoConfigurations.of( JdbcInstrumentationAutoConfiguration.class, DataSourceAutoConfiguration.class)) diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/r2dbc/R2DbcInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/r2dbc/R2DbcInstrumentationAutoConfigurationTest.java index ffdd3c7d0181..bed063c28d1f 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/r2dbc/R2DbcInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/r2dbc/R2DbcInstrumentationAutoConfigurationTest.java @@ -9,8 +9,9 @@ import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import java.util.Collections; import org.junit.jupiter.api.Test; @@ -28,8 +29,10 @@ class R2DbcInstrumentationAutoConfigurationTest { private final ApplicationContextRunner runner = new ApplicationContextRunner() .withBean( - ConfigProperties.class, - () -> DefaultConfigProperties.createFromMap(Collections.emptyMap())) + InstrumentationConfig.class, + () -> + new ConfigPropertiesBridge( + DefaultConfigProperties.createFromMap(Collections.emptyMap()))) .withConfiguration( AutoConfigurations.of( R2dbcInstrumentationAutoConfiguration.class, R2dbcAutoConfiguration.class)) diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java index d5fdb35b2bb8..3306b280869c 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java @@ -13,9 +13,10 @@ import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.code.SemconvCodeStabilityUtil; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.testing.assertj.AttributeAssertion; import io.opentelemetry.sdk.trace.data.StatusData; @@ -39,8 +40,8 @@ class SchedulingInstrumentationAspectTest { private String unproxiedTesterClassName; SpringSchedulingInstrumentationAspect newAspect( - OpenTelemetry openTelemetry, ConfigProperties configProperties) { - return new SpringSchedulingInstrumentationAspect(openTelemetry, configProperties); + OpenTelemetry openTelemetry, InstrumentationConfig config) { + return new SpringSchedulingInstrumentationAspect(openTelemetry, config); } @BeforeEach @@ -56,7 +57,8 @@ void setup() { SpringSchedulingInstrumentationAspect aspect = newAspect( testing.getOpenTelemetry(), - DefaultConfigProperties.createFromMap(Collections.emptyMap())); + new ConfigPropertiesBridge( + DefaultConfigProperties.createFromMap(Collections.emptyMap()))); factory.addAspect(aspect); schedulingTester = factory.getProxy(); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java index 37d91b411d5a..5b631daf1434 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java @@ -8,7 +8,8 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import java.util.Collections; import org.junit.jupiter.api.Test; @@ -20,8 +21,10 @@ class SchedulingInstrumentationAutoConfigurationTest { new ApplicationContextRunner() .withBean(OpenTelemetry.class, OpenTelemetry::noop) .withBean( - ConfigProperties.class, - () -> DefaultConfigProperties.createFromMap(Collections.emptyMap())) + InstrumentationConfig.class, + () -> + new ConfigPropertiesBridge( + DefaultConfigProperties.createFromMap(Collections.emptyMap()))) .withConfiguration( AutoConfigurations.of(SpringSchedulingInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/SpringWebInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/SpringWebInstrumentationAutoConfigurationTest.java index 53bbd882a6d2..8e08dec0ea20 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/SpringWebInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/SpringWebInstrumentationAutoConfigurationTest.java @@ -8,7 +8,8 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import java.util.Collections; import org.junit.jupiter.api.Test; @@ -22,8 +23,10 @@ class SpringWebInstrumentationAutoConfigurationTest { new ApplicationContextRunner() .withBean(OpenTelemetry.class, OpenTelemetry::noop) .withBean( - ConfigProperties.class, - () -> DefaultConfigProperties.createFromMap(Collections.emptyMap())) + InstrumentationConfig.class, + () -> + new ConfigPropertiesBridge( + DefaultConfigProperties.createFromMap(Collections.emptyMap()))) .withBean(RestTemplate.class, RestTemplate::new) .withConfiguration( AutoConfigurations.of(SpringWebInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java index d75814732785..df6273d4686c 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java @@ -8,7 +8,8 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import java.util.Collections; import org.junit.jupiter.api.Test; @@ -21,8 +22,10 @@ class SpringWebfluxInstrumentationAutoConfigurationTest { new ApplicationContextRunner() .withBean(OpenTelemetry.class, OpenTelemetry::noop) .withBean( - ConfigProperties.class, - () -> DefaultConfigProperties.createFromMap(Collections.emptyMap())) + InstrumentationConfig.class, + () -> + new ConfigPropertiesBridge( + DefaultConfigProperties.createFromMap(Collections.emptyMap()))) .withConfiguration( AutoConfigurations.of(SpringWebfluxInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java index 821f0fbfb647..4c25da12a112 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java @@ -8,7 +8,8 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import java.util.Collections; import org.junit.jupiter.api.DisplayName; @@ -24,7 +25,8 @@ class WebClientBeanPostProcessorTest { static { beanFactory.registerSingleton("openTelemetry", OpenTelemetry.noop()); beanFactory.registerSingleton( - "configProperties", DefaultConfigProperties.createFromMap(Collections.emptyMap())); + "configProperties", + new ConfigPropertiesBridge(DefaultConfigProperties.createFromMap(Collections.emptyMap()))); } @Test @@ -34,7 +36,7 @@ void returnsObject() { BeanPostProcessor underTest = new WebClientBeanPostProcessor( beanFactory.getBeanProvider(OpenTelemetry.class), - beanFactory.getBeanProvider(ConfigProperties.class)); + beanFactory.getBeanProvider(InstrumentationConfig.class)); assertThat(underTest.postProcessAfterInitialization(new Object(), "testObject")) .isExactlyInstanceOf(Object.class); @@ -46,7 +48,7 @@ void returnsWebClient() { BeanPostProcessor underTest = new WebClientBeanPostProcessor( beanFactory.getBeanProvider(OpenTelemetry.class), - beanFactory.getBeanProvider(ConfigProperties.class)); + beanFactory.getBeanProvider(InstrumentationConfig.class)); assertThat(underTest.postProcessAfterInitialization(WebClient.create(), "testWebClient")) .isInstanceOf(WebClient.class); @@ -58,7 +60,7 @@ void returnsWebClientBuilder() { BeanPostProcessor underTest = new WebClientBeanPostProcessor( beanFactory.getBeanProvider(OpenTelemetry.class), - beanFactory.getBeanProvider(ConfigProperties.class)); + beanFactory.getBeanProvider(InstrumentationConfig.class)); assertThat( underTest.postProcessAfterInitialization(WebClient.builder(), "testWebClientBuilder")) @@ -71,7 +73,7 @@ void addsExchangeFilterWebClient() { BeanPostProcessor underTest = new WebClientBeanPostProcessor( beanFactory.getBeanProvider(OpenTelemetry.class), - beanFactory.getBeanProvider(ConfigProperties.class)); + beanFactory.getBeanProvider(InstrumentationConfig.class)); WebClient webClient = WebClient.create(); Object processedWebClient = @@ -96,7 +98,7 @@ void addsExchangeFilterWebClientBuilder() { BeanPostProcessor underTest = new WebClientBeanPostProcessor( beanFactory.getBeanProvider(OpenTelemetry.class), - beanFactory.getBeanProvider(ConfigProperties.class)); + beanFactory.getBeanProvider(InstrumentationConfig.class)); WebClient.Builder webClientBuilder = WebClient.builder(); underTest.postProcessAfterInitialization(webClientBuilder, "testWebClientBuilder"); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java index 62112774516e..3c90a46fdfdc 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java @@ -9,7 +9,8 @@ import static org.junit.jupiter.api.Assumptions.assumeFalse; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import java.util.Collections; import javax.servlet.Filter; @@ -24,8 +25,10 @@ class SpringWebMvcInstrumentation5AutoConfigurationTest { new ApplicationContextRunner() .withBean(OpenTelemetry.class, OpenTelemetry::noop) .withBean( - ConfigProperties.class, - () -> DefaultConfigProperties.createFromMap(Collections.emptyMap())) + InstrumentationConfig.class, + () -> + new ConfigPropertiesBridge( + DefaultConfigProperties.createFromMap(Collections.emptyMap()))) .withConfiguration( AutoConfigurations.of(SpringWebMvc5InstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringConfigPropertiesTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringConfigPropertiesTest.java index 02433342b1ab..96c0245747d7 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringConfigPropertiesTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringConfigPropertiesTest.java @@ -86,9 +86,9 @@ void mapFlatHeadersWithUserSuppliedOtelBean(String key) { .withSystemProperties(key + "=a=1,b=2") .withBean(OpenTelemetry.class, OpenTelemetry::noop) .run( - context -> - assertThat(getConfig(context).getMap(key)) - .containsExactly(entry("a", "1"), entry("b", "2"))); + context -> { + // don't crash if OpenTelemetry bean is provided + }); } @ParameterizedTest diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/testDeclarativeConfig/java/io/opentelemetry/instrumentation/spring/autoconfigure/DeclarativeConfigTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/testDeclarativeConfig/java/io/opentelemetry/instrumentation/spring/autoconfigure/DeclarativeConfigTest.java new file mode 100644 index 000000000000..d15468a17944 --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure/src/testDeclarativeConfig/java/io/opentelemetry/instrumentation/spring/autoconfigure/DeclarativeConfigTest.java @@ -0,0 +1,134 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.spring.autoconfigure; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.web.SpringWebInstrumentationAutoConfiguration; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.ConfigDataApplicationContextInitializer; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; + +/** Spring Boot auto configuration test for {@link OpenTelemetryAutoConfiguration}. */ +class DeclarativeConfigTest { + @TestConfiguration + static class CustomTracerConfiguration { + @Bean + public OpenTelemetry customOpenTelemetry() { + return OpenTelemetry.noop(); + } + } + + private final ApplicationContextRunner contextRunner = + new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)) + // to load application.yaml + .withInitializer(new ConfigDataApplicationContextInitializer()); + + @Test + @DisplayName( + "when Application Context contains OpenTelemetry bean should NOT initialize openTelemetry") + void customOpenTelemetry() { + this.contextRunner + .withUserConfiguration(CustomTracerConfiguration.class) + .withPropertyValues("otel.file_format=1.0-rc.1") + .run( + context -> + assertThat(context) + .hasBean("customOpenTelemetry") + .doesNotHaveBean("openTelemetry") + .hasBean("otelProperties")); + } + + @Test + @DisplayName( + "when Application Context DOES NOT contain OpenTelemetry bean should initialize openTelemetry") + void initializeProvidersAndOpenTelemetry() { + this.contextRunner.run( + context -> + assertThat(context) + .hasBean("openTelemetry") + .hasBean("otelProperties") + .getBean(InstrumentationConfig.class) + .isNotNull() + .satisfies( + c -> + assertThat(c.getDeclarativeConfig("foo")) + .isNotNull() + .satisfies( + instrumentationConfig -> + assertThat(instrumentationConfig.getString("bar")) + .isEqualTo("baz")))); + } + + @Test + void shouldInitializeSdkWhenNotDisabled() { + this.contextRunner + .withPropertyValues("otel.file_format=1.0-rc.1", "otel.disabled=false") + .run( + context -> + assertThat(context).getBean("openTelemetry").isInstanceOf(OpenTelemetrySdk.class)); + } + + @Test + void shouldInitializeNoopOpenTelemetryWhenSdkIsDisabled() { + this.contextRunner + .withPropertyValues( + "otel.file_format=1.0-rc.1", + "otel.disabled=true", + "otel.resource.attributes=service.name=workflow-backend-dev,service.version=3c8f9ce9") + .run( + context -> + assertThat(context).getBean("openTelemetry").isEqualTo(OpenTelemetry.noop())); + } + + @Test + void shouldLoadInstrumentation() { + this.contextRunner + .withConfiguration(AutoConfigurations.of(SpringWebInstrumentationAutoConfiguration.class)) + .withPropertyValues("otel.file_format=1.0-rc.1") + .run(context -> assertThat(context).hasBean("otelRestTemplateBeanPostProcessor")); + } + + @Test + void shouldNotLoadInstrumentationWhenDefaultIsDisabled() { + this.contextRunner + .withConfiguration(AutoConfigurations.of(SpringWebInstrumentationAutoConfiguration.class)) + .withPropertyValues( + "otel.file_format=1.0-rc.1", + "otel.instrumentation/development.java.spring_starter.instrumentation_mode=none") + .run(context -> assertThat(context).doesNotHaveBean("otelRestTemplateBeanPostProcessor")); + } + + @Test + void shouldLoadInstrumentationWhenExplicitlyEnabled() { + this.contextRunner + .withConfiguration(AutoConfigurations.of(SpringWebInstrumentationAutoConfiguration.class)) + .withPropertyValues( + "otel.file_format=1.0-rc.1", + "otel.instrumentation/development.java.spring_starter.instrumentation_mode=none", + "otel.instrumentation/development.java.spring_web.enabled=true") + .run(context -> assertThat(context).hasBean("otelRestTemplateBeanPostProcessor")); + } + + @Test + void shouldNotLoadInstrumentationWhenExplicitlyDisabled() { + this.contextRunner + .withConfiguration(AutoConfigurations.of(SpringWebInstrumentationAutoConfiguration.class)) + .withPropertyValues( + "otel.file_format=1.0-rc.1", + "otel.instrumentation/development.java.spring_starter.instrumentation_mode=none", + "otel.instrumentation/development.java.spring_web.enabled=false") + .run(context -> assertThat(context).doesNotHaveBean("otelRestTemplateBeanPostProcessor")); + } +} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/testDeclarativeConfig/resources/application.yaml b/instrumentation/spring/spring-boot-autoconfigure/src/testDeclarativeConfig/resources/application.yaml new file mode 100644 index 000000000000..8f263bc8ff50 --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure/src/testDeclarativeConfig/resources/application.yaml @@ -0,0 +1,10 @@ +otel: + # "file_format" serves as opt-in to the new file format + file_format: "1.0-rc.1" + + # very lightweight test to make sure the declarative config is loaded + # the full config is tested in smoke-tests-otel-starter/spring-boot-2/src/testDeclarativeConfig + instrumentation/development: + java: + foo: + bar: baz diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java index bae340b948ef..3e16f15b23ef 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java @@ -8,7 +8,8 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import java.util.Collections; import org.junit.jupiter.api.Test; @@ -22,8 +23,10 @@ class RestClientInstrumentationAutoConfigurationTest { new ApplicationContextRunner() .withBean(OpenTelemetry.class, OpenTelemetry::noop) .withBean( - ConfigProperties.class, - () -> DefaultConfigProperties.createFromMap(Collections.emptyMap())) + InstrumentationConfig.class, + () -> + new ConfigPropertiesBridge( + DefaultConfigProperties.createFromMap(Collections.emptyMap()))) .withBean(RestClient.class, RestClient::create) .withConfiguration( AutoConfigurations.of(RestClientInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java index d064262095c6..a96d6abc2f4e 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java @@ -9,7 +9,8 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import jakarta.servlet.Filter; import java.util.Collections; @@ -24,8 +25,10 @@ class SpringWebMvcInstrumentation6AutoConfigurationTest { new ApplicationContextRunner() .withBean(OpenTelemetry.class, OpenTelemetry::noop) .withBean( - ConfigProperties.class, - () -> DefaultConfigProperties.createFromMap(Collections.emptyMap())) + InstrumentationConfig.class, + () -> + new ConfigPropertiesBridge( + DefaultConfigProperties.createFromMap(Collections.emptyMap()))) .withConfiguration( AutoConfigurations.of(SpringWebMvc6InstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-kafka-2.7/library/src/main/java/io/opentelemetry/instrumentation/spring/kafka/v2_7/SpringKafkaTelemetry.java b/instrumentation/spring/spring-kafka-2.7/library/src/main/java/io/opentelemetry/instrumentation/spring/kafka/v2_7/SpringKafkaTelemetry.java index c5f88ccbde39..96ce08d8c5ab 100644 --- a/instrumentation/spring/spring-kafka-2.7/library/src/main/java/io/opentelemetry/instrumentation/spring/kafka/v2_7/SpringKafkaTelemetry.java +++ b/instrumentation/spring/spring-kafka-2.7/library/src/main/java/io/opentelemetry/instrumentation/spring/kafka/v2_7/SpringKafkaTelemetry.java @@ -13,6 +13,7 @@ import org.springframework.kafka.listener.AbstractMessageListenerContainer; import org.springframework.kafka.listener.BatchInterceptor; import org.springframework.kafka.listener.RecordInterceptor; +import javax.annotation.Nullable; /** Entrypoint for instrumenting Spring Kafka listeners. */ public final class SpringKafkaTelemetry { @@ -57,7 +58,7 @@ public RecordInterceptor createRecordInterceptor() { * {@link AbstractMessageListenerContainer#setRecordInterceptor(RecordInterceptor)} method. */ public RecordInterceptor createRecordInterceptor( - RecordInterceptor decoratedInterceptor) { + @Nullable RecordInterceptor decoratedInterceptor) { return new InstrumentedRecordInterceptor<>(processInstrumenter, decoratedInterceptor); } @@ -78,7 +79,7 @@ public BatchInterceptor createBatchInterceptor() { * {@link AbstractMessageListenerContainer#setBatchInterceptor(BatchInterceptor)} method. */ public BatchInterceptor createBatchInterceptor( - BatchInterceptor decoratedInterceptor) { + @Nullable BatchInterceptor decoratedInterceptor) { return new InstrumentedBatchInterceptor<>(batchProcessInstrumenter, decoratedInterceptor); } } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java index 035799c06d47..5c7fe70d9f1d 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.tooling.config; import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; +import static java.util.Objects.requireNonNull; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; @@ -119,11 +120,9 @@ public boolean isDeclarative() { @Override public DeclarativeConfigProperties getDeclarativeConfig(String node) { DeclarativeConfigProperties config = - InstrumentationConfigUtil.javaInstrumentationConfig(configProvider, node); + InstrumentationConfigUtil.javaInstrumentationConfig(requireNonNull(configProvider), node); if (config == null) { // there is no declarative config for this node - // this needs to be a different value than null to avoid confusion with - // the case when declarative config is not supported at all return empty(); } return config; diff --git a/smoke-tests-otel-starter/spring-boot-2/build.gradle.kts b/smoke-tests-otel-starter/spring-boot-2/build.gradle.kts index 3aed6f536441..ca6a1752ef0d 100644 --- a/smoke-tests-otel-starter/spring-boot-2/build.gradle.kts +++ b/smoke-tests-otel-starter/spring-boot-2/build.gradle.kts @@ -31,3 +31,22 @@ configurations.configureEach { force("org.slf4j:slf4j-api:1.7.36") } } + +testing { + suites { + val testDeclarativeConfig by registering(JvmTestSuite::class) { + dependencies { + implementation(project()) + implementation(project(":smoke-tests-otel-starter:spring-boot-common")) + implementation("org.springframework.boot:spring-boot-starter-web:2.6.15") + implementation("org.springframework.boot:spring-boot-starter-test:2.6.15") + } + } + } +} + +tasks { + check { + dependsOn(testing.suites) + } +} diff --git a/smoke-tests-otel-starter/spring-boot-2/src/testDeclarativeConfig/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTest.java b/smoke-tests-otel-starter/spring-boot-2/src/testDeclarativeConfig/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTest.java new file mode 100644 index 000000000000..2e0e2d14d6fb --- /dev/null +++ b/smoke-tests-otel-starter/spring-boot-2/src/testDeclarativeConfig/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTest.java @@ -0,0 +1,79 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.spring.smoketest; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.satisfies; + +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.semconv.HttpAttributes; +import io.opentelemetry.semconv.ServiceAttributes; +import io.opentelemetry.semconv.incubating.ServiceIncubatingAttributes; +import io.opentelemetry.semconv.incubating.TelemetryIncubatingAttributes; +import org.assertj.core.api.AbstractCharSequenceAssert; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.web.client.RestTemplate; + +@SpringBootTest( + classes = { + OtelSpringStarterSmokeTestApplication.class, + AbstractOtelSpringStarterSmokeTest.TestConfiguration.class, + SpringSmokeOtelConfiguration.class + }, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@EnableAutoConfiguration(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class}) +class OtelSpringStarterSmokeTest extends AbstractSpringStarterSmokeTest { + + @Autowired private RestTemplateBuilder restTemplateBuilder; + + // can't use @LocalServerPort annotation since it moved packages between Spring Boot 2 and 3 + @Value("${local.server.port}") + private int port; + + @Test + void restTemplate() { + testing.clearAllExportedData(); + + RestTemplate restTemplate = restTemplateBuilder.rootUri("http://localhost:" + port).build(); + restTemplate.getForObject(OtelSpringStarterSmokeTestController.PING, String.class); + testing.waitAndAssertTraces( + traceAssert -> + traceAssert.hasSpansSatisfyingExactly( + span -> + HttpSpanDataAssert.create(span) + .assertClientGetRequest("/ping") + .hasResourceSatisfying( + r -> + r.hasAttribute( + // to make sure the declarative config is picked up + // in application.yaml + ServiceAttributes.SERVICE_NAME, + "declarative-config-spring-boot-2")), + span -> + span.hasKind(SpanKind.SERVER) + .hasResourceSatisfying( + r -> + r.hasAttribute( + TelemetryIncubatingAttributes.TELEMETRY_DISTRO_NAME, + "opentelemetry-spring-boot-starter") + .hasAttribute( + satisfies( + TelemetryIncubatingAttributes.TELEMETRY_DISTRO_VERSION, + AbstractCharSequenceAssert::isNotBlank)) + .hasAttribute( + satisfies( + ServiceIncubatingAttributes.SERVICE_INSTANCE_ID, + AbstractCharSequenceAssert::isNotBlank))) + .hasAttribute(HttpAttributes.HTTP_ROUTE, "/ping"), + AbstractSpringStarterSmokeTest::withSpanAssert)); + } +} diff --git a/smoke-tests-otel-starter/spring-boot-2/src/testDeclarativeConfig/resources/application.yaml b/smoke-tests-otel-starter/spring-boot-2/src/testDeclarativeConfig/resources/application.yaml new file mode 100644 index 000000000000..6b24c0ee67fa --- /dev/null +++ b/smoke-tests-otel-starter/spring-boot-2/src/testDeclarativeConfig/resources/application.yaml @@ -0,0 +1,47 @@ +otel: + # "file_format" serves as opt-in to the new file format + file_format: "1.0-rc.1" + resource: + detection/development: + detectors: + - service: + attributes: + - name: service.name + value: declarative-config-spring-boot-2 + + tracer_provider: + processors: + - simple: + exporter: + test: + - simple: + exporter: + console: + + logger_provider: + processors: + - simple: + exporter: + test: + + meter_provider: + readers: + - periodic: + # Set really long interval. We'll call forceFlush when we need the metrics + # instead of collecting them periodically. + interval: 1000000 + exporter: + test: + + propagator: + composite: + - tracecontext: + - baggage: + + instrumentation/development: + java: + runtime-telemetry: + emit_experimental_telemetry: true + http: + client: + emit_experimental_telemetry: true diff --git a/smoke-tests-otel-starter/spring-smoke-testing/src/main/java/io/opentelemetry/spring/smoketest/SpringSmokeTestRunner.java b/smoke-tests-otel-starter/spring-smoke-testing/src/main/java/io/opentelemetry/spring/smoketest/SpringSmokeTestRunner.java index 471016ee883e..0675f3b0b61a 100644 --- a/smoke-tests-otel-starter/spring-smoke-testing/src/main/java/io/opentelemetry/spring/smoketest/SpringSmokeTestRunner.java +++ b/smoke-tests-otel-starter/spring-smoke-testing/src/main/java/io/opentelemetry/spring/smoketest/SpringSmokeTestRunner.java @@ -7,6 +7,9 @@ import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.testing.InstrumentationTestRunner; +import io.opentelemetry.instrumentation.testing.provider.TestLogRecordExporterComponentProvider; +import io.opentelemetry.instrumentation.testing.provider.TestMetricExporterComponentProvider; +import io.opentelemetry.instrumentation.testing.provider.TestSpanExporterComponentProvider; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.MetricData; @@ -36,6 +39,11 @@ static void resetExporters() { testSpanExporter = InMemorySpanExporter.create(); testMetricExporter = InMemoryMetricExporter.create(AggregationTemporality.DELTA); testLogRecordExporter = InMemoryLogRecordExporter.create(); + + // for declarative config + TestLogRecordExporterComponentProvider.setLogRecordExporter(testLogRecordExporter); + TestMetricExporterComponentProvider.setMetricExporter(testMetricExporter); + TestSpanExporterComponentProvider.setSpanExporter(testSpanExporter); } @Override