Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
Comparing source compatibility of against
No changes.
***! 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 METHOD: PUBLIC(+) java.lang.String getHttpRoute(java.lang.Object)
+++ NEW ANNOTATION: javax.annotation.Nullable
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ public void onStart(AttributesBuilder attributes, Context parentContext, REQUEST
String fullUrl = stripSensitiveData(getter.getUrlFull(request));
internalSet(attributes, SemanticAttributes.URL_FULL, fullUrl);

String httpRoute = getter.getHttpRoute(request);
if (httpRoute != null && !httpRoute.isEmpty()) {
internalSet(attributes, SemanticAttributes.HTTP_ROUTE, httpRoute);
}

int resendCount = resendCountIncrementer.applyAsInt(parentContext);
if (resendCount > 0) {
attributes.put(SemanticAttributes.HTTP_REQUEST_RESEND_COUNT, resendCount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@ public interface HttpClientAttributesGetter<REQUEST, RESPONSE>
@Nullable
String getUrlFull(REQUEST request);

/**
* Returns the path template in the format used by the respective client framework.
*
* <p>Examples: <code>/foo/{bar}</code>
*/
@Nullable
default String getHttpRoute(REQUEST request) {
return null;
}

/** {@inheritDoc} */
@Nullable
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ static void applyClientDurationAdvice(DoubleHistogramBuilder builder) {
((ExtendedDoubleHistogramBuilder) builder)
.setAttributesAdvice(
asList(
SemanticAttributes.HTTP_ROUTE,
SemanticAttributes.HTTP_REQUEST_METHOD,
SemanticAttributes.HTTP_RESPONSE_STATUS_CODE,
SemanticAttributes.ERROR_TYPE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ public String getUrlFull(Map<String, String> request) {
return request.get("urlFull");
}

@Nullable
@Override
public String getHttpRoute(Map<String, String> request) {
return request.get("httpRoute");
}

@Override
public String getHttpRequestMethod(Map<String, String> request) {
return request.get("method");
Expand Down Expand Up @@ -138,6 +144,7 @@ void normal() {
Map<String, String> request = new HashMap<>();
request.put("method", "POST");
request.put("urlFull", "http://github.com");
request.put("httpRoute", "/api");
request.put("header.content-length", "10");
request.put("header.user-agent", "okhttp 3.x");
request.put("header.custom-request-header", "123,456");
Expand Down Expand Up @@ -170,6 +177,7 @@ void normal() {
.containsOnly(
entry(SemanticAttributes.HTTP_REQUEST_METHOD, "POST"),
entry(SemanticAttributes.URL_FULL, "http://github.com"),
entry(SemanticAttributes.HTTP_ROUTE, "/api"),
entry(
AttributeKey.stringArrayKey("http.request.header.custom-request-header"),
asList("123", "456")),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@

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
Expand All @@ -21,11 +24,27 @@ public enum WebClientHttpAttributesGetter
implements HttpClientAttributesGetter<ClientRequest, ClientResponse> {
INSTANCE;

private static final String URI_TEMPLATE_ATTRIBUTE = WebClient.class.getName() + ".uriTemplate";
private static final Pattern PATTERN_BEFORE_PATH = Pattern.compile("^https?://[^/]+/");

@Override
public String getUrlFull(ClientRequest request) {
return request.url().toString();
}

@Nullable
@Override
public String getHttpRoute(ClientRequest clientRequest) {
Map<String, Object> 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 getHttpRequestMethod(ClientRequest request) {
return request.method().name();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.lang.invoke.MethodType;
import java.net.URI;
import java.time.Duration;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
Expand All @@ -44,7 +45,7 @@ public WebClient.RequestBodySpec buildRequest(

return webClient
.method(HttpMethod.valueOf(method))
.uri(uri)
.uri(uri.toString(), Collections.emptyMap())
.headers(h -> headers.forEach(h::add));
}

Expand Down Expand Up @@ -182,6 +183,7 @@ void shouldEndSpanOnMonoTimeout() {
.hasAttributesSatisfyingExactly(
equalTo(SemanticAttributes.HTTP_REQUEST_METHOD, "GET"),
equalTo(SemanticAttributes.URL_FULL, uri.toString()),
equalTo(SemanticAttributes.HTTP_ROUTE, uri.getPath()),
equalTo(SemanticAttributes.SERVER_ADDRESS, "localhost"),
equalTo(SemanticAttributes.SERVER_PORT, uri.getPort()),
equalTo(SemanticAttributes.ERROR_TYPE, "cancelled")),
Expand Down