From 71fdb863b4ff2bed1159a3618647127c47fe504f Mon Sep 17 00:00:00 2001 From: Michael Munch Date: Tue, 26 Aug 2025 20:05:15 +0200 Subject: [PATCH 1/4] Added url template --- .../WebClientHttpAttributesGetter.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java index 80c75f68a61d..387c6f3696e1 100644 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java @@ -7,20 +7,41 @@ import static java.util.Collections.emptyList; +import io.opentelemetry.instrumentation.api.incubator.semconv.http.HttpClientExperimentalAttributesGetter; import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesGetter; import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; import javax.annotation.Nullable; import org.springframework.web.reactive.function.client.ClientRequest; import org.springframework.web.reactive.function.client.ClientResponse; +import org.springframework.web.reactive.function.client.WebClient; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. */ public enum WebClientHttpAttributesGetter - implements HttpClientAttributesGetter { + implements HttpClientExperimentalAttributesGetter { INSTANCE; + + private static final String URI_TEMPLATE_ATTRIBUTE = WebClient.class.getName() + ".uriTemplate"; + private static final Pattern PATTERN_BEFORE_PATH = Pattern.compile("^https?://[^/]+/"); + + @Nullable + @Override + public String getUrlTemplate(ClientRequest clientRequest) { + Map attributes = clientRequest.attributes(); + Object value = attributes.get(URI_TEMPLATE_ATTRIBUTE); + if (value instanceof String) { + String uriTemplate = (String) value; + String path = PATTERN_BEFORE_PATH.matcher(uriTemplate).replaceFirst(""); + return path.startsWith("/") ? path : "/" + path; + } + return null; + } + @Override public String getUrlFull(ClientRequest request) { return request.url().toString(); @@ -71,4 +92,6 @@ public String getErrorType( } return null; } + + } From a7b5a6fd4bef7e290fe411a273465066bf6f28fa Mon Sep 17 00:00:00 2001 From: Michael Munch Date: Wed, 27 Aug 2025 13:43:42 +0200 Subject: [PATCH 2/4] Remove missing import --- .../webflux/v5_3/internal/WebClientHttpAttributesGetter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java index 387c6f3696e1..3e0a661ab1a9 100644 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java @@ -8,7 +8,6 @@ import static java.util.Collections.emptyList; import io.opentelemetry.instrumentation.api.incubator.semconv.http.HttpClientExperimentalAttributesGetter; -import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesGetter; import java.util.List; import java.util.Map; import java.util.regex.Pattern; From bf02f732802c8969db73da74b7b8bfc2980ca41a Mon Sep 17 00:00:00 2001 From: Michael Munch Date: Wed, 27 Aug 2025 13:44:07 +0200 Subject: [PATCH 3/4] RestClient implement getUrlTemplate --- .../v3_1/SpringWebHttpAttributesGetter.java | 57 ++++++++++++++++++- 1 file changed, 55 insertions(+), 2 deletions(-) diff --git a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java index b61433ddaa44..b6d7afdbf335 100644 --- a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java +++ b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java @@ -7,17 +7,18 @@ import static java.util.Collections.emptyList; -import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesGetter; +import io.opentelemetry.instrumentation.api.incubator.semconv.http.HttpClientExperimentalAttributesGetter; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.util.List; +import java.util.Map; import javax.annotation.Nullable; import org.springframework.http.HttpRequest; import org.springframework.http.client.ClientHttpResponse; enum SpringWebHttpAttributesGetter - implements HttpClientAttributesGetter { + implements HttpClientExperimentalAttributesGetter { INSTANCE; @Override @@ -107,4 +108,56 @@ public String getServerAddress(HttpRequest httpRequest) { public Integer getServerPort(HttpRequest httpRequest) { return httpRequest.getURI().getPort(); } + + private static final String URI_TEMPLATE_ATTRIBUTE = "org.springframework.web.client.RestClient.uriTemplate"; + @Nullable private static final MethodHandle GET_ATTRIBUTES; + + static { + MethodHandle getAttributes = null; + Class httpRequestClass = null; + + try { + httpRequestClass = Class.forName("org.springframework.http.HttpRequest"); + } catch (ClassNotFoundException e) { + // ignored + } + + if (httpRequestClass != null) { + MethodHandles.Lookup lookup = MethodHandles.publicLookup(); + try { + getAttributes = + lookup.findVirtual( + httpRequestClass, + "getAttributes", + MethodType.methodType(java.util.Map.class)); + } catch (NoSuchMethodException | IllegalAccessException ignored) { + // ignored + } + } + + GET_ATTRIBUTES = getAttributes; + } + + @Nullable + @Override + public String getUrlTemplate(HttpRequest httpRequest) { + if (GET_ATTRIBUTES == null) { + return null; + } + + try { + Object attributes = GET_ATTRIBUTES.invoke(httpRequest); + if (attributes instanceof java.util.Map) { + Map map = (Map) attributes; + Object value = map.get(URI_TEMPLATE_ATTRIBUTE); + if (value instanceof String) { + return (String) value; + } + } + } catch (Throwable e) { + // ignore + } + + return null; + } } From b3391952327d19e26acf8acfe29c3ea4418fd3b9 Mon Sep 17 00:00:00 2001 From: otelbot <197425009+otelbot@users.noreply.github.com> Date: Wed, 27 Aug 2025 11:55:33 +0000 Subject: [PATCH 4/4] ./gradlew spotlessApply --- .../spring/web/v3_1/SpringWebHttpAttributesGetter.java | 7 +++---- .../v5_3/internal/WebClientHttpAttributesGetter.java | 3 --- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java index b6d7afdbf335..4660f06a9be7 100644 --- a/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java +++ b/instrumentation/spring/spring-web/spring-web-3.1/library/src/main/java/io/opentelemetry/instrumentation/spring/web/v3_1/SpringWebHttpAttributesGetter.java @@ -109,7 +109,8 @@ public Integer getServerPort(HttpRequest httpRequest) { return httpRequest.getURI().getPort(); } - private static final String URI_TEMPLATE_ATTRIBUTE = "org.springframework.web.client.RestClient.uriTemplate"; + private static final String URI_TEMPLATE_ATTRIBUTE = + "org.springframework.web.client.RestClient.uriTemplate"; @Nullable private static final MethodHandle GET_ATTRIBUTES; static { @@ -127,9 +128,7 @@ public Integer getServerPort(HttpRequest httpRequest) { try { getAttributes = lookup.findVirtual( - httpRequestClass, - "getAttributes", - MethodType.methodType(java.util.Map.class)); + httpRequestClass, "getAttributes", MethodType.methodType(java.util.Map.class)); } catch (NoSuchMethodException | IllegalAccessException ignored) { // ignored } diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java index 3e0a661ab1a9..226c759373b4 100644 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.3/library/src/main/java/io/opentelemetry/instrumentation/spring/webflux/v5_3/internal/WebClientHttpAttributesGetter.java @@ -24,7 +24,6 @@ public enum WebClientHttpAttributesGetter implements HttpClientExperimentalAttributesGetter { INSTANCE; - private static final String URI_TEMPLATE_ATTRIBUTE = WebClient.class.getName() + ".uriTemplate"; private static final Pattern PATTERN_BEFORE_PATH = Pattern.compile("^https?://[^/]+/"); @@ -91,6 +90,4 @@ public String getErrorType( } return null; } - - }