OTEL: Use suggested 'code.function.name' for span attributes

Closes #45944

Signed-off-by: Martin Bartoš <mabartos@redhat.com>
Co-authored-by: Alexander Schwartz <alexander.schwartz@gmx.net>
This commit is contained in:
Martin Bartoš 2026-02-03 15:56:48 +01:00 committed by GitHub
parent e3c4ec6112
commit 3e568fc81b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 16 additions and 2 deletions

View file

@ -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

View file

@ -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());

View file

@ -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"));
});
}