Skip to content
Draft
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
Expand Up @@ -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<HttpRequest, ClientHttpResponse> {
implements HttpClientExperimentalAttributesGetter<HttpRequest, ClientHttpResponse> {
INSTANCE;

@Override
Expand Down Expand Up @@ -107,4 +108,55 @@ 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
}
Comment on lines +120 to +124
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need to forName this class as it must be present.


if (httpRequestClass != null) {
MethodHandles.Lookup lookup = MethodHandles.publicLookup();
try {
getAttributes =
lookup.findVirtual(
httpRequestClass, "getAttributes", MethodType.methodType(java.util.Map.class));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could import java.util.Map

} 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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,39 @@

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.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<ClientRequest, ClientResponse> {
implements HttpClientExperimentalAttributesGetter<ClientRequest, ClientResponse> {
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<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 getUrlFull(ClientRequest request) {
return request.url().toString();
Expand Down
Loading