diff --git a/.gitignore b/.gitignore index 6c4640f68103..6eb86aa73185 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ target !**/gradle/wrapper/* .gradle **/build/ +**/generated/ examples/**/build/ # Eclipse # 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 d850037dfd7f..c4a0b4fd00d1 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,6 +17,7 @@ import io.opentelemetry.instrumentation.resources.ProcessRuntimeResourceProvider; import io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration; import io.opentelemetry.sdk.autoconfigure.spi.ResourceProvider; +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; @@ -24,6 +25,7 @@ import org.springframework.boot.info.BuildProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import java.util.Optional; @Configuration @EnableConfigurationProperties({OtelSpringResourceProperties.class, OtelResourceProperties.class}) @@ -35,9 +37,9 @@ public class OtelResourceAutoConfiguration { public ResourceProvider otelResourceProvider( OtelSpringResourceProperties otelSpringResourceProperties, OtelResourceProperties otelResourceProperties, - BuildProperties buildProperties) { + @Autowired(required = false) BuildProperties buildProperties) { return new SpringResourceProvider( - otelSpringResourceProperties, otelResourceProperties, buildProperties); + otelSpringResourceProperties, otelResourceProperties, Optional.ofNullable(buildProperties)); } @Bean 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 63ffbf927078..b4c8125c7643 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,18 +11,19 @@ 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 OtelSpringResourceProperties otelSpringResourceProperties; private final OtelResourceProperties otelResourceProperties; - private final BuildProperties buildProperties; + private final Optional buildProperties; public SpringResourceProvider( OtelSpringResourceProperties otelSpringResourceProperties, OtelResourceProperties otelResourceProperties, - BuildProperties buildProperties) { + Optional buildProperties) { this.otelSpringResourceProperties = otelSpringResourceProperties; this.otelResourceProperties = otelResourceProperties; this.buildProperties = buildProperties; @@ -41,10 +42,9 @@ public Resource createResource(ConfigProperties configProperties) { if (applicationName != null) { attributesBuilder.put(ResourceAttributes.SERVICE_NAME, applicationName); } - String version = buildProperties.getVersion(); - if (version != null) { - attributesBuilder.put(ResourceAttributes.SERVICE_VERSION, version); - } + buildProperties + .map(entries -> entries.get("build.version")) + .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 1becb9116d2a..464b77963455 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 @@ -125,7 +125,7 @@ void shouldDetermineServiceNameBySpringApplicationName() { "when spring.application.name is set value should be passed to service name attribute") void shouldDetermineServiceVersionBySpringApplicationVersion() { Properties properties = new Properties(); - properties.put("version", "0.3"); + properties.put("build.version", "0.3"); this.contextRunner .withBean("buildProperties", BuildProperties.class, () -> new BuildProperties(properties)) .withConfiguration( 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 115e82359597..02eb3897ba3c 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,7 +46,7 @@ *
  • 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 + *

    Note: should not be used inside a spring application, where the spring.application.name is * already available. */ @AutoService(ResourceProvider.class) diff --git a/smoke-tests-otel-starter/build.gradle.kts b/smoke-tests-otel-starter/build.gradle.kts index 062ad5b5debf..65c018987178 100644 --- a/smoke-tests-otel-starter/build.gradle.kts +++ b/smoke-tests-otel-starter/build.gradle.kts @@ -53,6 +53,10 @@ configurations.configureEach { exclude("org.spockframework", "spock-core") } +springBoot { + buildInfo() +} + graalvmNative { binaries.all { // Workaround for https://github.com/junit-team/junit5/issues/3405 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 d7da4bd906a2..d11f49eb3bea 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 @@ -13,16 +13,19 @@ 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.testing.assertj.OpenTelemetryAssertions; import io.opentelemetry.sdk.testing.assertj.TracesAssert; import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; import io.opentelemetry.sdk.testing.exporter.InMemoryMetricExporter; import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; +import io.opentelemetry.semconv.ResourceAttributes; import io.opentelemetry.semconv.SemanticAttributes; import io.opentelemetry.spring.smoketest.OtelSpringStarterSmokeTestApplication; import io.opentelemetry.spring.smoketest.OtelSpringStarterSmokeTestController; import java.util.List; +import org.assertj.core.api.AbstractCharSequenceAssert; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -99,6 +102,12 @@ void shouldSendTelemetry() throws InterruptedException { spanDataAssert -> spanDataAssert .hasKind(SpanKind.SERVER) + .hasResourceSatisfying( + r -> + r.hasAttributesSatisfying( + OpenTelemetryAssertions.satisfies( + ResourceAttributes.SERVICE_VERSION, + AbstractCharSequenceAssert::isNotBlank))) .hasAttribute(SemanticAttributes.HTTP_REQUEST_METHOD, "GET") .hasAttribute(SemanticAttributes.HTTP_RESPONSE_STATUS_CODE, 200L) .hasAttribute(SemanticAttributes.HTTP_ROUTE, "/ping")));