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 index 0b7829b071d1..968bff6e5347 100644 --- 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 @@ -13,8 +13,10 @@ 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 @@ -31,9 +33,7 @@ public LoggingMetricExporter otelLoggingMetricExporter() { static final class CustomCondition implements Condition { @Override - public boolean matches( - org.springframework.context.annotation.ConditionContext context, - org.springframework.core.type.AnnotatedTypeMetadata metadata) { + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return ExporterConfigEvaluator.isExporterEnabled( context.getEnvironment(), "otel.exporter.logging.enabled", 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 index 09b7234b1a79..a31ee6ce78c9 100644 --- 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 @@ -13,8 +13,10 @@ 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 @@ -31,9 +33,7 @@ public LoggingSpanExporter otelLoggingSpanExporter() { static final class CustomCondition implements Condition { @Override - public boolean matches( - org.springframework.context.annotation.ConditionContext context, - org.springframework.core.type.AnnotatedTypeMetadata metadata) { + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return ExporterConfigEvaluator.isExporterEnabled( context.getEnvironment(), "otel.exporter.logging.enabled", 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 new file mode 100644 index 000000000000..18ad43096076 --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/SystemOutLogRecordExporterAutoConfiguration.java @@ -0,0 +1,46 @@ +/* + * 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 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) +@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.exporter.logging.enabled", + "otel.exporter.logging.logs.enabled", + "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 index 5c65cd13593b..f3a0c1a2695d 100644 --- 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 @@ -17,7 +17,9 @@ 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) @@ -32,9 +34,7 @@ public LogRecordExporter otelOtlpLogRecordExporter(ConfigProperties configProper static final class CustomCondition implements Condition { @Override - public boolean matches( - org.springframework.context.annotation.ConditionContext context, - org.springframework.core.type.AnnotatedTypeMetadata metadata) { + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return ExporterConfigEvaluator.isExporterEnabled( context.getEnvironment(), "otel.exporter.otlp.enabled", 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 index 2ada08d5c387..3abfd071113c 100644 --- 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 @@ -17,8 +17,10 @@ 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) @@ -34,9 +36,7 @@ public MetricExporter otelOtlpMetricExporter(ConfigProperties configProperties) static final class CustomCondition implements Condition { @Override - public boolean matches( - org.springframework.context.annotation.ConditionContext context, - org.springframework.core.type.AnnotatedTypeMetadata metadata) { + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return ExporterConfigEvaluator.isExporterEnabled( context.getEnvironment(), "otel.exporter.otlp.enabled", 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 index ab254433c034..18c5e6f5702c 100644 --- 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 @@ -17,8 +17,10 @@ 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. @@ -39,9 +41,7 @@ public SpanExporter otelOtlpSpanExporter(ConfigProperties configProperties) { static final class CustomCondition implements Condition { @Override - public boolean matches( - org.springframework.context.annotation.ConditionContext context, - org.springframework.core.type.AnnotatedTypeMetadata metadata) { + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return ExporterConfigEvaluator.isExporterEnabled( context.getEnvironment(), "otel.exporter.otlp.enabled", 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 index 2912f7f041b9..7f9355b96e63 100644 --- 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 @@ -15,8 +15,10 @@ 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. @@ -43,9 +45,7 @@ public ZipkinSpanExporter otelZipkinSpanExporter(ZipkinSpanExporterProperties pr static final class CustomCondition implements Condition { @Override - public boolean matches( - org.springframework.context.annotation.ConditionContext context, - org.springframework.core.type.AnnotatedTypeMetadata metadata) { + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return ExporterConfigEvaluator.isExporterEnabled( context.getEnvironment(), null, 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 new file mode 100644 index 000000000000..58082f2f871b --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/exporters/logging/SystemOutLogRecordExporterAutoConfigurationTest.java @@ -0,0 +1,91 @@ +/* + * 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.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 SystemOutLogRecordExporter}. */ +class SystemOutLogRecordExporterAutoConfigurationTest { + + private final ApplicationContextRunner contextRunner = + new ApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of( + OpenTelemetryAutoConfiguration.class, + SystemOutLogRecordExporterAutoConfiguration.class)); + + @Test + void loggingEnabledNew() { + contextRunner + .withPropertyValues("otel.logs.exporter=logging") + .run( + context -> + assertThat( + context.getBean( + "otelSystemOutLogRecordExporter", SystemOutLogRecordExporter.class)) + .isNotNull()); + } + + @Test + @DisplayName("when exporters are ENABLED should initialize SystemOutLogRecordExporter bean") + void loggingEnabled() { + contextRunner + .withPropertyValues("otel.exporter.logging.enabled=true") + .run( + context -> + assertThat( + context.getBean( + "otelSystemOutLogRecordExporter", SystemOutLogRecordExporter.class)) + .isNotNull()); + } + + @Test + void loggingLogsEnabled() { + contextRunner + .withPropertyValues("otel.exporter.logging.logs.enabled=true") + .run( + context -> + assertThat( + context.getBean( + "otelSystemOutLogRecordExporter", SystemOutLogRecordExporter.class)) + .isNotNull()); + } + + @Test + @DisplayName("when exporters are DISABLED should NOT initialize SystemOutLogRecordExporter bean") + void loggingDisabled() { + contextRunner + .withPropertyValues("otel.exporter.logging.enabled=false") + .run( + context -> + assertThat(context.containsBean("otelSystemOutLogRecordExporter")).isFalse()); + } + + @Test + @DisplayName("when exporters are DISABLED should NOT initialize SystemOutLogRecordExporter bean") + void loggingLogsDisabled() { + contextRunner + .withPropertyValues("otel.exporter.logging.logs.enabled=false") + .run( + context -> + assertThat(context.containsBean("otelSystemOutLogRecordExporter")).isFalse()); + } + + @Test + @DisplayName( + "when exporter enabled property is MISSING should initialize SystemOutLogRecordExporter bean") + void exporterPresentByDefault() { + contextRunner.run( + context -> assertThat(context.containsBean("otelSystemOutLogRecordExporter")).isFalse()); + } +}