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 a5745ce83450..5557b5720cf7 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 @@ -7,49 +7,31 @@ import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.trace.TracerProvider; -import io.opentelemetry.context.propagation.ContextPropagators; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpExporterProperties; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpLogRecordExporterAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpMetricExporterAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpSpanExporterAutoConfiguration; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.MapConverter; -import io.opentelemetry.instrumentation.spring.autoconfigure.propagators.PropagationProperties; -import io.opentelemetry.instrumentation.spring.autoconfigure.resources.OtelResourceAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.resources.OtelResourceProperties; -import io.opentelemetry.instrumentation.spring.autoconfigure.resources.SpringConfigProperties; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.OtelResourceProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.OtlpExporterProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.PropagationProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.SpringConfigProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.resources.DistroVersionResourceProvider; +import io.opentelemetry.instrumentation.spring.autoconfigure.resources.SpringResourceProvider; +import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; +import io.opentelemetry.sdk.autoconfigure.internal.ComponentLoader; +import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; -import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; -import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; -import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import io.opentelemetry.sdk.metrics.SdkMeterProvider; -import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder; -import io.opentelemetry.sdk.metrics.export.MetricExporter; -import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader; -import io.opentelemetry.sdk.metrics.export.PeriodicMetricReaderBuilder; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; -import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import io.opentelemetry.sdk.trace.samplers.Sampler; -import java.time.Duration; -import java.util.Collections; import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; -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; +import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; -import org.springframework.expression.spel.standard.SpelExpressionParser; /** * Create {@link io.opentelemetry.api.OpenTelemetry} bean if bean is missing. @@ -60,7 +42,6 @@ */ @Configuration @EnableConfigurationProperties({ - SamplerProperties.class, OtlpExporterProperties.class, OtelResourceProperties.class, PropagationProperties.class @@ -76,143 +57,54 @@ public static class OpenTelemetrySdkConfig { @Bean @ConfigurationPropertiesBinding - @Conditional(MapConverterCondition.class) public MapConverter mapConverter() { // needed for otlp exporter headers and OtelResourceProperties return new MapConverter(); } - static final class MapConverterCondition extends AnyNestedCondition { - public MapConverterCondition() { - super(ConfigurationPhase.REGISTER_BEAN); - } - - @ConditionalOnBean(OtelResourceAutoConfiguration.class) - static class Resource {} - - @ConditionalOnBean(OtlpLogRecordExporterAutoConfiguration.class) - static class Logger {} - - @ConditionalOnBean(OtlpSpanExporterAutoConfiguration.class) - static class Span {} - - @ConditionalOnBean(OtlpMetricExporterAutoConfiguration.class) - static class Metric {} - } - @Bean - @ConditionalOnMissingBean - ConfigProperties configProperties( - Environment env, - OtlpExporterProperties otlpExporterProperties, - OtelResourceProperties resourceProperties, - PropagationProperties propagationProperties) { - return new SpringConfigProperties( - env, - new SpelExpressionParser(), - otlpExporterProperties, - resourceProperties, - propagationProperties); - } - - @Bean(destroyMethod = "") // SDK components are shutdown from the OpenTelemetry instance - @ConditionalOnMissingBean - public SdkTracerProvider sdkTracerProvider( - SamplerProperties samplerProperties, - ObjectProvider> spanExportersProvider, - Resource otelResource) { - SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder(); - - spanExportersProvider.getIfAvailable(Collections::emptyList).stream() - .map(spanExporter -> BatchSpanProcessor.builder(spanExporter).build()) - .forEach(tracerProviderBuilder::addSpanProcessor); - - return tracerProviderBuilder - .setResource(otelResource) - .setSampler(Sampler.traceIdRatioBased(samplerProperties.getProbability())) - .build(); - } - - @Bean(destroyMethod = "") // SDK components are shutdown from the OpenTelemetry instance - @ConditionalOnMissingBean - public SdkLoggerProvider sdkLoggerProvider( - ObjectProvider> loggerExportersProvider, Resource otelResource) { - - SdkLoggerProviderBuilder loggerProviderBuilder = SdkLoggerProvider.builder(); - loggerProviderBuilder.setResource(otelResource); - - loggerExportersProvider - .getIfAvailable(Collections::emptyList) - .forEach( - loggerExporter -> - loggerProviderBuilder.addLogRecordProcessor( - BatchLogRecordProcessor.builder(loggerExporter).build())); - - return loggerProviderBuilder.build(); + public OpenTelemetrySdkComponentLoader openTelemetrySdkComponentLoader( + ApplicationContext applicationContext) { + return new OpenTelemetrySdkComponentLoader(applicationContext); } - @Bean(destroyMethod = "") // SDK components are shutdown from the OpenTelemetry instance - @ConditionalOnMissingBean - public SdkMeterProvider sdkMeterProvider( - ConfigProperties configProperties, - ObjectProvider> metricExportersProvider, - Resource otelResource) { - - SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder(); - - metricExportersProvider.getIfAvailable(Collections::emptyList).stream() - .map(metricExporter -> createPeriodicMetricReader(configProperties, metricExporter)) - .forEach(meterProviderBuilder::registerMetricReader); - - return meterProviderBuilder.setResource(otelResource).build(); - } - - private static PeriodicMetricReader createPeriodicMetricReader( - ConfigProperties properties, MetricExporter metricExporter) { - PeriodicMetricReaderBuilder metricReaderBuilder = - PeriodicMetricReader.builder(metricExporter); - Duration interval = properties.getDuration("otel.metric.export.interval"); - if (interval != null) { - metricReaderBuilder.setInterval(interval); - } - return metricReaderBuilder.build(); + @Bean + public ResourceProvider otelSpringResourceProvider(Optional buildProperties) { + return new SpringResourceProvider(buildProperties); } @Bean - @ConditionalOnMissingBean - public Resource otelResource( - ConfigProperties config, ObjectProvider> resourceProviders) { - Resource resource = Resource.getDefault(); - for (ResourceProvider resourceProvider : - resourceProviders.getIfAvailable(Collections::emptyList)) { - resource = resource.merge(resourceProvider.createResource(config)); - } - return resource; + public ResourceProvider otelDistroVersionResourceProvider() { + return new DistroVersionResourceProvider(); } @Bean // If you change the bean name, also change it in the OpenTelemetryJdbcDriverAutoConfiguration // class public OpenTelemetry openTelemetry( - ObjectProvider propagatorsProvider, - SdkTracerProvider tracerProvider, - SdkMeterProvider meterProvider, - SdkLoggerProvider loggerProvider, - ObjectProvider> openTelemetryConsumerProvider) { - - ContextPropagators propagators = propagatorsProvider.getIfAvailable(ContextPropagators::noop); - - OpenTelemetrySdk openTelemetry = - OpenTelemetrySdk.builder() - .setTracerProvider(tracerProvider) - .setMeterProvider(meterProvider) - .setLoggerProvider(loggerProvider) - .setPropagators(propagators) - .build(); - - List openTelemetryInjectors = - openTelemetryConsumerProvider.getIfAvailable(() -> Collections.emptyList()); - openTelemetryInjectors.forEach(consumer -> consumer.accept(openTelemetry)); + Environment env, + OtlpExporterProperties otlpExporterProperties, + OtelResourceProperties resourceProperties, + PropagationProperties propagationProperties, + OpenTelemetrySdkComponentLoader componentLoader, + ObjectProvider openTelemetryConsumerProvider) { + + OpenTelemetry openTelemetry = + AutoConfigureUtil.setComponentLoader( + AutoConfigureUtil.setConfigPropertiesCustomizer( + AutoConfiguredOpenTelemetrySdk.builder(), + c -> + SpringConfigProperties.create( + env, + otlpExporterProperties, + resourceProperties, + propagationProperties, + c)), + componentLoader) + .build() + .getOpenTelemetrySdk(); + + openTelemetryConsumerProvider.forEach(consumer -> consumer.accept(openTelemetry)); return openTelemetry; } @@ -228,4 +120,29 @@ public OpenTelemetry openTelemetry() { return OpenTelemetry.noop(); } } + + /** + * The {@link ComponentLoader} is used by the SDK autoconfiguration to load all components, e.g. + * here + */ + public static class OpenTelemetrySdkComponentLoader implements ComponentLoader { + private final ApplicationContext applicationContext; + + private final SpiHelper spiHelper = + SpiHelper.create(OpenTelemetrySdkComponentLoader.class.getClassLoader()); + + public OpenTelemetrySdkComponentLoader(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + } + + @Override + public Iterable load(Class spiClass) { + List spi = spiHelper.load(spiClass); + List beans = + applicationContext.getBeanProvider(spiClass).orderedStream().collect(Collectors.toList()); + spi.addAll(beans); + return spi; + } + } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/SamplerProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/SamplerProperties.java deleted file mode 100644 index 7d8de1918ffb..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/SamplerProperties.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure; - -import javax.validation.constraints.DecimalMax; -import javax.validation.constraints.DecimalMin; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Configuration for OpenTelemetry Sampler. - * - *

Get Sampling Probability - */ -@ConfigurationProperties(prefix = "otel.traces.sampler") -public final class SamplerProperties { - - // if Sample probability == 1: always sample - // if Sample probability == 0: never sample - @DecimalMin("0.0") - @DecimalMax("1.0") - private double probability = 1.0; - - public double getProbability() { - return probability; - } - - public void setProbability(double probability) { - this.probability = probability; - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/internal/ExporterConfigEvaluator.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/internal/ExporterConfigEvaluator.java deleted file mode 100644 index d3051fc633a6..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/internal/ExporterConfigEvaluator.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.internal; - -import java.util.Arrays; -import org.springframework.core.env.Environment; - -/** - * This class is internal and is hence not for public use. Its APIs are unstable and can change at - * any time. - */ -public final class ExporterConfigEvaluator { - - private ExporterConfigEvaluator() {} - - /** - * Returns whether the exporter is enabled. This method is used for OTLP, logging and zipkin - * exporters. - */ - public static boolean isExporterEnabled( - Environment environment, String exportersKey, String wantExporter, boolean defaultValue) { - String exporter = environment.getProperty(exportersKey); - if (exporter != null) { - return Arrays.asList(exporter.split(",")).contains(wantExporter); - } - - return defaultValue; - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/LoggingMetricExporterAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/LoggingMetricExporterAutoConfiguration.java deleted file mode 100644 index 8fb8f40c4997..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/LoggingMetricExporterAutoConfiguration.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging; - -import io.opentelemetry.exporter.logging.LoggingMetricExporter; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.internal.ExporterConfigEvaluator; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Condition; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.type.AnnotatedTypeMetadata; - -/** Configures {@link LoggingMetricExporter} bean for tracing. */ -@Configuration -@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class) -@Conditional({LoggingMetricExporterAutoConfiguration.CustomCondition.class, SdkEnabled.class}) -@ConditionalOnClass(LoggingMetricExporter.class) -public class LoggingMetricExporterAutoConfiguration { - - @Bean(destroyMethod = "") // SDK components are shutdown from the OpenTelemetry instance - @ConditionalOnMissingBean - public LoggingMetricExporter otelLoggingMetricExporter() { - return LoggingMetricExporter.create(); - } - - static final class CustomCondition implements Condition { - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return ExporterConfigEvaluator.isExporterEnabled( - context.getEnvironment(), "otel.metrics.exporter", "logging", false); - } - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/LoggingSpanExporterAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/LoggingSpanExporterAutoConfiguration.java deleted file mode 100644 index a57a9579366b..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/LoggingSpanExporterAutoConfiguration.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging; - -import io.opentelemetry.exporter.logging.LoggingSpanExporter; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.internal.ExporterConfigEvaluator; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Condition; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.type.AnnotatedTypeMetadata; - -/** Configures {@link LoggingSpanExporter} bean for tracing. */ -@Configuration -@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class) -@Conditional({LoggingSpanExporterAutoConfiguration.CustomCondition.class, SdkEnabled.class}) -@ConditionalOnClass(LoggingSpanExporter.class) -public class LoggingSpanExporterAutoConfiguration { - - @Bean(destroyMethod = "") // SDK components are shutdown from the OpenTelemetry instance - @ConditionalOnMissingBean - public LoggingSpanExporter otelLoggingSpanExporter() { - return LoggingSpanExporter.create(); - } - - static final class CustomCondition implements Condition { - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return ExporterConfigEvaluator.isExporterEnabled( - context.getEnvironment(), "otel.traces.exporter", "logging", false); - } - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/SystemOutLogRecordExporterAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/SystemOutLogRecordExporterAutoConfiguration.java deleted file mode 100644 index 22c75276c6c1..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/SystemOutLogRecordExporterAutoConfiguration.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging; - -import io.opentelemetry.exporter.logging.SystemOutLogRecordExporter; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.internal.ExporterConfigEvaluator; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Condition; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.type.AnnotatedTypeMetadata; - -/** Configures {@link SystemOutLogRecordExporter} bean for tracing. */ -@Configuration -@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class) -@Conditional({SystemOutLogRecordExporterAutoConfiguration.CustomCondition.class, SdkEnabled.class}) -@ConditionalOnClass(SystemOutLogRecordExporter.class) -public class SystemOutLogRecordExporterAutoConfiguration { - - @Bean(destroyMethod = "") // SDK components are shutdown from the OpenTelemetry instance - @ConditionalOnMissingBean - public SystemOutLogRecordExporter otelSystemOutLogRecordExporter() { - return SystemOutLogRecordExporter.create(); - } - - static final class CustomCondition implements Condition { - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return ExporterConfigEvaluator.isExporterEnabled( - context.getEnvironment(), "otel.logs.exporter", "logging", false); - } - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpLogRecordExporterAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpLogRecordExporterAutoConfiguration.java deleted file mode 100644 index 5fbe71bbdc2b..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpLogRecordExporterAutoConfiguration.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp; - -import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; -import io.opentelemetry.exporter.otlp.internal.OtlpLogRecordExporterProvider; -import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.internal.ExporterConfigEvaluator; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import io.opentelemetry.sdk.logs.export.LogRecordExporter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Condition; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.Conditional; -import org.springframework.core.type.AnnotatedTypeMetadata; - -@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class) -@Conditional({OtlpLogRecordExporterAutoConfiguration.CustomCondition.class, SdkEnabled.class}) -@ConditionalOnClass(OtlpGrpcLogRecordExporter.class) -public class OtlpLogRecordExporterAutoConfiguration { - - @Bean(destroyMethod = "") // SDK components are shutdown from the OpenTelemetry instance - @ConditionalOnMissingBean({OtlpGrpcLogRecordExporter.class, OtlpHttpLogRecordExporter.class}) - public LogRecordExporter otelOtlpLogRecordExporter(ConfigProperties configProperties) { - return new OtlpLogRecordExporterProvider().createExporter(configProperties); - } - - static final class CustomCondition implements Condition { - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return ExporterConfigEvaluator.isExporterEnabled( - context.getEnvironment(), "otel.logs.exporter", "otlp", true); - } - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpMetricExporterAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpMetricExporterAutoConfiguration.java deleted file mode 100644 index 89d8e5334cfd..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpMetricExporterAutoConfiguration.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp; - -import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; -import io.opentelemetry.exporter.otlp.internal.OtlpMetricExporterProvider; -import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.internal.ExporterConfigEvaluator; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import io.opentelemetry.sdk.metrics.export.MetricExporter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Condition; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.type.AnnotatedTypeMetadata; - -@Configuration -@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class) -@Conditional({OtlpMetricExporterAutoConfiguration.CustomCondition.class, SdkEnabled.class}) -@ConditionalOnClass(OtlpGrpcMetricExporter.class) -public class OtlpMetricExporterAutoConfiguration { - - @Bean(destroyMethod = "") // SDK components are shutdown from the OpenTelemetry instance - @ConditionalOnMissingBean({OtlpGrpcMetricExporter.class, OtlpHttpMetricExporter.class}) - public MetricExporter otelOtlpMetricExporter(ConfigProperties configProperties) { - return new OtlpMetricExporterProvider().createExporter(configProperties); - } - - static final class CustomCondition implements Condition { - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return ExporterConfigEvaluator.isExporterEnabled( - context.getEnvironment(), "otel.metrics.exporter", "otlp", true); - } - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpSpanExporterAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpSpanExporterAutoConfiguration.java deleted file mode 100644 index 147a041314d4..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpSpanExporterAutoConfiguration.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp; - -import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; -import io.opentelemetry.exporter.otlp.internal.OtlpSpanExporterProvider; -import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.internal.ExporterConfigEvaluator; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Condition; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.type.AnnotatedTypeMetadata; - -/** - * Configures {@link OtlpGrpcSpanExporter} for tracing. - * - *

Initializes {@link OtlpGrpcSpanExporter} bean if bean is missing. - */ -@Configuration -@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class) -@Conditional({OtlpSpanExporterAutoConfiguration.CustomCondition.class, SdkEnabled.class}) -@ConditionalOnClass(OtlpGrpcSpanExporter.class) -public class OtlpSpanExporterAutoConfiguration { - - @Bean(destroyMethod = "") // SDK components are shutdown from the OpenTelemetry instance - @ConditionalOnMissingBean({OtlpGrpcSpanExporter.class, OtlpHttpSpanExporter.class}) - public SpanExporter otelOtlpSpanExporter(ConfigProperties configProperties) { - return new OtlpSpanExporterProvider().createExporter(configProperties); - } - - static final class CustomCondition implements Condition { - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return ExporterConfigEvaluator.isExporterEnabled( - context.getEnvironment(), "otel.traces.exporter", "otlp", true); - } - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/zipkin/ZipkinSpanExporterAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/zipkin/ZipkinSpanExporterAutoConfiguration.java deleted file mode 100644 index 69c18442625a..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/zipkin/ZipkinSpanExporterAutoConfiguration.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.zipkin; - -import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; -import io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.internal.ExporterConfigEvaluator; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Condition; -import org.springframework.context.annotation.ConditionContext; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.type.AnnotatedTypeMetadata; - -/** - * Configures {@link ZipkinSpanExporter} for tracing. - * - *

Initializes {@link ZipkinSpanExporter} bean if bean is missing. - */ -@Configuration -@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class) -@EnableConfigurationProperties(ZipkinSpanExporterProperties.class) -@Conditional({ZipkinSpanExporterAutoConfiguration.CustomCondition.class, SdkEnabled.class}) -@ConditionalOnClass(ZipkinSpanExporter.class) -public class ZipkinSpanExporterAutoConfiguration { - - @Bean(destroyMethod = "") // SDK components are shutdown from the OpenTelemetry instance - @ConditionalOnMissingBean - public ZipkinSpanExporter otelZipkinSpanExporter(ZipkinSpanExporterProperties properties) { - - ZipkinSpanExporterBuilder builder = ZipkinSpanExporter.builder(); - if (properties.getEndpoint() != null) { - builder.setEndpoint(properties.getEndpoint()); - } - return builder.build(); - } - - static final class CustomCondition implements Condition { - @Override - public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { - return ExporterConfigEvaluator.isExporterEnabled( - context.getEnvironment(), "otel.traces.exporter", "zipkin", true); - } - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/zipkin/ZipkinSpanExporterProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/zipkin/ZipkinSpanExporterProperties.java deleted file mode 100644 index d7e1df91b948..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/zipkin/ZipkinSpanExporterProperties.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.zipkin; - -import javax.annotation.Nullable; -import org.springframework.boot.context.properties.ConfigurationProperties; - -/** - * Configuration for {@link io.opentelemetry.exporter.zipkin.ZipkinSpanExporter}. - * - *

Get Exporter Endpoint - */ -@ConfigurationProperties(prefix = "otel.exporter.zipkin") -public class ZipkinSpanExporterProperties { - - @Nullable private String endpoint; - - @Nullable - public String getEndpoint() { - return endpoint; - } - - public void setEndpoint(String endpoint) { - this.endpoint = endpoint; - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/propagators/CompositeTextMapPropagatorFactory.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/propagators/CompositeTextMapPropagatorFactory.java deleted file mode 100644 index 38c9f7ac3f3c..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/propagators/CompositeTextMapPropagatorFactory.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.propagators; - -import static java.util.logging.Level.WARNING; - -import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; -import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; -import io.opentelemetry.context.propagation.TextMapPropagator; -import io.opentelemetry.contrib.awsxray.propagator.AwsXrayPropagator; -import io.opentelemetry.extension.trace.propagation.B3Propagator; -import io.opentelemetry.extension.trace.propagation.OtTracePropagator; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.logging.Logger; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.util.ClassUtils; - -/** Factory of composite {@link TextMapPropagator}. Defaults to W3C and BAGGAGE. */ -public final class CompositeTextMapPropagatorFactory { - - private static final Logger logger = - Logger.getLogger(CompositeTextMapPropagatorFactory.class.getName()); - - static TextMapPropagator getCompositeTextMapPropagator( - BeanFactory beanFactory, List types) { - - Set propagators = new HashSet<>(); - - for (String type : types) { - switch (type) { - case "b3": - if (isOnClasspath("io.opentelemetry.extension.trace.propagation.B3Propagator")) { - propagators.add( - beanFactory - .getBeanProvider(B3Propagator.class) - .getIfAvailable(B3Propagator::injectingSingleHeader)); - } - break; - case "b3multi": - if (isOnClasspath("io.opentelemetry.extension.trace.propagation.B3Propagator")) { - propagators.add( - beanFactory - .getBeanProvider(B3Propagator.class) - .getIfAvailable(B3Propagator::injectingMultiHeaders)); - } - break; - case "ottrace": - if (isOnClasspath("io.opentelemetry.extension.trace.propagation.OtTracerPropagator")) { - propagators.add( - beanFactory - .getBeanProvider(OtTracePropagator.class) - .getIfAvailable(OtTracePropagator::getInstance)); - } - break; - case "xray": - if (isOnClasspath("io.opentelemetry.contrib.awsxray.propagator.AwsXrayPropagator")) { - propagators.add( - beanFactory - .getBeanProvider(AwsXrayPropagator.class) - .getIfAvailable(AwsXrayPropagator::getInstance)); - } - break; - case "tracecontext": - propagators.add(W3CTraceContextPropagator.getInstance()); - break; - case "baggage": - propagators.add(W3CBaggagePropagator.getInstance()); - break; - default: - logger.log(WARNING, "Unsupported type of propagator: {0}", type); - break; - } - } - - return TextMapPropagator.composite(propagators); - } - - private static boolean isOnClasspath(String clazz) { - return ClassUtils.isPresent(clazz, CompositeTextMapPropagatorFactory.class.getClassLoader()); - } - - private CompositeTextMapPropagatorFactory() {} -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/propagators/PropagationAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/propagators/PropagationAutoConfiguration.java deleted file mode 100644 index af4e0d4f8f1c..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/propagators/PropagationAutoConfiguration.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.propagators; - -import io.opentelemetry.context.propagation.ContextPropagators; -import io.opentelemetry.context.propagation.TextMapPropagator; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; - -/** Configures {@link ContextPropagators} bean for propagation. */ -@Configuration -@EnableConfigurationProperties(PropagationProperties.class) -@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class) -@ConditionalOnProperty(prefix = "otel.propagation", name = "enabled", matchIfMissing = true) -@Conditional(SdkEnabled.class) -public class PropagationAutoConfiguration { - - private static final List DEFAULT_PROPAGATORS = Arrays.asList("tracecontext", "baggage"); - - @Bean - @ConditionalOnMissingBean - ContextPropagators contextPropagators(ObjectProvider> propagators) { - List mapPropagators = propagators.getIfAvailable(Collections::emptyList); - if (mapPropagators.isEmpty()) { - return ContextPropagators.noop(); - } - return ContextPropagators.create(TextMapPropagator.composite(mapPropagators)); - } - - @Configuration - static class PropagatorsConfiguration { - - @Bean - TextMapPropagator compositeTextMapPropagator( - BeanFactory beanFactory, ConfigProperties configProperties) { - return CompositeTextMapPropagatorFactory.getCompositeTextMapPropagator( - beanFactory, configProperties.getList("otel.propagators", DEFAULT_PROPAGATORS)); - } - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/OtelResourceProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/OtelResourceProperties.java similarity index 88% rename from instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/OtelResourceProperties.java rename to instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/OtelResourceProperties.java index e4eface5ea24..954f3c26ae70 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/OtelResourceProperties.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/OtelResourceProperties.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.spring.autoconfigure.resources; +package io.opentelemetry.instrumentation.spring.autoconfigure.properties; import java.util.Collections; import java.util.Map; diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpExporterProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/OtlpExporterProperties.java similarity index 93% rename from instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpExporterProperties.java rename to instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/OtlpExporterProperties.java index 9ec65498e71e..d645c363bf2b 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpExporterProperties.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/OtlpExporterProperties.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp; +package io.opentelemetry.instrumentation.spring.autoconfigure.properties; import java.util.HashMap; import java.util.Map; diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/propagators/PropagationProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/PropagationProperties.java similarity index 98% rename from instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/propagators/PropagationProperties.java rename to instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/PropagationProperties.java index 6c4ed8f92420..00be4467e2d1 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/propagators/PropagationProperties.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/PropagationProperties.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.spring.autoconfigure.propagators; +package io.opentelemetry.instrumentation.spring.autoconfigure.properties; import java.util.Collections; import java.util.List; diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringConfigProperties.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/SpringConfigProperties.java similarity index 69% rename from instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringConfigProperties.java rename to instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/SpringConfigProperties.java index 75b3a487a357..1f707ff6b426 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringConfigProperties.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/SpringConfigProperties.java @@ -3,11 +3,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.spring.autoconfigure.resources; +package io.opentelemetry.instrumentation.spring.autoconfigure.properties; import io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpExporterProperties; -import io.opentelemetry.instrumentation.spring.autoconfigure.propagators.PropagationProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import java.time.Duration; @@ -17,6 +15,7 @@ import javax.annotation.Nullable; import org.springframework.core.env.Environment; import org.springframework.expression.ExpressionParser; +import org.springframework.expression.spel.standard.SpelExpressionParser; public class SpringConfigProperties implements ConfigProperties { private final Environment environment; @@ -25,18 +24,37 @@ public class SpringConfigProperties implements ConfigProperties { private final OtlpExporterProperties otlpExporterProperties; private final OtelResourceProperties resourceProperties; private final PropagationProperties propagationProperties; + private final ConfigProperties fallback; public SpringConfigProperties( Environment environment, ExpressionParser parser, OtlpExporterProperties otlpExporterProperties, OtelResourceProperties resourceProperties, - PropagationProperties propagationProperties) { + PropagationProperties propagationProperties, + ConfigProperties fallback) { this.environment = environment; this.parser = parser; this.otlpExporterProperties = otlpExporterProperties; this.resourceProperties = resourceProperties; this.propagationProperties = propagationProperties; + this.fallback = fallback; + } + + // visible for testing + public static ConfigProperties create( + Environment env, + OtlpExporterProperties otlpExporterProperties, + OtelResourceProperties resourceProperties, + PropagationProperties propagationProperties, + ConfigProperties fallback) { + return new SpringConfigProperties( + env, + new SpelExpressionParser(), + otlpExporterProperties, + resourceProperties, + propagationProperties, + fallback); } @Nullable @@ -48,31 +66,31 @@ public String getString(String name) { // in specification to default to `http/protobuf` return OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF; } - return value; + return or(value, fallback.getString(name)); } @Nullable @Override public Boolean getBoolean(String name) { - return environment.getProperty(name, Boolean.class); + return or(environment.getProperty(name, Boolean.class), fallback.getBoolean(name)); } @Nullable @Override public Integer getInt(String name) { - return environment.getProperty(name, Integer.class); + return or(environment.getProperty(name, Integer.class), fallback.getInt(name)); } @Nullable @Override public Long getLong(String name) { - return environment.getProperty(name, Long.class); + return or(environment.getProperty(name, Long.class), fallback.getLong(name)); } @Nullable @Override public Double getDouble(String name) { - return environment.getProperty(name, Double.class); + return or(environment.getProperty(name, Double.class), fallback.getDouble(name)); } @SuppressWarnings("unchecked") @@ -82,8 +100,7 @@ public List getList(String name) { return propagationProperties.getPropagators(); } - List value = environment.getProperty(name, List.class); - return value == null ? Collections.emptyList() : value; + return or(environment.getProperty(name, List.class), fallback.getList(name)); } @Nullable @@ -91,7 +108,7 @@ public List getList(String name) { public Duration getDuration(String name) { String value = getString(name); if (value == null) { - return null; + return fallback.getDuration(name); } return DefaultConfigProperties.createFromMap(Collections.singletonMap(name, value)) .getDuration(name); @@ -118,8 +135,13 @@ public Map getMap(String name) { String value = environment.getProperty(name); if (value == null) { - return Collections.emptyMap(); + return fallback.getMap(name); } return (Map) parser.parseExpression(value).getValue(); } + + @Nullable + private static T or(@Nullable T first, @Nullable T second) { + return first != null ? first : second; + } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/OtelResourceAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/OtelResourceAutoConfiguration.java deleted file mode 100644 index dd732636334a..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/OtelResourceAutoConfiguration.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.resources; - -import io.opentelemetry.instrumentation.resources.ContainerResource; -import io.opentelemetry.instrumentation.resources.ContainerResourceProvider; -import io.opentelemetry.instrumentation.resources.HostResource; -import io.opentelemetry.instrumentation.resources.HostResourceProvider; -import io.opentelemetry.instrumentation.resources.OsResource; -import io.opentelemetry.instrumentation.resources.OsResourceProvider; -import io.opentelemetry.instrumentation.resources.ProcessResource; -import io.opentelemetry.instrumentation.resources.ProcessResourceProvider; -import io.opentelemetry.instrumentation.resources.ProcessRuntimeResource; -import io.opentelemetry.instrumentation.resources.ProcessRuntimeResourceProvider; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; -import io.opentelemetry.sdk.autoconfigure.internal.EnvironmentResourceProvider; -import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; -import java.util.Optional; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.info.BuildProperties; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Conditional; -import org.springframework.context.annotation.Configuration; - -@Configuration -@EnableConfigurationProperties({OtelResourceProperties.class}) -@AutoConfigureBefore(OpenTelemetryAutoConfiguration.class) -@ConditionalOnProperty(prefix = "otel.springboot.resource", name = "enabled", matchIfMissing = true) -@Conditional(SdkEnabled.class) -public class OtelResourceAutoConfiguration { - - @Bean - public ResourceProvider otelEnvironmentResourceProvider() { - return new EnvironmentResourceProvider(); - } - - @Bean - public ResourceProvider otelSpringResourceProvider(Optional buildProperties) { - return new SpringResourceProvider(buildProperties); - } - - @Bean - public ResourceProvider otelDistroVersionResourceProvider() { - return new DistroVersionResourceProvider(); - } - - @Bean - @ConditionalOnClass(OsResource.class) - public ResourceProvider otelOsResourceProvider() { - return new OsResourceProvider(); - } - - @Bean - @ConditionalOnClass(ProcessResource.class) - public ResourceProvider otelProcessResourceProvider() { - return new ProcessResourceProvider(); - } - - @Bean - @ConditionalOnClass(ProcessRuntimeResource.class) - public ResourceProvider otelProcessRuntimeResourceProvider() { - return new ProcessRuntimeResourceProvider(); - } - - @Bean - @ConditionalOnClass(HostResource.class) - public ResourceProvider otelHostResourceProvider() { - return new HostResourceProvider(); - } - - @Bean - @ConditionalOnClass(ContainerResource.class) - public ResourceProvider otelContainerResourceProvider() { - return new ContainerResourceProvider(); - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 587aadc4c0ba..c98ed28ab3b0 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -5,12 +5,82 @@ } ], "properties": [ + { + "name": "otel.attribute.count.limit", + "type": "java.lang.Integer", + "description": "The maximum number of attributes. Applies to spans, span events, span links, and logs.", + "defaultValue": 128 + }, + { + "name": "otel.attribute.value.length.limit", + "type": "java.lang.String", + "description": "The maximum length of attribute values. Applies to spans and logs. By default, there is no limit." + }, + { + "name": "otel.blrp.export.timeout", + "type": "java.lang.String", + "description": "The maximum allowed time, in milliseconds, to export OTLP log batch data.
Durations can be of the form {number}{unit}, where unit is one of:

  • ms
  • s
  • m
  • h
  • d

If no unit is specified, milliseconds is the assumed duration unit.", + "defaultValue": 30000 + }, + { + "name": "otel.blrp.max.export.batch.size", + "type": "java.lang.Integer", + "description": "The maximum OTLP log batch size.", + "defaultValue": 512 + }, + { + "name": "otel.blrp.max.queue.size", + "type": "java.lang.Integer", + "description": "The maximum OTLP log batch queue size.", + "defaultValue": 2048 + }, + { + "name": "otel.blrp.schedule.delay", + "type": "java.lang.String", + "description": "The interval, in milliseconds, between two consecutive OTLP log batch exports.
Durations can be of the form {number}{unit}, where unit is one of:

  • ms
  • s
  • m
  • h
  • d

If no unit is specified, milliseconds is the assumed duration unit.", + "defaultValue": 1000 + }, + { + "name": "otel.bsp.schedule.delay", + "type": "java.lang.String", + "description": "The interval, in milliseconds, between two consecutive OTLP span batch exports.
Durations can be of the form {number}{unit}, where unit is one of:

  • ms
  • s
  • m
  • h
  • d

If no unit is specified, milliseconds is the assumed duration unit.", + "defaultValue": 5000 + }, + { + "name": "otel.bsp.export.timeout", + "type": "java.lang.String", + "description": "The maximum allowed time, in milliseconds, to export OTLP span batch data.
Durations can be of the form {number}{unit}, where unit is one of:

  • ms
  • s
  • m
  • h
  • d

If no unit is specified, milliseconds is the assumed duration unit.", + "defaultValue": 30000 + }, + { + "name": "otel.bsp.max.export.batch.size", + "type": "java.lang.Integer", + "description": "The maximum OTLP span batch size.", + "defaultValue": 512 + }, + { + "name": "otel.bsp.max.queue.size", + "type": "java.lang.Integer", + "description": "The maximum OTLP span batch queue size.", + "defaultValue": 2048 + }, { "name": "otel.experimental.exporter.otlp.retry.enabled", "type": "java.lang.Boolean", "description": "Enable experimental retry support. See https://github.com/open-telemetry/opentelemetry-java/blob/main/sdk-extensions/autoconfigure/README.md#otlp-exporter-retry.", "defaultValue": false }, + { + "name": "otel.experimental.metrics.cardinality.limit", + "type": "java.lang.Integer", + "description": "If set, configure experimental cardinality limit. The value dictates the maximum number of distinct points per metric.", + "defaultValue": 2000 + }, + { + "name": "otel.experimental.resource.disabled.keys", + "type": "java.util.List", + "description": "Filter out resource entries with these keys." + }, { "name": "otel.exporter.otlp.certificate", "type": "java.lang.String", @@ -280,6 +350,16 @@ "description": "Enable the Servlet instrumentation.", "defaultValue": true }, + { + "name": "otel.java.enabled.resource.providers", + "type": "java.util.List", + "description": "Enables one or more ResourceProvider types. If unset, all resource providers are enabled. Each entry is the fully qualified classname of a ResourceProvider." + }, + { + "name": "otel.java.disabled.resource.providers", + "type": "java.util.List", + "description": " Disables one or more ResourceProvider types. Each entry is the fully qualified classname of a ResourceProvider." + }, { "name": "otel.logs.exporter", "type": "java.util.List", @@ -292,6 +372,12 @@ "description": "The interval, in milliseconds, between the start of two export attempts.
Durations can be of the form {number}{unit}, where unit is one of:

  • ms
  • s
  • m
  • h
  • d

If no unit is specified, milliseconds is the assumed duration unit.", "defaultValue": "60000" }, + { + "name": "otel.metrics.exemplar.filter", + "type": "java.lang.String", + "description": "The filter for exemplar sampling.", + "defaultValue": "TRACE_BASED" + }, { "name": "otel.metrics.exporter", "type": "java.util.List", @@ -316,10 +402,32 @@ "defaultValue": false }, { - "name": "otel.springboot.resource.enabled", - "type": "java.lang.Boolean", - "description": "Enable the resource auto-configuration.", - "defaultValue": true + "name": "otel.service.name", + "type": "java.lang.String", + "description": "Specify logical service name. Takes precedence over service.name defined with otel.resource.attributes." + }, + { + "name": "otel.span.attribute.value.length.limit", + "type": "java.lang.Integer", + "description": "The maximum length of span attribute values. Takes precedence over otel.attribute.value.length.limit. By default, there is no limit." + }, + { + "name": "otel.span.attribute.count.limit", + "type": "java.lang.Integer", + "description": "The maximum number of attributes per span. Takes precedence over otel.attribute.count.limit.", + "defaultValue": 128 + }, + { + "name": "otel.span.event.count.limit", + "type": "java.lang.Integer", + "description": "The maximum number of events per span.", + "defaultValue": 128 + }, + { + "name": "otel.span.link.count.limit", + "type": "java.lang.Integer", + "description": "The maximum number of links per span.", + "defaultValue": 128 }, { "name": "otel.traces.exporter", @@ -328,9 +436,15 @@ "defaultValue": "otlp" }, { - "name": "otel.traces.sampler.probability", + "name": "otel.traces.sampler", + "type": "java.lang.String", + "description": "The sampler to use for tracing.", + "defaultValue": "parentbased_always_on" + }, + { + "name": "otel.traces.sampler.arg", "type": "java.lang.Double", - "description": "The probability of sampling.
The value should be within [0.0, 1.0]. 1.0 means keep everything, 0.0 means drop all spans.", + "description": "An argument to the configured tracer if supported, for example a ratio.", "defaultValue": 1.0 } ], @@ -424,6 +538,23 @@ } ] }, + { + "name": "otel.metrics.exemplar.filter", + "values": [ + { + "value": "ALWAYS_ON", + "description": "Take all exemplars." + }, + { + "value": "ALWAYS_OFF", + "description": "Drop all exemplars." + }, + { + "value": "TRACE_BASED", + "description": "Choose exemplars that correspond to a sampled span." + } + ] + }, { "name": "otel.metrics.exporter", "values": [ @@ -494,6 +625,35 @@ "description": "Zipkin exporter." } ] + }, + { + "name": "otel.traces.sampler", + "values": [ + { + "value": "always_on", + "description": "Keep all spans." + }, + { + "value": "always_off", + "description": "Drop all spans." + }, + { + "value": "traceidratio", + "description": "Keep a ratio of otel.traces.sampler.arg of all spans." + }, + { + "value": "parentbased_always_on", + "description": "Keep all spans where the parent is also kept. If there is no parent, keep all spans." + }, + { + "value": "parentbased_always_off", + "description": "Keep all spans where the parent is also kept. If there is no parent, drop all spans." + }, + { + "value": "parentbased_traceidratio", + "description": "Keep all spans where the parent is also kept. If there is no parent, keep a ratio of otel.traces.sampler.arg of all spans." + } + ] } ] } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 0d6e9b094c9e..1119252c3dae 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -1,11 +1,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration,\ -io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingMetricExporterAutoConfiguration,\ -io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingSpanExporterAutoConfiguration,\ -io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpLogRecordExporterAutoConfiguration,\ -io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpMetricExporterAutoConfiguration,\ -io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpSpanExporterAutoConfiguration,\ -io.opentelemetry.instrumentation.spring.autoconfigure.exporters.zipkin.ZipkinSpanExporterAutoConfiguration,\ io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.annotations.InstrumentationAnnotationsAutoConfiguration,\ io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.kafka.KafkaInstrumentationAutoConfiguration,\ io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.logging.OpenTelemetryAppenderAutoConfiguration,\ @@ -13,9 +7,7 @@ io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.jdbc.OpenT io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.micrometer.MicrometerBridgeAutoConfiguration,\ io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.web.SpringWebInstrumentationAutoConfiguration,\ io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.webflux.SpringWebfluxInstrumentationAutoConfiguration,\ -io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.webmvc.SpringWebMvc5InstrumentationAutoConfiguration,\ -io.opentelemetry.instrumentation.spring.autoconfigure.propagators.PropagationAutoConfiguration,\ -io.opentelemetry.instrumentation.spring.autoconfigure.resources.OtelResourceAutoConfiguration +io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.webmvc.SpringWebMvc5InstrumentationAutoConfiguration org.springframework.context.ApplicationListener=\ io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.logging.LogbackAppenderApplicationListener diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 0642d53bce54..cbfda6912187 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,10 +1,4 @@ io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration -io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingMetricExporterAutoConfiguration -io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingSpanExporterAutoConfiguration -io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpLogRecordExporterAutoConfiguration -io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpMetricExporterAutoConfiguration -io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpSpanExporterAutoConfiguration -io.opentelemetry.instrumentation.spring.autoconfigure.exporters.zipkin.ZipkinSpanExporterAutoConfiguration io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.annotations.InstrumentationAnnotationsAutoConfiguration io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.kafka.KafkaInstrumentationAutoConfiguration io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.logging.OpenTelemetryAppenderAutoConfiguration @@ -13,5 +7,3 @@ io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.micrometer io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.web.SpringWebInstrumentationAutoConfiguration io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.webflux.SpringWebfluxInstrumentationAutoConfiguration io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.webmvc.SpringWebMvc6InstrumentationAutoConfiguration -io.opentelemetry.instrumentation.spring.autoconfigure.propagators.PropagationAutoConfiguration -io.opentelemetry.instrumentation.spring.autoconfigure.resources.OtelResourceAutoConfiguration 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 90a750292c03..f27fe499c530 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 @@ -6,17 +6,17 @@ package io.opentelemetry.instrumentation.spring.autoconfigure; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.withSettings; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.instrumentation.spring.autoconfigure.resources.OtelResourceAutoConfiguration; +import io.opentelemetry.exporter.otlp.internal.OtlpSpanExporterProvider; import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import io.opentelemetry.sdk.metrics.SdkMeterProvider; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener; +import io.opentelemetry.sdk.trace.export.SpanExporter; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import org.mockito.Mockito; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -32,7 +32,10 @@ public OpenTelemetry customOpenTelemetry() { } } - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); + private final ApplicationContextRunner contextRunner = + new ApplicationContextRunner() + .withPropertyValues( + "otel.traces.exporter=none", "otel.metrics.exporter=none", "otel.logs.exporter=none"); @Test @DisplayName( @@ -45,10 +48,7 @@ void customOpenTelemetry() { context -> assertThat(context) .hasBean("customOpenTelemetry") - .doesNotHaveBean("openTelemetry") - .doesNotHaveBean("sdkTracerProvider") - .doesNotHaveBean("sdkMeterProvider") - .doesNotHaveBean("sdkLoggerProvider")); + .doesNotHaveBean("openTelemetry")); } @Test @@ -57,69 +57,32 @@ void customOpenTelemetry() { void initializeProvidersAndOpenTelemetry() { this.contextRunner .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)) - .run( - context -> - assertThat(context) - .hasBean("openTelemetry") - .hasBean("sdkTracerProvider") - .hasBean("sdkMeterProvider") - .hasBean("sdkLoggerProvider")); + .run(context -> assertThat(context).hasBean("openTelemetry")); } @Test @DisplayName( - "when Application Context DOES NOT contain OpenTelemetry bean but TracerProvider should initialize openTelemetry") + "when Application Context DOES NOT contain OpenTelemetry bean but SpanExporter should initialize openTelemetry") void initializeOpenTelemetryWithCustomProviders() { + OtlpSpanExporterProvider spanExporterProvider = + Mockito.mock( + OtlpSpanExporterProvider.class, + withSettings().extraInterfaces(AutoConfigureListener.class)); + Mockito.when(spanExporterProvider.getName()).thenReturn("custom"); + Mockito.when(spanExporterProvider.createExporter(any())) + .thenReturn(Mockito.mock(SpanExporter.class)); + this.contextRunner .withBean( - "customTracerProvider", - SdkTracerProvider.class, - () -> SdkTracerProvider.builder().build(), - bd -> bd.setDestroyMethodName("")) - .withBean( - "customMeterProvider", - SdkMeterProvider.class, - () -> SdkMeterProvider.builder().build(), - bd -> bd.setDestroyMethodName("")) - .withBean( - "customLoggerProvider", - SdkLoggerProvider.class, - () -> SdkLoggerProvider.builder().build(), + "customSpanExporter", + OtlpSpanExporterProvider.class, + () -> spanExporterProvider, bd -> bd.setDestroyMethodName("")) .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)) - .run( - context -> - assertThat(context) - .hasBean("openTelemetry") - .hasBean("customTracerProvider") - .doesNotHaveBean("sdkTracerProvider") - .hasBean("customMeterProvider") - .doesNotHaveBean("sdkMeterProvider") - .hasBean("customLoggerProvider") - .doesNotHaveBean("sdkLoggerProvider")); - } - - @Test - @DisplayName("when otel attributes are set in properties they should be put in resource") - void shouldInitializeAttributes() { - this.contextRunner - .withConfiguration( - AutoConfigurations.of( - OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)) - .withPropertyValues( - "otel.resource.attributes.xyz=foo", - "otel.resource.attributes.environment=dev", - "otel.resource.attributes.service.instance.id=id-example") - .run( - context -> { - Resource otelResource = context.getBean("otelResource", Resource.class); + .withPropertyValues("otel.traces.exporter=custom") + .run(context -> assertThat(context).hasBean("openTelemetry")); - assertThat(otelResource.getAttribute(AttributeKey.stringKey("environment"))) - .isEqualTo("dev"); - assertThat(otelResource.getAttribute(AttributeKey.stringKey("xyz"))).isEqualTo("foo"); - assertThat(otelResource.getAttribute(AttributeKey.stringKey("service.instance.id"))) - .isEqualTo("id-example"); - }); + Mockito.verify(spanExporterProvider).afterAutoConfigure(any()); } @Test @@ -130,10 +93,7 @@ void shouldInitializeSdkWhenNotDisabled() { .run( context -> { assertThat(context).getBean("openTelemetry").isInstanceOf(OpenTelemetrySdk.class); - assertThat(context) - .hasBean("openTelemetry") - .hasBean("sdkTracerProvider") - .hasBean("sdkMeterProvider"); + assertThat(context).hasBean("openTelemetry"); }); } @@ -143,11 +103,7 @@ void shouldInitializeNoopOpenTelemetryWhenSdkIsDisabled() { .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)) .withPropertyValues("otel.sdk.disabled=true") .run( - context -> { - assertThat(context).getBean("openTelemetry").isEqualTo(OpenTelemetry.noop()); - assertThat(context) - .doesNotHaveBean("sdkTracerProvider") - .doesNotHaveBean("sdkMeterProvider"); - }); + context -> + assertThat(context).getBean("openTelemetry").isEqualTo(OpenTelemetry.noop())); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/MetricExporterAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/MetricExporterAutoConfigurationTest.java deleted file mode 100644 index dba88212ef97..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/MetricExporterAutoConfigurationTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.exporter.logging.LoggingMetricExporter; -import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingMetricExporterAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpMetricExporterAutoConfiguration; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -class MetricExporterAutoConfigurationTest { - - private final ApplicationContextRunner contextRunner = - new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - OpenTelemetryAutoConfiguration.class, - OtlpMetricExporterAutoConfiguration.class, - LoggingMetricExporterAutoConfiguration.class)); - - @Test - void defaultConfiguration() { - contextRunner.run( - context -> { - assertThat(context.getBean("otelOtlpMetricExporter", OtlpHttpMetricExporter.class)) - .as("OTLP exporter is enabled by default") - .isNotNull(); - assertThat(context.containsBean("otelLoggingMetricExporter")) - .as("Logging exporter is not created unless explicitly configured") - .isFalse(); - }); - } - - @Test - void loggingEnabledByConfiguration() { - contextRunner - .withPropertyValues("otel.metrics.exporter=logging,otlp") - .run( - context -> { - assertThat(context.getBean("otelOtlpMetricExporter", OtlpHttpMetricExporter.class)) - .as("OTLP exporter is present even with logging enabled") - .isNotNull(); - assertThat(context.getBean("otelLoggingMetricExporter", LoggingMetricExporter.class)) - .as("Logging exporter is explicitly enabled") - .isNotNull(); - }); - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/SpanExporterAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/SpanExporterAutoConfigurationTest.java deleted file mode 100644 index 2cfd63d80a51..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/SpanExporterAutoConfigurationTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.exporter.logging.LoggingSpanExporter; -import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging.LoggingSpanExporterAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpSpanExporterAutoConfiguration; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -class SpanExporterAutoConfigurationTest { - - private final ApplicationContextRunner contextRunner = - new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - OpenTelemetryAutoConfiguration.class, - OtlpSpanExporterAutoConfiguration.class, - LoggingSpanExporterAutoConfiguration.class)); - - @Test - void defaultConfiguration() { - contextRunner.run( - context -> { - assertThat(context.getBean("otelOtlpSpanExporter", OtlpHttpSpanExporter.class)) - .as("OTLP exporter is enabled by default") - .isNotNull(); - assertThat(context.containsBean("otelLoggingSpanExporter")) - .as("Logging exporter is not created unless explicitly configured") - .isFalse(); - }); - } - - @Test - void loggingEnabledByConfiguration() { - contextRunner - .withPropertyValues("otel.traces.exporter=logging,otlp") - .run( - context -> { - assertThat(context.getBean("otelOtlpSpanExporter", OtlpHttpSpanExporter.class)) - .as("OTLP exporter is present even with logging enabled") - .isNotNull(); - assertThat(context.getBean("otelLoggingSpanExporter", LoggingSpanExporter.class)) - .as("Logging exporter is explicitly enabled") - .isNotNull(); - }); - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/LoggingMetricExporterAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/LoggingMetricExporterAutoConfigurationTest.java deleted file mode 100644 index 25849a6be309..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/LoggingMetricExporterAutoConfigurationTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.exporter.logging.LoggingMetricExporter; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -class LoggingMetricExporterAutoConfigurationTest { - - private final ApplicationContextRunner runner = - new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - OpenTelemetryAutoConfiguration.class, - LoggingMetricExporterAutoConfiguration.class)); - - @Test - void enabled() { - runner - .withPropertyValues("otel.metrics.exporter=logging") - .run( - context -> - assertThat( - context.getBean("otelLoggingMetricExporter", LoggingMetricExporter.class)) - .isNotNull()); - } - - @Test - void disabled() { - runner - .withPropertyValues("otel.metrics.exporter=none") - .run(context -> assertThat(context.containsBean("otelOtlpMetricExporter")).isFalse()); - } - - @Test - void noProperties() { - runner.run(context -> assertThat(context.containsBean("otelLoggingMetricExporter")).isFalse()); - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/LoggingSpanExporterAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/LoggingSpanExporterAutoConfigurationTest.java deleted file mode 100644 index e4a69116b870..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/LoggingSpanExporterAutoConfigurationTest.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.exporter.logging.LoggingSpanExporter; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -/** Spring Boot auto configuration test for {@link LoggingSpanExporter}. */ -class LoggingSpanExporterAutoConfigurationTest { - - private final ApplicationContextRunner runner = - new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - OpenTelemetryAutoConfiguration.class, - LoggingSpanExporterAutoConfiguration.class)); - - @Test - void enabled() { - runner - .withPropertyValues("otel.traces.exporter=logging") - .run( - context -> - assertThat(context.getBean("otelLoggingSpanExporter", LoggingSpanExporter.class)) - .isNotNull()); - } - - @Test - void disabled() { - runner - .withPropertyValues("otel.traces.exporter=none") - .run(context -> assertThat(context.containsBean("otelOtlpMetricExporter")).isFalse()); - } - - @Test - void noProperties() { - runner.run(context -> assertThat(context.containsBean("otelLoggingSpanExporter")).isFalse()); - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/SystemOutLogRecordExporterAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/SystemOutLogRecordExporterAutoConfigurationTest.java deleted file mode 100644 index d139cef3e762..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/SystemOutLogRecordExporterAutoConfigurationTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.logging; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.exporter.logging.SystemOutLogRecordExporter; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -/** Spring Boot auto configuration test for {@link SystemOutLogRecordExporter}. */ -class SystemOutLogRecordExporterAutoConfigurationTest { - - private final ApplicationContextRunner runner = - new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - OpenTelemetryAutoConfiguration.class, - SystemOutLogRecordExporterAutoConfiguration.class)); - - @Test - void enabled() { - runner - .withPropertyValues("otel.logs.exporter=logging") - .run( - context -> - assertThat( - context.getBean( - "otelSystemOutLogRecordExporter", SystemOutLogRecordExporter.class)) - .isNotNull()); - } - - @Test - void disabled() { - runner - .withPropertyValues("otel.logs.exporter=none") - .run(context -> assertThat(context.containsBean("otelOtlpMetricExporter")).isFalse()); - } - - @Test - void noProperties() { - runner.run(context -> assertThat(context.containsBean("otelLoggingSpanExporter")).isFalse()); - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpLogExporterAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpLogExporterAutoConfigurationTest.java deleted file mode 100644 index 27b3687379b6..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpLogExporterAutoConfigurationTest.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -class OtlpLogExporterAutoConfigurationTest { - - private final ApplicationContextRunner runner = - new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - OpenTelemetryAutoConfiguration.class, - OtlpLogRecordExporterAutoConfiguration.class)); - - @Test - void otlpDisabled() { - runner - .withPropertyValues("otel.logs.exporter=none") - .run(context -> assertThat(context.containsBean("otelOtlpLogRecordExporter")).isFalse()); - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpMetricExporterAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpMetricExporterAutoConfigurationTest.java deleted file mode 100644 index 822026f3550d..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpMetricExporterAutoConfigurationTest.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -class OtlpMetricExporterAutoConfigurationTest { - - private final ApplicationContextRunner runner = - new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - OpenTelemetryAutoConfiguration.class, OtlpMetricExporterAutoConfiguration.class)); - - @Test - void otlpDisabled() { - runner - .withPropertyValues("otel.metrics.exporter=none") - .run(context -> assertThat(context.containsBean("otelOtlpMetricExporter")).isFalse()); - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpSpanExporterAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpSpanExporterAutoConfigurationTest.java deleted file mode 100644 index 63a2cc2af347..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpSpanExporterAutoConfigurationTest.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -/** Spring Boot auto configuration test for {@link OtlpSpanExporterAutoConfiguration}. */ -class OtlpSpanExporterAutoConfigurationTest { - - private final ApplicationContextRunner contextRunner = - new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - OpenTelemetryAutoConfiguration.class, OtlpSpanExporterAutoConfiguration.class)); - - @Test - void otlpDisabled() { - contextRunner - .withPropertyValues("otel.traces.exporter=none") - .run(context -> assertThat(context.containsBean("otelOtlpSpanExporter")).isFalse()); - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/zipkin/ZipkinSpanExporterAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/zipkin/ZipkinSpanExporterAutoConfigurationTest.java deleted file mode 100644 index eec9ebad4a0f..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/zipkin/ZipkinSpanExporterAutoConfigurationTest.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.zipkin; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -/** Spring Boot auto configuration test for {@link ZipkinSpanExporter}. */ -class ZipkinSpanExporterAutoConfigurationTest { - - private final ApplicationContextRunner contextRunner = - new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - OpenTelemetryAutoConfiguration.class, ZipkinSpanExporterAutoConfiguration.class)); - - @Test - @DisplayName("when exporters are ENABLED should initialize ZipkinSpanExporter bean") - void exportersEnabled() { - this.contextRunner - .withPropertyValues("otel.traces.exporter=zipkin") - .run( - context -> - assertThat(context.getBean("otelZipkinSpanExporter", ZipkinSpanExporter.class)) - .isNotNull()); - } - - @Test - @DisplayName( - "when otel.exporter.zipkin properties are set should initialize ZipkinSpanExporterProperties with property values") - void handlesProperties() { - this.contextRunner - .withPropertyValues( - "otel.traces.exporter=zipkin", - "otel.exporter.zipkin.endpoint=http://localhost:8080/test") - .run( - context -> { - ZipkinSpanExporterProperties zipkinSpanExporterProperties = - context.getBean(ZipkinSpanExporterProperties.class); - assertThat(zipkinSpanExporterProperties.getEndpoint()) - .isEqualTo("http://localhost:8080/test"); - }); - } - - @Test - @DisplayName("when exporters are DISABLED should NOT initialize ZipkinSpanExporter bean") - void disabledProperty() { - this.contextRunner - .withPropertyValues("otel.traces.exporter=none") - .run(context -> assertThat(context.containsBean("otelZipkinSpanExporter")).isFalse()); - } - - @Test - @DisplayName("when zipkin enabled property is MISSING should initialize ZipkinSpanExporter bean") - void noProperty() { - this.contextRunner.run( - context -> - assertThat(context.getBean("otelZipkinSpanExporter", ZipkinSpanExporter.class)) - .isNotNull()); - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/propagators/PropagationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/propagators/PropagationAutoConfigurationTest.java deleted file mode 100644 index 93a01df65cc4..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/propagators/PropagationAutoConfigurationTest.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.propagators; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.context.propagation.TextMapPropagator; -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -class PropagationAutoConfigurationTest { - - private final ApplicationContextRunner contextRunner = - new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - OpenTelemetryAutoConfiguration.class, PropagationAutoConfiguration.class)); - - @Test - @DisplayName("when propagation is ENABLED should initialize PropagationAutoConfiguration bean") - void shouldBeConfigured() { - - this.contextRunner - .withPropertyValues("otel.propagation.enabled=true") - .run(context -> assertThat(context.containsBean("propagationAutoConfiguration")).isTrue()); - } - - @Test - @DisplayName( - "when propagation is DISABLED should NOT initialize PropagationAutoConfiguration bean") - void shouldNotBeConfigured() { - - this.contextRunner - .withPropertyValues("otel.propagation.enabled=false") - .run(context -> assertThat(context.containsBean("propagationAutoConfiguration")).isFalse()); - } - - @Test - @DisplayName( - "when propagation enabled property is MISSING should initialize PropagationAutoConfiguration bean") - void noProperty() { - this.contextRunner.run( - context -> assertThat(context.containsBean("propagationAutoConfiguration")).isTrue()); - } - - @Test - @DisplayName("when no propagators are defined should contain default propagators") - void shouldContainDefaults() { - - this.contextRunner.run( - context -> - assertThat( - context.getBean("compositeTextMapPropagator", TextMapPropagator.class).fields()) - .contains("traceparent", "baggage")); - } - - @Test - @DisplayName("when propagation is set to b3 should contain only b3 propagator") - void shouldContainB3() { - this.contextRunner - .withPropertyValues("otel.propagators=b3") - .run( - context -> { - TextMapPropagator compositePropagator = - context.getBean("compositeTextMapPropagator", TextMapPropagator.class); - - assertThat(compositePropagator.fields()) - .contains("b3") - .doesNotContain("baggage", "traceparent"); - }); - } - - @Test - @DisplayName("when propagation is set to unsupported value should create an empty propagator") - void shouldCreateNoop() { - - this.contextRunner - .withPropertyValues("otel.propagators=invalid") - .run( - context -> { - TextMapPropagator compositePropagator = - context.getBean("compositeTextMapPropagator", TextMapPropagator.class); - - assertThat(compositePropagator.fields()).isEmpty(); - }); - } - - @Test - @DisplayName("when propagation is set to some values should contain only supported values - List") - void shouldContainOnlySupportedList() { - this.contextRunner - .withPropertyValues("otel.propagators=invalid,b3") - .run( - context -> { - TextMapPropagator compositePropagator = - context.getBean("compositeTextMapPropagator", TextMapPropagator.class); - - assertThat(compositePropagator.fields()).containsExactly("b3"); - }); - } - - @Test - @DisplayName("when propagation is set to some values should contain only supported values") - void shouldContainOnlySupported() { - this.contextRunner - .withPropertyValues("otel.propagators=invalid,b3") - .run( - context -> { - TextMapPropagator compositePropagator = - context.getBean("compositeTextMapPropagator", TextMapPropagator.class); - - assertThat(compositePropagator.fields()).containsExactly("b3"); - }); - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpExporterPropertiesTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/OtlpExporterPropertiesTest.java similarity index 83% rename from instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpExporterPropertiesTest.java rename to instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/OtlpExporterPropertiesTest.java index 980e69ad768c..1df883e0c0a1 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/otlp/OtlpExporterPropertiesTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/properties/OtlpExporterPropertiesTest.java @@ -3,18 +3,16 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp; +package io.opentelemetry.instrumentation.spring.autoconfigure.properties; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.propagators.PropagationProperties; -import io.opentelemetry.instrumentation.spring.autoconfigure.resources.OtelResourceAutoConfiguration; -import io.opentelemetry.instrumentation.spring.autoconfigure.resources.OtelResourceProperties; -import io.opentelemetry.instrumentation.spring.autoconfigure.resources.SpringConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import java.util.Arrays; +import java.util.Collections; import java.util.stream.Stream; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -38,9 +36,9 @@ class OtlpExporterPropertiesTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - OpenTelemetryAutoConfiguration.class, OtelResourceAutoConfiguration.class)); + .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)) + .withPropertyValues( + "otel.traces.exporter=none", "otel.metrics.exporter=none", "otel.logs.exporter=none"); public static Stream headerKeys() { return Arrays.stream(HEADER_KEYS).map(Arguments::of); @@ -94,6 +92,7 @@ private static ConfigProperties getConfig(AssertableApplicationContext context) new SpelExpressionParser(), context.getBean(OtlpExporterProperties.class), new OtelResourceProperties(), - new PropagationProperties()); + new PropagationProperties(), + DefaultConfigProperties.createFromMap(Collections.emptyMap())); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/DistroVersionResourceProviderTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/DistroVersionResourceProviderTest.java index 011502ff9614..1454354fdbcf 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/DistroVersionResourceProviderTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/DistroVersionResourceProviderTest.java @@ -9,6 +9,7 @@ import com.google.common.collect.ImmutableMap; import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import org.junit.jupiter.api.DisplayName; @@ -19,7 +20,9 @@ public class DistroVersionResourceProviderTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(OtelResourceAutoConfiguration.class)); + .withPropertyValues( + "otel.traces.exporter=none", "otel.metrics.exporter=none", "otel.logs.exporter=none") + .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)); @Test @DisplayName("distro version should be set") diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/OtelResourceAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/OtelResourceAutoConfigurationTest.java deleted file mode 100644 index 297d7dac5530..000000000000 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/OtelResourceAutoConfigurationTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.spring.autoconfigure.resources; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; - -public class OtelResourceAutoConfigurationTest { - private final ApplicationContextRunner contextRunner = - new ApplicationContextRunner() - .withConfiguration( - AutoConfigurations.of( - OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)); - - @Test - @DisplayName( - "when otel.springboot.resource.enabled is set to true configuration should be initialized") - void shouldDetermineServiceNameByOtelServiceName() { - this.contextRunner - .withPropertyValues("otel.springboot.resource.enabled=true") - .run(context -> assertThat(context.containsBean("otelSpringResourceProvider")).isTrue()); - } - - @Test - @DisplayName( - "when otel.springboot.resource.enabled is not specified configuration should be initialized") - void shouldInitAutoConfigurationByDefault() { - this.contextRunner.run( - context -> assertThat(context.containsBean("otelSpringResourceProvider")).isTrue()); - } - - @Test - @DisplayName( - "when otel.springboot.resource.enabled is set to false configuration should NOT be initialized") - void shouldNotInitAutoConfiguration() { - this.contextRunner - .withPropertyValues("otel.springboot.resource.enabled=false") - .run(context -> assertThat(context.containsBean("otelSpringResourceProvider")).isFalse()); - } -} diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringConfigPropertiesTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringConfigPropertiesTest.java index 598dd94fa5e0..76cbe9c76c63 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringConfigPropertiesTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringConfigPropertiesTest.java @@ -8,8 +8,13 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; -import io.opentelemetry.instrumentation.spring.autoconfigure.exporters.otlp.OtlpExporterProperties; -import io.opentelemetry.instrumentation.spring.autoconfigure.propagators.PropagationProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.OtelResourceProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.OtlpExporterProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.PropagationProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.SpringConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import java.util.HashMap; +import java.util.Map; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -28,19 +33,26 @@ void shouldInitializeAttributesByMapInArow() { .run( context -> { Environment env = context.getBean("environment", Environment.class); + Map fallback = new HashMap<>(); + fallback.put("fallback", "fallbackVal"); + fallback.put("otel.springboot.test.map", "hidden"); + SpringConfigProperties config = new SpringConfigProperties( env, new SpelExpressionParser(), new OtlpExporterProperties(), new OtelResourceProperties(), - new PropagationProperties()); + new PropagationProperties(), + DefaultConfigProperties.createFromMap(fallback)); assertThat(config.getMap("otel.springboot.test.map")) .contains( entry("environment", "dev"), entry("xyz", "foo"), entry("service.instance.id", "id-example")); + + assertThat(config.getString("fallback")).isEqualTo("fallbackVal"); }); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProviderTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProviderTest.java index cfe3da4d171e..ed5aad0bbe90 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProviderTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProviderTest.java @@ -7,58 +7,33 @@ import static io.opentelemetry.semconv.ResourceAttributes.SERVICE_NAME; import static io.opentelemetry.semconv.ResourceAttributes.SERVICE_VERSION; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.entry; -import com.google.common.collect.ImmutableMap; -import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; -import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.OtelResourceProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.OtlpExporterProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.PropagationProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.SpringConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.assertj.AttributesAssert; +import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions; +import java.util.Collections; import java.util.Properties; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.info.BuildProperties; +import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.core.env.Environment; public class SpringResourceProviderTest { + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withPropertyValues("otel.springboot.resource.enabled=true") - .withConfiguration( - AutoConfigurations.of( - OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)); - - @Test - @DisplayName("when attributes are SET should set OtelResourceProperties with given attributes") - void hasAttributes() { - - this.contextRunner.run( - context -> { - ResourceProvider resource = - context.getBean("otelSpringResourceProvider", ResourceProvider.class); - - assertThat( - resource - .createResource( - DefaultConfigProperties.createFromMap( - ImmutableMap.of("spring.application.name", "backend"))) - .getAttributes() - .asMap()) - .contains(entry(AttributeKey.stringKey("service.name"), "backend")); - }); - } - - @Test - @DisplayName("when attributes are DEFAULT should set OtelResourceProperties to default values") - void hasDefaultTypes() { - - this.contextRunner.run( - context -> - assertThat(context.getBean(OtelResourceProperties.class).getAttributes()).isEmpty()); - } + .withPropertyValues( + "otel.traces.exporter=none", "otel.metrics.exporter=none", "otel.logs.exporter=none") + .withConfiguration(AutoConfigurations.of(OpenTelemetryAutoConfiguration.class)); @Test @DisplayName( @@ -66,15 +41,9 @@ void hasDefaultTypes() { void shouldDetermineServiceNameBySpringApplicationName() { this.contextRunner .withPropertyValues("spring.application.name=myapp-backend") - .withConfiguration( - AutoConfigurations.of( - OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)) .run( - context -> { - Resource otelResource = context.getBean("otelResource", Resource.class); - - assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("myapp-backend"); - }); + context -> + assertResourceAttributes(context).containsEntry(SERVICE_NAME, "myapp-backend")); } @Test @@ -86,47 +55,26 @@ void shouldDetermineServiceNameAndVersionBySpringApplicationVersion() { properties.put("version", "0.3"); this.contextRunner .withBean("buildProperties", BuildProperties.class, () -> new BuildProperties(properties)) - .withConfiguration( - AutoConfigurations.of( - OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)) .run( - context -> { - Resource otelResource = context.getBean("otelResource", Resource.class); - - assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("demo"); - assertThat(otelResource.getAttribute(SERVICE_VERSION)).isEqualTo("0.3"); - }); + context -> + assertResourceAttributes(context) + .containsEntry(SERVICE_NAME, "demo") + .containsEntry(SERVICE_VERSION, "0.3")); } - @Test - @DisplayName( - "when spring application name and otel service name are not set service name should be default") - void hasDefaultServiceName() { - this.contextRunner - .withConfiguration( - AutoConfigurations.of( - OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)) - .run( - context -> { - Resource otelResource = context.getBean("otelResource", Resource.class); - - assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("unknown_service:java"); - }); - } - - @Test - @DisplayName("when otel service name is set it should be set as service name attribute") - void shouldDetermineServiceNameByOtelServiceName() { - this.contextRunner - .withConfiguration( - AutoConfigurations.of( - OtelResourceAutoConfiguration.class, OpenTelemetryAutoConfiguration.class)) - .withPropertyValues("otel.resource.attributes.service.name=otel-name-backend") - .run( - context -> { - Resource otelResource = context.getBean("otelResource", Resource.class); - - assertThat(otelResource.getAttribute(SERVICE_NAME)).isEqualTo("otel-name-backend"); - }); + private static AttributesAssert assertResourceAttributes(AssertableApplicationContext context) { + ConfigProperties configProperties = + SpringConfigProperties.create( + context.getBean(Environment.class), + new OtlpExporterProperties(), + new OtelResourceProperties(), + new PropagationProperties(), + DefaultConfigProperties.createFromMap(Collections.emptyMap())); + + return OpenTelemetryAssertions.assertThat( + context + .getBean(SpringResourceProvider.class) + .createResource(configProperties) + .getAttributes()); } } diff --git a/smoke-tests-otel-starter/build.gradle.kts b/smoke-tests-otel-starter/build.gradle.kts index acedced8b511..35459869ee8b 100644 --- a/smoke-tests-otel-starter/build.gradle.kts +++ b/smoke-tests-otel-starter/build.gradle.kts @@ -16,6 +16,7 @@ dependencies { implementation("com.h2database:h2") implementation("org.apache.commons:commons-dbcp2") implementation(project(":instrumentation:jdbc:library")) + implementation("io.opentelemetry:opentelemetry-extension-trace-propagators") implementation(project(":instrumentation:spring:starters:spring-boot-starter")) implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES)) diff --git a/smoke-tests-otel-starter/src/main/resources/application.yaml b/smoke-tests-otel-starter/src/main/resources/application.yaml index 3404552d2198..3882e12b10b9 100644 --- a/smoke-tests-otel-starter/src/main/resources/application.yaml +++ b/smoke-tests-otel-starter/src/main/resources/application.yaml @@ -5,3 +5,6 @@ otel: capture-code-attributes: true propagators: - b3 + resource: + attributes: + attributeFromYaml: true # boolean will be automatically converted to string by spring diff --git a/smoke-tests-otel-starter/src/test/java/io/opentelemetry/smoketest/OtelSpringStarterSmokeTest.java b/smoke-tests-otel-starter/src/test/java/io/opentelemetry/smoketest/OtelSpringStarterSmokeTest.java index 5d658736514a..e322746ccad9 100644 --- a/smoke-tests-otel-starter/src/test/java/io/opentelemetry/smoketest/OtelSpringStarterSmokeTest.java +++ b/smoke-tests-otel-starter/src/test/java/io/opentelemetry/smoketest/OtelSpringStarterSmokeTest.java @@ -7,13 +7,25 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.OtelResourceProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.OtlpExporterProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.PropagationProperties; +import io.opentelemetry.instrumentation.spring.autoconfigure.properties.SpringConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider; +import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider; +import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.MetricData; import io.opentelemetry.sdk.metrics.export.MetricExporter; +import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.testing.assertj.TracesAssert; import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricExporter; @@ -23,6 +35,7 @@ import io.opentelemetry.semconv.SemanticAttributes; import io.opentelemetry.spring.smoketest.OtelSpringStarterSmokeTestApplication; import io.opentelemetry.spring.smoketest.OtelSpringStarterSmokeTestController; +import java.util.Collections; import java.util.List; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -30,6 +43,8 @@ import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.core.env.Environment; @SpringBootTest( classes = { @@ -43,6 +58,9 @@ "otel.logs.exporter=none", "otel.metric.export.interval=100", "otel.exporter.otlp.headers=a=1,b=2", + "otel.traces.exporter=memory", + "otel.metrics.exporter=memory", + "otel.logs.exporter=memory" // We set the export interval of the metrics to 100 ms. The default value is 1 minute. // the headers are simply set here to make sure that headers can be parsed }) @@ -56,28 +74,93 @@ class OtelSpringStarterSmokeTest { @Autowired private TestRestTemplate testRestTemplate; - @Autowired private ConfigProperties configProperties; + @Autowired private Environment environment; + @Autowired private PropagationProperties propagationProperties; + @Autowired private OtelResourceProperties otelResourceProperties; + @Autowired private OtlpExporterProperties otlpExporterProperties; @Configuration(proxyBeanMethods = false) static class TestConfiguration { + + @Bean + ConfigurableMetricExporterProvider otlpMetricExporterProvider() { + return new ConfigurableMetricExporterProvider() { + @Override + public MetricExporter createExporter(ConfigProperties configProperties) { + return METRIC_EXPORTER; + } + + @Override + public String getName() { + return "memory"; + } + }; + } + + @Bean + ConfigurableSpanExporterProvider otlpSpanExporterProvider() { + return new ConfigurableSpanExporterProvider() { + @Override + public SpanExporter createExporter(ConfigProperties configProperties) { + return SPAN_EXPORTER; + } + + @Override + public String getName() { + return "memory"; + } + }; + } + @Bean - public MetricExporter metricExporter() { - return METRIC_EXPORTER; + ConfigurableLogRecordExporterProvider otlpLogRecordExporterProvider() { + return new ConfigurableLogRecordExporterProvider() { + @Override + public LogRecordExporter createExporter(ConfigProperties configProperties) { + return LOG_RECORD_EXPORTER; + } + + @Override + public String getName() { + return "memory"; + } + }; } @Bean - public SpanExporter spanExporter() { - return SPAN_EXPORTER; + @Order(1) + AutoConfigurationCustomizerProvider hiddenPropagatorCustomizer() { + return customizer -> + customizer.addResourceCustomizer( + (resource, config) -> + resource.merge( + Resource.create( + Attributes.of( + AttributeKey.booleanKey("keyFromResourceCustomizer"), false)))); } @Bean - public LogRecordExporter logRecordExporter() { - return LOG_RECORD_EXPORTER; + @Order(2) + AutoConfigurationCustomizerProvider propagatorCustomizer() { + return customizer -> + customizer.addResourceCustomizer( + (resource, config) -> + resource.merge( + Resource.create( + Attributes.of( + AttributeKey.booleanKey("keyFromResourceCustomizer"), true)))); } } @Test void propertyConversion() { + ConfigProperties configProperties = + SpringConfigProperties.create( + environment, + otlpExporterProperties, + otelResourceProperties, + propagationProperties, + DefaultConfigProperties.createFromMap(Collections.emptyMap())); assertThat(configProperties.getMap("otel.exporter.otlp.headers")) .containsEntry("a", "1") .containsEntry("b", "2"); @@ -111,6 +194,13 @@ void shouldSendTelemetry() throws InterruptedException { spanDataAssert -> spanDataAssert .hasKind(SpanKind.SERVER) + .hasResourceSatisfying( + r -> + r.hasAttribute( + AttributeKey.booleanKey("keyFromResourceCustomizer"), + true) + .hasAttribute( + AttributeKey.stringKey("attributeFromYaml"), "true")) .hasAttribute(SemanticAttributes.HTTP_REQUEST_METHOD, "GET") .hasAttribute(SemanticAttributes.HTTP_RESPONSE_STATUS_CODE, 200L) .hasAttribute(SemanticAttributes.HTTP_ROUTE, "/ping")));