From 8709349361ee8ca947a720fa62c07c5b48237b82 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 28 Feb 2024 13:54:02 +0100 Subject: [PATCH] spring starter shouldn't depend on spring-boot-resources, which uses snake yaml, which doesn't work with graal native --- .../build.gradle.kts | 1 - .../OtelResourceAutoConfiguration.java | 22 +++++------------ .../resources/SpringResourceProvider.java | 17 +++++++++++++ .../OpenTelemetryAutoConfigurationTest.java | 24 +++++++++++++++++++ .../SpringBootServiceNameDetector.java | 4 ++-- .../SpringBootServiceVersionDetector.java | 4 ++++ .../spring-boot-starter/build.gradle.kts | 1 - 7 files changed, 53 insertions(+), 20 deletions(-) diff --git a/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts b/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts index 980e1376f470..ffe05a2e8c9b 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts +++ b/instrumentation/spring/spring-boot-autoconfigure/build.gradle.kts @@ -46,7 +46,6 @@ dependencies { compileOnly(project(":instrumentation-annotations")) compileOnly(project(":instrumentation:resources:library")) - compileOnly(project(":instrumentation:spring:spring-boot-resources:library")) annotationProcessor("com.google.auto.service:auto-service") compileOnly("com.google.auto.service:auto-service-annotations") 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 index 2efcf96bb327..928225b6a350 100644 --- 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 @@ -17,14 +17,15 @@ import io.opentelemetry.instrumentation.resources.ProcessRuntimeResourceProvider; import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.SdkEnabled; -import io.opentelemetry.instrumentation.spring.resources.SpringBootServiceNameDetector; -import io.opentelemetry.instrumentation.spring.resources.SpringBootServiceVersionDetector; import io.opentelemetry.sdk.autoconfigure.internal.EnvironmentResourceProvider; import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; 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; @@ -42,8 +43,9 @@ public ResourceProvider otelEnvironmentResourceProvider() { } @Bean - public ResourceProvider otelSpringResourceProvider() { - return new SpringResourceProvider(); + public ResourceProvider otelSpringResourceProvider( + @Autowired(required = false) BuildProperties buildProperties) { + return new SpringResourceProvider(Optional.ofNullable(buildProperties)); } @Bean @@ -51,18 +53,6 @@ public ResourceProvider otelDistroVersionResourceProvider() { return new DistroVersionResourceProvider(); } - @Bean - @ConditionalOnClass(SpringBootServiceNameDetector.class) - public ResourceProvider otelSpringBootServiceNameResourceProvider() { - return new SpringBootServiceNameDetector(); - } - - @Bean - @ConditionalOnClass(SpringBootServiceVersionDetector.class) - public ResourceProvider otelSpringBootServiceVersionResourceProvider() { - return new SpringBootServiceVersionDetector(); - } - @Bean @ConditionalOnClass(OsResource.class) public ResourceProvider otelOsResourceProvider() { diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProvider.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProvider.java index 756d227f818e..baf76a586ce2 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProvider.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/resources/SpringResourceProvider.java @@ -11,16 +11,33 @@ import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.semconv.ResourceAttributes; +import java.util.Optional; +import org.springframework.boot.info.BuildProperties; public class SpringResourceProvider implements ResourceProvider { + private final Optional buildProperties; + + public SpringResourceProvider(Optional buildProperties) { + this.buildProperties = buildProperties; + } + @Override public Resource createResource(ConfigProperties configProperties) { AttributesBuilder attributesBuilder = Attributes.builder(); + buildProperties + .map(BuildProperties::getName) + .ifPresent(v -> attributesBuilder.put(ResourceAttributes.SERVICE_NAME, v)); + String springApplicationName = configProperties.getString("spring.application.name"); if (springApplicationName != null) { attributesBuilder.put(ResourceAttributes.SERVICE_NAME, springApplicationName); } + + buildProperties + .map(BuildProperties::getVersion) + .ifPresent(v -> attributesBuilder.put(ResourceAttributes.SERVICE_VERSION, v)); + return Resource.create(attributesBuilder.build()); } } 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 e0bf3f98f849..4c8cdd43ec02 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,6 +6,7 @@ package io.opentelemetry.instrumentation.spring.autoconfigure; 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 io.opentelemetry.api.OpenTelemetry; @@ -16,9 +17,11 @@ import io.opentelemetry.sdk.metrics.SdkMeterProvider; import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.SdkTracerProvider; +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.TestConfiguration; import org.springframework.boot.test.context.runner.ApplicationContextRunner; import org.springframework.context.annotation.Bean; @@ -117,6 +120,27 @@ void shouldDetermineServiceNameBySpringApplicationName() { }); } + @Test + @DisplayName( + "when spring.application.name is set value should be passed to service name attribute") + void shouldDetermineServiceNameAndVersionBySpringApplicationVersion() { + Properties properties = new Properties(); + properties.put("name", "demo"); + 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"); + }); + } + @Test @DisplayName( "when spring application name and otel service name are not set service name should be default") diff --git a/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameDetector.java b/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameDetector.java index 02eb3897ba3c..6ec01260aeaa 100644 --- a/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameDetector.java +++ b/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceNameDetector.java @@ -46,8 +46,8 @@ *
  • Check for --spring.application.name program argument via sun.java.command system property * * - *

    Note: should not be used inside a spring application, where the spring.application.name is - * already available. + *

    Note: The spring starter already includes provider in + * io.opentelemetry.instrumentation.spring.autoconfigure.resources.SpringResourceProvider */ @AutoService(ResourceProvider.class) public class SpringBootServiceNameDetector implements ConditionalResourceProvider { diff --git a/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceVersionDetector.java b/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceVersionDetector.java index 3c9ddb05fcdd..b858e28e8acd 100644 --- a/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceVersionDetector.java +++ b/instrumentation/spring/spring-boot-resources/library/src/main/java/io/opentelemetry/instrumentation/spring/resources/SpringBootServiceVersionDetector.java @@ -18,6 +18,10 @@ import java.util.Properties; import java.util.logging.Logger; +/** + * Note: The spring starter already includes provider in + * io.opentelemetry.instrumentation.spring.autoconfigure.resources.SpringResourceProvider + */ @AutoService(ResourceProvider.class) public class SpringBootServiceVersionDetector implements ResourceProvider { diff --git a/instrumentation/spring/starters/spring-boot-starter/build.gradle.kts b/instrumentation/spring/starters/spring-boot-starter/build.gradle.kts index 600b789300c0..66e481b2e6e6 100644 --- a/instrumentation/spring/starters/spring-boot-starter/build.gradle.kts +++ b/instrumentation/spring/starters/spring-boot-starter/build.gradle.kts @@ -14,7 +14,6 @@ dependencies { api(project(":instrumentation:spring:spring-boot-autoconfigure")) api(project(":instrumentation-annotations")) implementation(project(":instrumentation:resources:library")) - implementation(project(":instrumentation:spring:spring-boot-resources:library")) api("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi") api("io.opentelemetry:opentelemetry-api") api("io.opentelemetry:opentelemetry-exporter-logging")