From 3e568fc81b922a1308746d8cd6ee2e3ae351d090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Barto=C5=A1?= Date: Tue, 3 Feb 2026 15:56:48 +0100 Subject: [PATCH] OTEL: Use suggested 'code.function.name' for span attributes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #45944 Signed-off-by: Martin Bartoš Co-authored-by: Alexander Schwartz --- .../upgrading/topics/changes/changes-26_6_0.adoc | 8 +++++++- .../integration/resteasy/KeycloakTracingCustomizer.java | 8 +++++++- .../org/keycloak/tests/tracing/TracingProviderTest.java | 2 ++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/docs/documentation/upgrading/topics/changes/changes-26_6_0.adoc b/docs/documentation/upgrading/topics/changes/changes-26_6_0.adoc index 4308da0ebd3..a32ad9dc87f 100644 --- a/docs/documentation/upgrading/topics/changes/changes-26_6_0.adoc +++ b/docs/documentation/upgrading/topics/changes/changes-26_6_0.adoc @@ -22,7 +22,8 @@ It also lists significant changes to internal APIs. === Dev Mode defaults to localhost -When running the server in dev mode on a platform other than Windows Subsystem For Linux, the `http-host` setting will default to localhost. This ensures your dev instance won't be accessible from +When running the server in dev mode on a platform other than Windows Subsystem For Linux, the `http-host` setting will default to localhost. +This ensures your dev instance won't be accessible from other machines. If you want the previous behavior of binding to all interfaces, then explicitly set `http-host` to `0.0.0.0`. === `X-Forwarded-Prefix` Header is now supported @@ -115,6 +116,11 @@ The following sections provide details on deprecated features. The `tracing.serviceName`, and `tracing.resourceAttributes` fields of the Keycloak CR, are now deprecated. You should use the new `telemetry.serviceName`, and `telemetry.resourceAttributes` fields that are shared among all OpenTelemetry components - logs, metrics, and traces. +=== Deprecation of tracing span attributes for HTTP requests + +The OpenTelemetry tracing span attributes `code.function` and `code.namespace` are deprecated for the HTTP request spans when tracing is enabled. +These attributes will be removed in the next major release, and only the fully qualified `code.function.name` span attribute will stay. + // ------------------------ Removed features ------------------------ // == Removed features diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/integration/resteasy/KeycloakTracingCustomizer.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/integration/resteasy/KeycloakTracingCustomizer.java index 6f005191a5d..ed90c30cab0 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/integration/resteasy/KeycloakTracingCustomizer.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/integration/resteasy/KeycloakTracingCustomizer.java @@ -30,6 +30,7 @@ import io.opentelemetry.api.trace.SpanBuilder; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; +import io.opentelemetry.semconv.CodeAttributes; import io.opentelemetry.semconv.incubating.CodeIncubatingAttributes; import org.apache.commons.lang3.StringUtils; import org.jboss.resteasy.reactive.common.model.ResourceClass; @@ -44,11 +45,13 @@ public final class KeycloakTracingCustomizer implements HandlerChainCustomizer { private final String className; private final String methodName; private final String spanName; + private final String functionName; public StartHandler(String className, String methodName) { this.className = className; this.methodName = methodName; this.spanName = StringUtils.substringAfterLast(className, ".") + "." + methodName; + this.functionName = className + "." + methodName; } @Override @@ -60,9 +63,12 @@ public final class KeycloakTracingCustomizer implements HandlerChainCustomizer { Tracer myTracer = openTelemetry.getTracer(this.getClass().getName(), Version.VERSION); SpanBuilder spanBuilder = myTracer.spanBuilder(spanName); spanBuilder.setParent(Context.current().with(Span.current())); - // for semconv >= 1.32 use CODE_FUNCTION_NAME instead + spanBuilder.setAttribute(CodeAttributes.CODE_FUNCTION_NAME, functionName); + // for backwards compatibility. deprecated in 26.6, to be removed in 27.0 spanBuilder.setAttribute(CodeIncubatingAttributes.CODE_FUNCTION, methodName); spanBuilder.setAttribute(CodeIncubatingAttributes.CODE_NAMESPACE, className); + // end deprecation + Span span = spanBuilder.startSpan(); requestContext.setProperty("span", span); requestContext.setProperty("scope", span.makeCurrent()); diff --git a/tests/base/src/test/java/org/keycloak/tests/tracing/TracingProviderTest.java b/tests/base/src/test/java/org/keycloak/tests/tracing/TracingProviderTest.java index e5223c4f4cf..aac67cf0803 100644 --- a/tests/base/src/test/java/org/keycloak/tests/tracing/TracingProviderTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/tracing/TracingProviderTest.java @@ -17,6 +17,7 @@ import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.data.ExceptionEventData; import io.opentelemetry.sdk.trace.data.StatusData; +import io.opentelemetry.semconv.CodeAttributes; import io.opentelemetry.semconv.ExceptionAttributes; import org.junit.jupiter.api.Test; @@ -42,6 +43,7 @@ public class TracingProviderTest { ReadableSpan readableSpan = (ReadableSpan) current; assertThat(readableSpan.getAttribute(AttributeKey.stringKey("code.function")), is("runOnServer")); assertThat(readableSpan.getAttribute(AttributeKey.stringKey("code.namespace")), is("org.keycloak.testframework.remote.providers.runonserver.RunOnServerRealmResourceProvider")); + assertThat(readableSpan.getAttribute(CodeAttributes.CODE_FUNCTION_NAME), is("org.keycloak.testframework.remote.providers.runonserver.RunOnServerRealmResourceProvider.runOnServer")); assertThat(readableSpan.getName(), is("RunOnServerRealmResourceProvider.runOnServer")); }); }