From 9ca9b7e3d990922c9c869d401817ad4181ac5414 Mon Sep 17 00:00:00 2001 From: Jean Bisutti Date: Sun, 7 Jul 2024 20:15:23 +0200 Subject: [PATCH] GraalVM native support for the OpenTelemetry annotations --- .../OpenTelemetryAnnotationsRuntimeHints.java | 24 +++++++++++++++++++ .../resources/META-INF/spring/aot.factories | 2 ++ .../spring-boot-common/build.gradle.kts | 2 ++ .../AbstractOtelSpringStarterSmokeTest.java | 9 ++++--- .../OtelSpringStarterSmokeTestController.java | 6 ++++- .../spring/smoketest/SpringComponent.java | 18 ++++++++++++++ 6 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 instrumentation/spring/spring-boot-autoconfigure-3/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/instrumentation/annotations/OpenTelemetryAnnotationsRuntimeHints.java create mode 100644 instrumentation/spring/spring-boot-autoconfigure-3/src/main/resources/META-INF/spring/aot.factories create mode 100644 smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/SpringComponent.java diff --git a/instrumentation/spring/spring-boot-autoconfigure-3/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/instrumentation/annotations/OpenTelemetryAnnotationsRuntimeHints.java b/instrumentation/spring/spring-boot-autoconfigure-3/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/instrumentation/annotations/OpenTelemetryAnnotationsRuntimeHints.java new file mode 100644 index 000000000000..ae01b6efa4ac --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure-3/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/instrumentation/annotations/OpenTelemetryAnnotationsRuntimeHints.java @@ -0,0 +1,24 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.annotations; + +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.aot.hint.TypeReference; + +class OpenTelemetryAnnotationsRuntimeHints implements RuntimeHintsRegistrar { + + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + hints + .reflection() + .registerType( + TypeReference.of( + "io.opentelemetry.instrumentation.spring.autoconfigure.instrumentation.annotations.InstrumentationWithSpanAspect"), + hint -> hint.withMembers(MemberCategory.INVOKE_PUBLIC_METHODS)); + } +} diff --git a/instrumentation/spring/spring-boot-autoconfigure-3/src/main/resources/META-INF/spring/aot.factories b/instrumentation/spring/spring-boot-autoconfigure-3/src/main/resources/META-INF/spring/aot.factories new file mode 100644 index 000000000000..a14c7bbed2f3 --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure-3/src/main/resources/META-INF/spring/aot.factories @@ -0,0 +1,2 @@ +org.springframework.aot.hint.RuntimeHintsRegistrar=\ +opentelemetry.instrumentation.spring.autoconfigure.instrumentation.annotations.OpenTelemetryRuntimeHints diff --git a/smoke-tests-otel-starter/spring-boot-common/build.gradle.kts b/smoke-tests-otel-starter/spring-boot-common/build.gradle.kts index e32d7771828e..c260f55ddd89 100644 --- a/smoke-tests-otel-starter/spring-boot-common/build.gradle.kts +++ b/smoke-tests-otel-starter/spring-boot-common/build.gradle.kts @@ -20,6 +20,8 @@ dependencies { compileOnly("org.testcontainers:kafka") compileOnly("org.testcontainers:mongodb") + implementation("org.springframework.boot:spring-boot-starter-aop") + api(project(":smoke-tests-otel-starter:spring-smoke-testing")) implementation("io.opentelemetry:opentelemetry-extension-trace-propagators") diff --git a/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/AbstractOtelSpringStarterSmokeTest.java b/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/AbstractOtelSpringStarterSmokeTest.java index ec9af70ca329..aadf8d566612 100644 --- a/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/AbstractOtelSpringStarterSmokeTest.java +++ b/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/AbstractOtelSpringStarterSmokeTest.java @@ -175,7 +175,10 @@ void shouldSendTelemetry() { equalTo(ClientAttributes.CLIENT_ADDRESS, "127.0.0.1"), satisfies( ServerAttributes.SERVER_PORT, - integerAssert -> integerAssert.isNotZero())))); + integerAssert -> integerAssert.isNotZero())), + span -> + span.hasName("SpringComponent.withSpanMethod") + .hasAttribute(AttributeKey.stringKey("paramName"), "from-controller"))); // Metric testing.waitAndAssertMetrics( @@ -236,8 +239,8 @@ void restTemplate() { traceAssert.hasSpansSatisfyingExactly( span -> assertClientSpan(span, "/ping"), span -> - span.hasKind(SpanKind.SERVER) - .hasAttribute(HttpAttributes.HTTP_ROUTE, "/ping"))); + span.hasKind(SpanKind.SERVER).hasAttribute(HttpAttributes.HTTP_ROUTE, "/ping"), + span -> span.hasName("SpringComponent.withSpanMethod"))); } public static void assertClientSpan(SpanDataAssert span, String path) { diff --git a/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTestController.java b/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTestController.java index 891666797bf6..7d02c29d5fc1 100644 --- a/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTestController.java +++ b/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/OtelSpringStarterSmokeTestController.java @@ -20,15 +20,19 @@ public class OtelSpringStarterSmokeTestController { public static final String TEST_HISTOGRAM = "histogram-test-otel-spring-starter"; public static final String METER_SCOPE_NAME = "scope"; private final LongHistogram histogram; + private final SpringComponent component; - public OtelSpringStarterSmokeTestController(OpenTelemetry openTelemetry) { + public OtelSpringStarterSmokeTestController( + OpenTelemetry openTelemetry, SpringComponent springComponent) { Meter meter = openTelemetry.getMeter(METER_SCOPE_NAME); histogram = meter.histogramBuilder(TEST_HISTOGRAM).ofLongs().build(); + this.component = springComponent; } @GetMapping(PING) public String ping() { histogram.record(10); + component.withSpanMethod("from-controller"); return "pong"; } } diff --git a/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/SpringComponent.java b/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/SpringComponent.java new file mode 100644 index 000000000000..9c9e40c3fea4 --- /dev/null +++ b/smoke-tests-otel-starter/spring-boot-common/src/main/java/io/opentelemetry/spring/smoketest/SpringComponent.java @@ -0,0 +1,18 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.spring.smoketest; + +import io.opentelemetry.instrumentation.annotations.SpanAttribute; +import io.opentelemetry.instrumentation.annotations.WithSpan; +import org.springframework.stereotype.Component; + +@Component +public class SpringComponent { + + @SuppressWarnings("MethodCanBeStatic") + @WithSpan() + public void withSpanMethod(@SpanAttribute String paramName) {} +}