diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-api.txt index d1692462b6fd..c5846e2d2586 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-api.txt @@ -1,2 +1,10 @@ Comparing source compatibility of opentelemetry-instrumentation-api-2.15.0-SNAPSHOT.jar against opentelemetry-instrumentation-api-2.14.0.jar -No changes. \ No newline at end of file +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesGetter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + GENERIC TEMPLATES: === REQUEST:java.lang.Object, === RESPONSE:java.lang.Object + +++ NEW INTERFACE: io.opentelemetry.instrumentation.api.semconv.url.UrlAttributesGetter +*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.instrumentation.api.semconv.url.UrlAttributesGetter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + GENERIC TEMPLATES: === REQUEST:java.lang.Object + +++ NEW METHOD: PUBLIC(+) java.lang.String getUrlTemplate(java.lang.Object) + +++ NEW ANNOTATION: javax.annotation.Nullable diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/semconv/http/HttpClientAttributesGetter.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/semconv/http/HttpClientAttributesGetter.java index d81eb582f2a0..e0e7533ebd14 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/semconv/http/HttpClientAttributesGetter.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/semconv/http/HttpClientAttributesGetter.java @@ -7,6 +7,7 @@ import io.opentelemetry.instrumentation.api.semconv.network.NetworkAttributesGetter; import io.opentelemetry.instrumentation.api.semconv.network.ServerAttributesGetter; +import io.opentelemetry.instrumentation.api.semconv.url.UrlAttributesGetter; import javax.annotation.Nullable; /** @@ -21,7 +22,8 @@ public interface HttpClientAttributesGetter extends HttpCommonAttributesGetter, NetworkAttributesGetter, - ServerAttributesGetter { + ServerAttributesGetter, + UrlAttributesGetter { /** * Returns the absolute URL describing a network resource according to Examples: {@code /users/{id}}; {@code /users?q={query}} + */ + @Nullable + default String getUrlTemplate(REQUEST request) { + return null; + } } diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/semconv/url/internal/InternalUrlAttributesExtractor.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/semconv/url/internal/InternalUrlAttributesExtractor.java index 37103b0c6983..f259c8ab80ee 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/semconv/url/internal/InternalUrlAttributesExtractor.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/semconv/url/internal/InternalUrlAttributesExtractor.java @@ -7,6 +7,7 @@ import static io.opentelemetry.instrumentation.api.internal.AttributesExtractorUtil.internalSet; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.instrumentation.api.semconv.url.UrlAttributesGetter; import io.opentelemetry.semconv.UrlAttributes; @@ -31,10 +32,12 @@ public void onStart(AttributesBuilder attributes, REQUEST request) { String urlScheme = getUrlScheme(request); String urlPath = getter.getUrlPath(request); String urlQuery = getter.getUrlQuery(request); + String urlTemplate = getter.getUrlTemplate(request); internalSet(attributes, UrlAttributes.URL_SCHEME, urlScheme); internalSet(attributes, UrlAttributes.URL_PATH, urlPath); internalSet(attributes, UrlAttributes.URL_QUERY, urlQuery); + internalSet(attributes, AttributeKey.stringKey("url.template"), urlTemplate); } private String getUrlScheme(REQUEST request) { diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/semconv/http/HttpSpanNameExtractorTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/semconv/http/HttpSpanNameExtractorTest.java index 0c59545984a2..51adf205c52b 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/semconv/http/HttpSpanNameExtractorTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/semconv/http/HttpSpanNameExtractorTest.java @@ -46,4 +46,12 @@ void nothing() { assertThat(HttpSpanNameExtractor.create(clientGetter).extract(Collections.emptyMap())) .isEqualTo("HTTP"); } + + @Test + void templateAndMethod() { + when(clientGetter.getUrlTemplate(anyMap())).thenReturn("/cats/{id}"); + when(clientGetter.getHttpRequestMethod(anyMap())).thenReturn("GET"); + assertThat(HttpSpanNameExtractor.create(clientGetter).extract(Collections.emptyMap())) + .isEqualTo("GET /cats/{id}"); + } } diff --git a/instrumentation/ktor/ktor-2-common/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/common/KtorHttpClientAttributesGetter.kt b/instrumentation/ktor/ktor-2-common/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/common/KtorHttpClientAttributesGetter.kt index 64df11c673e6..0f624158b04e 100644 --- a/instrumentation/ktor/ktor-2-common/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/common/KtorHttpClientAttributesGetter.kt +++ b/instrumentation/ktor/ktor-2-common/library/src/main/kotlin/io/opentelemetry/instrumentation/ktor/v2_0/common/KtorHttpClientAttributesGetter.kt @@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.ktor.v2_0.common import io.ktor.client.request.* import io.ktor.client.statement.* +import io.ktor.util.AttributeKey import io.opentelemetry.instrumentation.api.semconv.http.HttpClientAttributesGetter internal object KtorHttpClientAttributesGetter : HttpClientAttributesGetter { @@ -34,4 +35,7 @@ internal object KtorHttpClientAttributesGetter : HttpClientAttributesGetter("URL_TEMPLATE") + override fun getUrlTemplate(request: HttpRequestData): String? = request.attributes.getOrNull(urlTemplateAttributeKey) }