From 2421f02b85b08e9a91bf9d17618d6fe31e40a56f Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Wed, 5 Nov 2025 14:53:40 +0100 Subject: [PATCH] Extract OpenTelemetryLoggingAutoConfiguration This auto-configuration configures OpenTelemetry logging. The existing OpenTelemetrySdkAutoConfiguration now only configures the OpenTelemetry SDK, but no individual subsystems (logging, metrics, tracing). Closes gh-47963 --- ...rComposeConnectionDetailsFactoryTests.java | 4 +- ...rComposeConnectionDetailsFactoryTests.java | 4 +- ...ontainerConnectionDetailsFactoryTests.java | 6 +- ...ontainerConnectionDetailsFactoryTests.java | 6 +- .../OpenTelemetrySdkAutoConfiguration.java | 31 --- ...OpenTelemetryLoggingAutoConfiguration.java | 68 ++++++ .../SdkLoggerProviderBuilderCustomizer.java | 2 +- .../OtlpLoggingAutoConfiguration.java | 6 +- .../{ => otlp}/OtlpLoggingConfigurations.java | 2 +- .../OtlpLoggingConnectionDetails.java | 2 +- .../{ => otlp}/OtlpLoggingProperties.java | 2 +- .../logging/{ => otlp}/Transport.java | 2 +- .../logging/otlp/package-info.java | 23 ++ .../autoconfigure/logging/package-info.java | 2 +- ...DockerComposeConnectionDetailsFactory.java | 6 +- ...gingContainerConnectionDetailsFactory.java | 4 +- ...gingContainerConnectionDetailsFactory.java | 4 +- ...itional-spring-configuration-metadata.json | 15 +- ...ot.autoconfigure.AutoConfiguration.imports | 3 +- ...penTelemetrySdkAutoConfigurationTests.java | 157 ------------ ...elemetryLoggingAutoConfigurationTests.java | 228 ++++++++++++++++++ ...gingAutoConfigurationIntegrationTests.java | 7 +- .../OtlpLoggingAutoConfigurationTests.java | 12 +- 23 files changed, 361 insertions(+), 235 deletions(-) create mode 100644 module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingAutoConfiguration.java rename module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/{ => logging}/SdkLoggerProviderBuilderCustomizer.java (94%) rename module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/{ => otlp}/OtlpLoggingAutoConfiguration.java (94%) rename module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/{ => otlp}/OtlpLoggingConfigurations.java (99%) rename module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/{ => otlp}/OtlpLoggingConnectionDetails.java (99%) rename module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/{ => otlp}/OtlpLoggingProperties.java (99%) rename module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/{ => otlp}/Transport.java (98%) create mode 100644 module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/package-info.java create mode 100644 module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingAutoConfigurationTests.java rename module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/{ => otlp}/OtlpLoggingAutoConfigurationIntegrationTests.java (94%) rename module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/{ => otlp}/OtlpLoggingAutoConfigurationTests.java (95%) diff --git a/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/GrafanaOtlpLoggingDockerComposeConnectionDetailsFactoryTests.java b/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/GrafanaOtlpLoggingDockerComposeConnectionDetailsFactoryTests.java index 082df12f8a1..8f7a08f51a1 100644 --- a/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/GrafanaOtlpLoggingDockerComposeConnectionDetailsFactoryTests.java +++ b/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/GrafanaOtlpLoggingDockerComposeConnectionDetailsFactoryTests.java @@ -17,8 +17,8 @@ package org.springframework.boot.opentelemetry.docker.compose; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; -import org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingConnectionDetails; -import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.Transport; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/OtelCollectorOtlpLoggingDockerComposeConnectionDetailsFactoryTests.java b/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/OtelCollectorOtlpLoggingDockerComposeConnectionDetailsFactoryTests.java index 2d903c795e8..f4909682332 100644 --- a/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/OtelCollectorOtlpLoggingDockerComposeConnectionDetailsFactoryTests.java +++ b/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/docker/compose/OtelCollectorOtlpLoggingDockerComposeConnectionDetailsFactoryTests.java @@ -17,8 +17,8 @@ package org.springframework.boot.opentelemetry.docker.compose; import org.springframework.boot.docker.compose.service.connection.test.DockerComposeTest; -import org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingConnectionDetails; -import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.Transport; import org.springframework.boot.testsupport.container.TestImage; import static org.assertj.core.api.Assertions.assertThat; diff --git a/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOtlpLoggingContainerConnectionDetailsFactoryTests.java b/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOtlpLoggingContainerConnectionDetailsFactoryTests.java index 3a33d0707e8..563755574a6 100644 --- a/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOtlpLoggingContainerConnectionDetailsFactoryTests.java +++ b/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOtlpLoggingContainerConnectionDetailsFactoryTests.java @@ -23,9 +23,9 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingAutoConfiguration; -import org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingConnectionDetails; -import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingAutoConfiguration; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.Transport; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; diff --git a/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/OtelCollectorOltpLoggingContainerConnectionDetailsFactoryTests.java b/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/OtelCollectorOltpLoggingContainerConnectionDetailsFactoryTests.java index 14f884c8ebe..69aab41c197 100644 --- a/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/OtelCollectorOltpLoggingContainerConnectionDetailsFactoryTests.java +++ b/module/spring-boot-opentelemetry/src/dockerTest/java/org/springframework/boot/opentelemetry/testcontainers/OtelCollectorOltpLoggingContainerConnectionDetailsFactoryTests.java @@ -23,9 +23,9 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.ImportAutoConfiguration; -import org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingAutoConfiguration; -import org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingConnectionDetails; -import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingAutoConfiguration; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.Transport; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; import org.springframework.boot.testsupport.container.TestImage; import org.springframework.context.annotation.Configuration; diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfiguration.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfiguration.java index 3e6dedaca3a..465d0d5d98f 100644 --- a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfiguration.java +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfiguration.java @@ -20,11 +20,7 @@ import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.OpenTelemetrySdkBuilder; -import io.opentelemetry.sdk.logs.LogRecordProcessor; 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.resources.Resource; import io.opentelemetry.sdk.resources.ResourceBuilder; @@ -37,7 +33,6 @@ 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.Configuration; import org.springframework.core.env.Environment; /** @@ -80,30 +75,4 @@ public final class OpenTelemetrySdkAutoConfiguration { return builder.build(); } - @Configuration(proxyBeanMethods = false) - @ConditionalOnClass(SdkLoggerProvider.class) - static class LoggerConfiguration { - - @Bean - @ConditionalOnMissingBean - BatchLogRecordProcessor openTelemetryBatchLogRecordProcessor( - ObjectProvider logRecordExporters) { - LogRecordExporter exporter = LogRecordExporter.composite(logRecordExporters.orderedStream().toList()); - return BatchLogRecordProcessor.builder(exporter).build(); - } - - @Bean - @ConditionalOnMissingBean - SdkLoggerProvider openTelemetrySdkLoggerProvider(Resource openTelemetryResource, - ObjectProvider logRecordProcessors, - ObjectProvider customizers) { - SdkLoggerProviderBuilder builder = SdkLoggerProvider.builder(); - builder.setResource(openTelemetryResource); - logRecordProcessors.orderedStream().forEach(builder::addLogRecordProcessor); - customizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); - return builder.build(); - } - - } - } diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingAutoConfiguration.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingAutoConfiguration.java new file mode 100644 index 00000000000..56da453b7aa --- /dev/null +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingAutoConfiguration.java @@ -0,0 +1,68 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.opentelemetry.autoconfigure.logging; + +import io.opentelemetry.sdk.logs.LogRecordProcessor; +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.resources.Resource; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetrySdkAutoConfiguration; +import org.springframework.context.annotation.Bean; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for OpenTelemetry logging. + * + * @author Moritz Halbritter + * @since 4.0.0 + */ +@AutoConfiguration(after = OpenTelemetrySdkAutoConfiguration.class) +@ConditionalOnClass(SdkLoggerProvider.class) +public final class OpenTelemetryLoggingAutoConfiguration { + + OpenTelemetryLoggingAutoConfiguration() { + } + + @Bean + @ConditionalOnMissingBean + BatchLogRecordProcessor openTelemetryBatchLogRecordProcessor(ObjectProvider logRecordExporters) { + LogRecordExporter exporter = LogRecordExporter.composite(logRecordExporters.orderedStream().toList()); + return BatchLogRecordProcessor.builder(exporter).build(); + } + + @Bean + @ConditionalOnMissingBean + @ConditionalOnBean(Resource.class) + SdkLoggerProvider openTelemetrySdkLoggerProvider(Resource openTelemetryResource, + ObjectProvider logRecordProcessors, + ObjectProvider customizers) { + SdkLoggerProviderBuilder builder = SdkLoggerProvider.builder(); + builder.setResource(openTelemetryResource); + logRecordProcessors.orderedStream().forEach(builder::addLogRecordProcessor); + customizers.orderedStream().forEach((customizer) -> customizer.customize(builder)); + return builder.build(); + } + +} diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/SdkLoggerProviderBuilderCustomizer.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/SdkLoggerProviderBuilderCustomizer.java similarity index 94% rename from module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/SdkLoggerProviderBuilderCustomizer.java rename to module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/SdkLoggerProviderBuilderCustomizer.java index 23beda19673..9383d3355c4 100644 --- a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/SdkLoggerProviderBuilderCustomizer.java +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/SdkLoggerProviderBuilderCustomizer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.opentelemetry.autoconfigure; +package org.springframework.boot.opentelemetry.autoconfigure.logging; import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingAutoConfiguration.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingAutoConfiguration.java similarity index 94% rename from module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingAutoConfiguration.java rename to module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingAutoConfiguration.java index da4bd279cc5..a26ce2d4cd3 100644 --- a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingAutoConfiguration.java +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingAutoConfiguration.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.opentelemetry.autoconfigure.logging; +package org.springframework.boot.opentelemetry.autoconfigure.logging.otlp; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.sdk.logs.SdkLoggerProvider; @@ -24,8 +24,8 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingConfigurations.ConnectionDetails; -import org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingConfigurations.Exporters; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingConfigurations.ConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingConfigurations.Exporters; import org.springframework.context.annotation.Import; /** diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingConfigurations.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingConfigurations.java similarity index 99% rename from module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingConfigurations.java rename to module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingConfigurations.java index 5d4ecec61d0..2225783e64c 100644 --- a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingConfigurations.java +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingConfigurations.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.opentelemetry.autoconfigure.logging; +package org.springframework.boot.opentelemetry.autoconfigure.logging.otlp; import java.util.Locale; diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingConnectionDetails.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingConnectionDetails.java similarity index 99% rename from module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingConnectionDetails.java rename to module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingConnectionDetails.java index f73de8bbd92..70c25fb3753 100644 --- a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingConnectionDetails.java +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingConnectionDetails.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.opentelemetry.autoconfigure.logging; +package org.springframework.boot.opentelemetry.autoconfigure.logging.otlp; import org.springframework.boot.autoconfigure.service.connection.ConnectionDetails; diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingProperties.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingProperties.java similarity index 99% rename from module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingProperties.java rename to module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingProperties.java index 189d485aee1..1d4ac6e7f77 100644 --- a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingProperties.java +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingProperties.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.opentelemetry.autoconfigure.logging; +package org.springframework.boot.opentelemetry.autoconfigure.logging.otlp; import java.time.Duration; import java.util.HashMap; diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/Transport.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/Transport.java similarity index 98% rename from module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/Transport.java rename to module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/Transport.java index cfea5cee1be..5c03b7fc07d 100644 --- a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/Transport.java +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/Transport.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.opentelemetry.autoconfigure.logging; +package org.springframework.boot.opentelemetry.autoconfigure.logging.otlp; /** * Transport used to send OTLP log data. diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/package-info.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/package-info.java new file mode 100644 index 00000000000..eaa29a3f159 --- /dev/null +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for exporting logs with OpenTelemetry via OTLP. + */ +@NullMarked +package org.springframework.boot.opentelemetry.autoconfigure.logging.otlp; + +import org.jspecify.annotations.NullMarked; diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/package-info.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/package-info.java index ad105221b96..30be80211db 100644 --- a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/package-info.java +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/autoconfigure/logging/package-info.java @@ -15,7 +15,7 @@ */ /** - * Auto-configuration for exporting logs with OpenTelemetry. + * Auto-configuration for OpenTelemetry logging. */ @NullMarked package org.springframework.boot.opentelemetry.autoconfigure.logging; diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/docker/compose/OtlpLoggingDockerComposeConnectionDetailsFactory.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/docker/compose/OtlpLoggingDockerComposeConnectionDetailsFactory.java index 37bdb5cb409..160fec162ba 100644 --- a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/docker/compose/OtlpLoggingDockerComposeConnectionDetailsFactory.java +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/docker/compose/OtlpLoggingDockerComposeConnectionDetailsFactory.java @@ -19,8 +19,8 @@ package org.springframework.boot.opentelemetry.docker.compose; import org.springframework.boot.docker.compose.core.RunningService; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionDetailsFactory; import org.springframework.boot.docker.compose.service.connection.DockerComposeConnectionSource; -import org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingConnectionDetails; -import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.Transport; /** * {@link DockerComposeConnectionDetailsFactory} to create @@ -40,7 +40,7 @@ class OtlpLoggingDockerComposeConnectionDetailsFactory OtlpLoggingDockerComposeConnectionDetailsFactory() { super(OPENTELEMETRY_IMAGE_NAMES, - "org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingAutoConfiguration"); + "org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingAutoConfiguration"); } @Override diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOtlpLoggingContainerConnectionDetailsFactory.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOtlpLoggingContainerConnectionDetailsFactory.java index d8bf6a52d00..b50188dbbcb 100644 --- a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOtlpLoggingContainerConnectionDetailsFactory.java +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/GrafanaOtlpLoggingContainerConnectionDetailsFactory.java @@ -18,8 +18,8 @@ package org.springframework.boot.opentelemetry.testcontainers; import org.testcontainers.grafana.LgtmStackContainer; -import org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingConnectionDetails; -import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.Transport; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/OtelCollectorOltpLoggingContainerConnectionDetailsFactory.java b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/OtelCollectorOltpLoggingContainerConnectionDetailsFactory.java index 62dd6b7b634..b65c8308acb 100644 --- a/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/OtelCollectorOltpLoggingContainerConnectionDetailsFactory.java +++ b/module/spring-boot-opentelemetry/src/main/java/org/springframework/boot/opentelemetry/testcontainers/OtelCollectorOltpLoggingContainerConnectionDetailsFactory.java @@ -19,8 +19,8 @@ package org.springframework.boot.opentelemetry.testcontainers; import org.testcontainers.containers.Container; import org.testcontainers.containers.GenericContainer; -import org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingConnectionDetails; -import org.springframework.boot.opentelemetry.autoconfigure.logging.Transport; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.Transport; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionDetailsFactory; import org.springframework.boot.testcontainers.service.connection.ContainerConnectionSource; import org.springframework.boot.testcontainers.service.connection.ServiceConnection; diff --git a/module/spring-boot-opentelemetry/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/module/spring-boot-opentelemetry/src/main/resources/META-INF/additional-spring-configuration-metadata.json index 3aca58ea441..32133b47c30 100644 --- a/module/spring-boot-opentelemetry/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/module/spring-boot-opentelemetry/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -1,18 +1,11 @@ { "groups": [], "properties": [ - { - "name": "management.otlp.logging.export.enabled", - "deprecation": { - "replacement": "management.logging.export.otlp.enabled", - "level": "error" - } - }, { "name": "management.logging.export.otlp.enabled", "type": "java.lang.Boolean", "description": "Whether auto-configuration of logging is enabled to export logs over OTLP." - }, + }, { "name": "management.otlp.logging", "type": "org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.OpenTelemetryLoggingExportProperties", @@ -22,7 +15,7 @@ "level": "error" } }, - { + { "name": "management.otlp.logging.compression", "type": "org.springframework.boot.opentelemetry.actuate.autoconfigure.logging.OpenTelemetryLoggingExportProperties$Compression", "description": "Method used to compress the payload.", @@ -54,10 +47,8 @@ "level": "error" } }, - { + { "name": "management.otlp.logging.export.enabled", - "type": "java.lang.Boolean", - "description": "Whether auto-configuration of logging is enabled to export OTLP logs.", "deprecation": { "replacement": "management.logging.export.otlp.enabled", "level": "error" diff --git a/module/spring-boot-opentelemetry/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/module/spring-boot-opentelemetry/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 11af2d97f97..ca3030a43c7 100644 --- a/module/spring-boot-opentelemetry/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/module/spring-boot-opentelemetry/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -1,2 +1,3 @@ org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetrySdkAutoConfiguration -org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingAutoConfiguration +org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingAutoConfiguration +org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingAutoConfiguration diff --git a/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfigurationTests.java b/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfigurationTests.java index af28a1a84b5..f2a407e95de 100644 --- a/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfigurationTests.java +++ b/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/OpenTelemetrySdkAutoConfigurationTests.java @@ -16,22 +16,11 @@ package org.springframework.boot.opentelemetry.autoconfigure; -import java.util.Collection; -import java.util.concurrent.atomic.AtomicInteger; - import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.common.AttributeKey; -import io.opentelemetry.context.Context; import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.common.CompletableResultCode; -import io.opentelemetry.sdk.logs.LogRecordProcessor; -import io.opentelemetry.sdk.logs.ReadWriteLogRecord; import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; -import io.opentelemetry.sdk.logs.data.LogRecordData; -import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; -import io.opentelemetry.sdk.logs.export.LogRecordExporter; import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; @@ -74,8 +63,6 @@ class OpenTelemetrySdkAutoConfigurationTests { this.contextRunner.run((context) -> { assertThat(context).hasSingleBean(OpenTelemetrySdk.class); assertThat(context).hasSingleBean(Resource.class); - assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); - assertThat(context).hasSingleBean(SdkLoggerProvider.class); }); } @@ -85,8 +72,6 @@ class OpenTelemetrySdkAutoConfigurationTests { this.contextRunner.withClassLoader(new FilteredClassLoader(packageName)).run((context) -> { assertThat(context).doesNotHaveBean(OpenTelemetrySdk.class); assertThat(context).doesNotHaveBean(Resource.class); - assertThat(context).doesNotHaveBean(BatchLogRecordProcessor.class); - assertThat(context).doesNotHaveBean(SdkLoggerProvider.class); }); } @@ -95,8 +80,6 @@ class OpenTelemetrySdkAutoConfigurationTests { this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.sdk.logs")).run((context) -> { assertThat(context).hasSingleBean(OpenTelemetrySdk.class); assertThat(context).hasSingleBean(Resource.class); - assertThat(context).doesNotHaveBean(BatchLogRecordProcessor.class); - assertThat(context).doesNotHaveBean(SdkLoggerProvider.class); }); } @@ -107,10 +90,6 @@ class OpenTelemetrySdkAutoConfigurationTests { assertThat(context).hasBean("customOpenTelemetry"); assertThat(context).hasSingleBean(Resource.class); assertThat(context).hasBean("customResource"); - assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); - assertThat(context).hasBean("customBatchLogRecordProcessor").hasSingleBean(BatchLogRecordProcessor.class); - assertThat(context).hasSingleBean(LogRecordProcessor.class); - assertThat(context).hasBean("customSdkLoggerProvider").hasSingleBean(SdkLoggerProvider.class); }); } @@ -201,45 +180,6 @@ class OpenTelemetrySdkAutoConfigurationTests { }); } - @Test - void whenHasMultipleLogRecordExportersProvidesBatchLogRecordProcessor() { - this.contextRunner.withUserConfiguration(MultipleLogRecordExportersConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); - assertThat(context.getBeansOfType(LogRecordExporter.class)).hasSize(2); - assertThat(context).hasBean("customLogRecordExporter1"); - assertThat(context).hasBean("customLogRecordExporter2"); - }); - } - - @Test - void whenHasMultipleLogRecordProcessorsStillProvidesBatchLogRecordProcessor() { - this.contextRunner.withUserConfiguration(MultipleLogRecordProcessorsConfiguration.class).run((context) -> { - assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); - assertThat(context).hasSingleBean(SdkLoggerProvider.class); - assertThat(context.getBeansOfType(LogRecordProcessor.class)).hasSize(3); - assertThat(context).hasBean("openTelemetryBatchLogRecordProcessor"); - assertThat(context).hasBean("customLogRecordProcessor1"); - assertThat(context).hasBean("customLogRecordProcessor2"); - }); - } - - @Test - void whenHasMultipleSdkLoggerProviderBuilderCustomizersCallsCustomizeMethod() { - this.contextRunner.withUserConfiguration(MultipleSdkLoggerProviderBuilderCustomizersConfiguration.class) - .run((context) -> { - assertThat(context).hasSingleBean(SdkLoggerProvider.class); - assertThat(context.getBeansOfType(SdkLoggerProviderBuilderCustomizer.class)).hasSize(2); - assertThat(context).hasBean("customSdkLoggerProviderBuilderCustomizer1"); - assertThat(context).hasBean("customSdkLoggerProviderBuilderCustomizer2"); - assertThat(context - .getBean("customSdkLoggerProviderBuilderCustomizer1", NoopSdkLoggerProviderBuilderCustomizer.class) - .called()).isEqualTo(1); - assertThat(context - .getBean("customSdkLoggerProviderBuilderCustomizer2", NoopSdkLoggerProviderBuilderCustomizer.class) - .called()).isEqualTo(1); - }); - } - @Configuration(proxyBeanMethods = false) static class UserConfiguration { @@ -253,103 +193,6 @@ class OpenTelemetrySdkAutoConfigurationTests { return Resource.getDefault(); } - @Bean - BatchLogRecordProcessor customBatchLogRecordProcessor() { - return BatchLogRecordProcessor.builder(new NoopLogRecordExporter()).build(); - } - - @Bean - SdkLoggerProvider customSdkLoggerProvider() { - return SdkLoggerProvider.builder().build(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class MultipleLogRecordExportersConfiguration { - - @Bean - LogRecordExporter customLogRecordExporter1() { - return new NoopLogRecordExporter(); - } - - @Bean - LogRecordExporter customLogRecordExporter2() { - return new NoopLogRecordExporter(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class MultipleLogRecordProcessorsConfiguration { - - @Bean - LogRecordProcessor customLogRecordProcessor1() { - return new NoopLogRecordProcessor(); - } - - @Bean - LogRecordProcessor customLogRecordProcessor2() { - return new NoopLogRecordProcessor(); - } - - } - - @Configuration(proxyBeanMethods = false) - static class MultipleSdkLoggerProviderBuilderCustomizersConfiguration { - - @Bean - SdkLoggerProviderBuilderCustomizer customSdkLoggerProviderBuilderCustomizer1() { - return new NoopSdkLoggerProviderBuilderCustomizer(); - } - - @Bean - SdkLoggerProviderBuilderCustomizer customSdkLoggerProviderBuilderCustomizer2() { - return new NoopSdkLoggerProviderBuilderCustomizer(); - } - - } - - static class NoopLogRecordExporter implements LogRecordExporter { - - @Override - public CompletableResultCode export(Collection logs) { - return CompletableResultCode.ofSuccess(); - } - - @Override - public CompletableResultCode flush() { - return CompletableResultCode.ofSuccess(); - } - - @Override - public CompletableResultCode shutdown() { - return CompletableResultCode.ofSuccess(); - } - - } - - static class NoopLogRecordProcessor implements LogRecordProcessor { - - @Override - public void onEmit(Context context, ReadWriteLogRecord logRecord) { - } - - } - - static class NoopSdkLoggerProviderBuilderCustomizer implements SdkLoggerProviderBuilderCustomizer { - - final AtomicInteger called = new AtomicInteger(0); - - @Override - public void customize(SdkLoggerProviderBuilder builder) { - this.called.incrementAndGet(); - } - - int called() { - return this.called.get(); - } - } } diff --git a/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingAutoConfigurationTests.java b/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingAutoConfigurationTests.java new file mode 100644 index 00000000000..d12e3eb2b58 --- /dev/null +++ b/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OpenTelemetryLoggingAutoConfigurationTests.java @@ -0,0 +1,228 @@ +/* + * Copyright 2012-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.opentelemetry.autoconfigure.logging; + +import java.util.Collection; +import java.util.concurrent.atomic.AtomicInteger; + +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.logs.LogRecordProcessor; +import io.opentelemetry.sdk.logs.ReadWriteLogRecord; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; +import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder; +import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor; +import io.opentelemetry.sdk.logs.export.LogRecordExporter; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.context.annotation.ImportCandidates; +import org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetrySdkAutoConfiguration; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link OpenTelemetryLoggingAutoConfiguration}. + * + * @author Moritz Halbritter + */ +class OpenTelemetryLoggingAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(OpenTelemetrySdkAutoConfiguration.class, + OpenTelemetryLoggingAutoConfiguration.class)); + + @Test + void registeredInAutoConfigurationImports() { + assertThat(ImportCandidates.load(AutoConfiguration.class, null).getCandidates()) + .contains(OpenTelemetryLoggingAutoConfiguration.class.getName()); + } + + @Test + void providesBeans() { + this.contextRunner.run((context) -> { + assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); + assertThat(context).hasSingleBean(SdkLoggerProvider.class); + }); + } + + @Test + void whenOpenTelemetryLogsIsNotOnClasspathDoesNotProvideBeans() { + this.contextRunner.withClassLoader(new FilteredClassLoader("io.opentelemetry.sdk.logs")).run((context) -> { + assertThat(context).doesNotHaveBean(BatchLogRecordProcessor.class); + assertThat(context).doesNotHaveBean(SdkLoggerProvider.class); + }); + } + + @Test + void whenHasUserSuppliedBeansDoesNotProvideBeans() { + this.contextRunner.withUserConfiguration(UserConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); + assertThat(context).hasBean("customBatchLogRecordProcessor").hasSingleBean(BatchLogRecordProcessor.class); + assertThat(context).hasSingleBean(LogRecordProcessor.class); + assertThat(context).hasBean("customSdkLoggerProvider").hasSingleBean(SdkLoggerProvider.class); + }); + } + + @Test + void whenHasMultipleLogRecordExportersProvidesBatchLogRecordProcessor() { + this.contextRunner.withUserConfiguration(MultipleLogRecordExportersConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); + assertThat(context.getBeansOfType(LogRecordExporter.class)).hasSize(2); + assertThat(context).hasBean("customLogRecordExporter1"); + assertThat(context).hasBean("customLogRecordExporter2"); + }); + } + + @Test + void whenHasMultipleLogRecordProcessorsStillProvidesBatchLogRecordProcessor() { + this.contextRunner.withUserConfiguration(MultipleLogRecordProcessorsConfiguration.class).run((context) -> { + assertThat(context).hasSingleBean(BatchLogRecordProcessor.class); + assertThat(context).hasSingleBean(SdkLoggerProvider.class); + assertThat(context.getBeansOfType(LogRecordProcessor.class)).hasSize(3); + assertThat(context).hasBean("openTelemetryBatchLogRecordProcessor"); + assertThat(context).hasBean("customLogRecordProcessor1"); + assertThat(context).hasBean("customLogRecordProcessor2"); + }); + } + + @Test + void whenHasMultipleSdkLoggerProviderBuilderCustomizersCallsCustomizeMethod() { + this.contextRunner.withUserConfiguration(MultipleSdkLoggerProviderBuilderCustomizersConfiguration.class) + .run((context) -> { + assertThat(context).hasSingleBean(SdkLoggerProvider.class); + assertThat(context.getBeansOfType(SdkLoggerProviderBuilderCustomizer.class)).hasSize(2); + assertThat(context).hasBean("customSdkLoggerProviderBuilderCustomizer1"); + assertThat(context).hasBean("customSdkLoggerProviderBuilderCustomizer2"); + assertThat(context + .getBean("customSdkLoggerProviderBuilderCustomizer1", NoopSdkLoggerProviderBuilderCustomizer.class) + .called()).isEqualTo(1); + assertThat(context + .getBean("customSdkLoggerProviderBuilderCustomizer2", NoopSdkLoggerProviderBuilderCustomizer.class) + .called()).isEqualTo(1); + }); + } + + @Configuration(proxyBeanMethods = false) + static class UserConfiguration { + + @Bean + BatchLogRecordProcessor customBatchLogRecordProcessor() { + return BatchLogRecordProcessor.builder(new NoopLogRecordExporter()).build(); + } + + @Bean + SdkLoggerProvider customSdkLoggerProvider() { + return SdkLoggerProvider.builder().build(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class MultipleLogRecordExportersConfiguration { + + @Bean + LogRecordExporter customLogRecordExporter1() { + return new NoopLogRecordExporter(); + } + + @Bean + LogRecordExporter customLogRecordExporter2() { + return new NoopLogRecordExporter(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class MultipleLogRecordProcessorsConfiguration { + + @Bean + LogRecordProcessor customLogRecordProcessor1() { + return new NoopLogRecordProcessor(); + } + + @Bean + LogRecordProcessor customLogRecordProcessor2() { + return new NoopLogRecordProcessor(); + } + + } + + @Configuration(proxyBeanMethods = false) + static class MultipleSdkLoggerProviderBuilderCustomizersConfiguration { + + @Bean + SdkLoggerProviderBuilderCustomizer customSdkLoggerProviderBuilderCustomizer1() { + return new NoopSdkLoggerProviderBuilderCustomizer(); + } + + @Bean + SdkLoggerProviderBuilderCustomizer customSdkLoggerProviderBuilderCustomizer2() { + return new NoopSdkLoggerProviderBuilderCustomizer(); + } + + } + + static class NoopLogRecordExporter implements LogRecordExporter { + + @Override + public CompletableResultCode export(Collection logs) { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode flush() { + return CompletableResultCode.ofSuccess(); + } + + @Override + public CompletableResultCode shutdown() { + return CompletableResultCode.ofSuccess(); + } + + } + + static class NoopLogRecordProcessor implements LogRecordProcessor { + + @Override + public void onEmit(Context context, ReadWriteLogRecord logRecord) { + } + + } + + static class NoopSdkLoggerProviderBuilderCustomizer implements SdkLoggerProviderBuilderCustomizer { + + final AtomicInteger called = new AtomicInteger(0); + + @Override + public void customize(SdkLoggerProviderBuilder builder) { + this.called.incrementAndGet(); + } + + int called() { + return this.called.get(); + } + + } + +} diff --git a/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingAutoConfigurationIntegrationTests.java b/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingAutoConfigurationIntegrationTests.java similarity index 94% rename from module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingAutoConfigurationIntegrationTests.java rename to module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingAutoConfigurationIntegrationTests.java index ebaed5dd629..6d52496c3fa 100644 --- a/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingAutoConfigurationIntegrationTests.java +++ b/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingAutoConfigurationIntegrationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.opentelemetry.autoconfigure.logging; +package org.springframework.boot.opentelemetry.autoconfigure.logging.otlp; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -34,6 +34,7 @@ import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetrySdkAutoConfiguration; +import org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingAutoConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.ApplicationContext; @@ -49,8 +50,8 @@ class OtlpLoggingAutoConfigurationIntegrationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withPropertyValues("spring.application.name=otlp-logs-test", "management.opentelemetry.logging.export.otlp.headers.Authorization=Bearer my-token") - .withConfiguration( - AutoConfigurations.of(OpenTelemetrySdkAutoConfiguration.class, OtlpLoggingAutoConfiguration.class)); + .withConfiguration(AutoConfigurations.of(OpenTelemetrySdkAutoConfiguration.class, + OpenTelemetryLoggingAutoConfiguration.class, OtlpLoggingAutoConfiguration.class)); private final MockWebServer mockWebServer = new MockWebServer(); diff --git a/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingAutoConfigurationTests.java b/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingAutoConfigurationTests.java similarity index 95% rename from module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingAutoConfigurationTests.java rename to module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingAutoConfigurationTests.java index 380ff6e3dfb..d05f35560db 100644 --- a/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/OtlpLoggingAutoConfigurationTests.java +++ b/module/spring-boot-opentelemetry/src/test/java/org/springframework/boot/opentelemetry/autoconfigure/logging/otlp/OtlpLoggingAutoConfigurationTests.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.boot.opentelemetry.autoconfigure.logging; +package org.springframework.boot.opentelemetry.autoconfigure.logging.otlp; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Supplier; @@ -34,8 +34,9 @@ import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.context.annotation.ImportCandidates; import org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetrySdkAutoConfiguration; -import org.springframework.boot.opentelemetry.autoconfigure.SdkLoggerProviderBuilderCustomizer; -import org.springframework.boot.opentelemetry.autoconfigure.logging.OtlpLoggingConfigurations.ConnectionDetails.PropertiesOtlpLoggingConnectionDetails; +import org.springframework.boot.opentelemetry.autoconfigure.logging.OpenTelemetryLoggingAutoConfiguration; +import org.springframework.boot.opentelemetry.autoconfigure.logging.SdkLoggerProviderBuilderCustomizer; +import org.springframework.boot.opentelemetry.autoconfigure.logging.otlp.OtlpLoggingConfigurations.ConnectionDetails.PropertiesOtlpLoggingConnectionDetails; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; @@ -54,8 +55,9 @@ class OtlpLoggingAutoConfigurationTests { private final ApplicationContextRunner contextRunner; OtlpLoggingAutoConfigurationTests() { - this.contextRunner = new ApplicationContextRunner().withConfiguration( - AutoConfigurations.of(OpenTelemetrySdkAutoConfiguration.class, OtlpLoggingAutoConfiguration.class)); + this.contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(OpenTelemetrySdkAutoConfiguration.class, + OpenTelemetryLoggingAutoConfiguration.class, OtlpLoggingAutoConfiguration.class)); } @Test