Convert play-ws to instrumenter api (#3944)

This commit is contained in:
Lauri Tulmin 2021-08-25 19:31:50 +03:00 committed by GitHub
parent 564f51c706
commit 629801d9ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 283 additions and 130 deletions

View File

@ -5,7 +5,7 @@
package io.opentelemetry.javaagent.instrumentation.playws.v1_0;
import static io.opentelemetry.javaagent.instrumentation.playws.PlayWsClientTracer.tracer;
import static io.opentelemetry.javaagent.instrumentation.playws.PlayWsClientSingletons.instrumenter;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
@ -13,17 +13,21 @@ import play.shaded.ahc.org.asynchttpclient.AsyncHandler;
import play.shaded.ahc.org.asynchttpclient.HttpResponseBodyPart;
import play.shaded.ahc.org.asynchttpclient.HttpResponseHeaders;
import play.shaded.ahc.org.asynchttpclient.HttpResponseStatus;
import play.shaded.ahc.org.asynchttpclient.Request;
import play.shaded.ahc.org.asynchttpclient.Response;
public class AsyncHandlerWrapper implements AsyncHandler {
private final AsyncHandler delegate;
private final Request request;
private final Context context;
private final Context parentContext;
private final Response.ResponseBuilder builder = new Response.ResponseBuilder();
public AsyncHandlerWrapper(AsyncHandler delegate, Context context, Context parentContext) {
public AsyncHandlerWrapper(
AsyncHandler delegate, Request request, Context context, Context parentContext) {
this.delegate = delegate;
this.request = request;
this.context = context;
this.parentContext = parentContext;
}
@ -53,7 +57,7 @@ public class AsyncHandlerWrapper implements AsyncHandler {
@Override
public Object onCompleted() throws Exception {
tracer().end(context, builder.build());
instrumenter().end(context, request, builder.build(), null);
try (Scope ignored = parentContext.makeCurrent()) {
return delegate.onCompleted();
@ -62,7 +66,7 @@ public class AsyncHandlerWrapper implements AsyncHandler {
@Override
public void onThrowable(Throwable throwable) {
tracer().endExceptionally(context, throwable);
instrumenter().end(context, request, null, throwable);
try (Scope ignored = parentContext.makeCurrent()) {
delegate.onThrowable(throwable);

View File

@ -6,7 +6,7 @@
package io.opentelemetry.javaagent.instrumentation.playws.v1_0;
import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext;
import static io.opentelemetry.javaagent.instrumentation.playws.PlayWsClientTracer.tracer;
import static io.opentelemetry.javaagent.instrumentation.playws.PlayWsClientSingletons.instrumenter;
import static java.util.Arrays.asList;
import com.google.auto.service.AutoService;
@ -47,25 +47,26 @@ public class PlayWsInstrumentationModule extends InstrumentationModule {
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
Context parentContext = currentContext();
if (!tracer().shouldStartSpan(parentContext)) {
if (!instrumenter().shouldStart(parentContext, request)) {
return;
}
context = tracer().startSpan(parentContext, request, request.getHeaders());
context = instrumenter().start(parentContext, request);
scope = context.makeCurrent();
if (asyncHandler instanceof StreamedAsyncHandler) {
asyncHandler =
new StreamedAsyncHandlerWrapper(
(StreamedAsyncHandler<?>) asyncHandler, context, parentContext);
(StreamedAsyncHandler<?>) asyncHandler, request, context, parentContext);
} else if (!(asyncHandler instanceof WebSocketUpgradeHandler)) {
// websocket upgrade handlers aren't supported
asyncHandler = new AsyncHandlerWrapper(asyncHandler, context, parentContext);
asyncHandler = new AsyncHandlerWrapper(asyncHandler, request, context, parentContext);
}
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void methodExit(
@Advice.Argument(0) Request request,
@Advice.Thrown Throwable throwable,
@Advice.Local("otelContext") Context context,
@Advice.Local("otelScope") Scope scope) {
@ -75,7 +76,7 @@ public class PlayWsInstrumentationModule extends InstrumentationModule {
scope.close();
if (throwable != null) {
tracer().endExceptionally(context, throwable);
instrumenter().end(context, request, null, throwable);
}
}
}

View File

@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.playws.v1_0;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import org.reactivestreams.Publisher;
import play.shaded.ahc.org.asynchttpclient.Request;
import play.shaded.ahc.org.asynchttpclient.handler.StreamedAsyncHandler;
public class StreamedAsyncHandlerWrapper extends AsyncHandlerWrapper
@ -15,8 +16,8 @@ public class StreamedAsyncHandlerWrapper extends AsyncHandlerWrapper
private final StreamedAsyncHandler streamedDelegate;
public StreamedAsyncHandlerWrapper(
StreamedAsyncHandler delegate, Context context, Context parentContext) {
super(delegate, context, parentContext);
StreamedAsyncHandler delegate, Request request, Context context, Context parentContext) {
super(delegate, request, context, parentContext);
streamedDelegate = delegate;
}

View File

@ -5,7 +5,7 @@
package io.opentelemetry.javaagent.instrumentation.playws.v2_0;
import static io.opentelemetry.javaagent.instrumentation.playws.PlayWsClientTracer.tracer;
import static io.opentelemetry.javaagent.instrumentation.playws.PlayWsClientSingletons.instrumenter;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
@ -16,18 +16,22 @@ import play.shaded.ahc.io.netty.handler.codec.http.HttpHeaders;
import play.shaded.ahc.org.asynchttpclient.AsyncHandler;
import play.shaded.ahc.org.asynchttpclient.HttpResponseBodyPart;
import play.shaded.ahc.org.asynchttpclient.HttpResponseStatus;
import play.shaded.ahc.org.asynchttpclient.Request;
import play.shaded.ahc.org.asynchttpclient.Response;
import play.shaded.ahc.org.asynchttpclient.netty.request.NettyRequest;
public class AsyncHandlerWrapper implements AsyncHandler {
private final AsyncHandler delegate;
private final Request request;
private final Context context;
private final Context parentContext;
private final Response.ResponseBuilder builder = new Response.ResponseBuilder();
public AsyncHandlerWrapper(AsyncHandler delegate, Context context, Context parentContext) {
public AsyncHandlerWrapper(
AsyncHandler delegate, Request request, Context context, Context parentContext) {
this.delegate = delegate;
this.request = request;
this.context = context;
this.parentContext = parentContext;
}
@ -58,7 +62,7 @@ public class AsyncHandlerWrapper implements AsyncHandler {
@Override
public Object onCompleted() throws Exception {
Response response = builder.build();
tracer().end(context, response);
instrumenter().end(context, request, response, null);
try (Scope ignored = parentContext.makeCurrent()) {
return delegate.onCompleted();
@ -67,7 +71,7 @@ public class AsyncHandlerWrapper implements AsyncHandler {
@Override
public void onThrowable(Throwable throwable) {
tracer().endExceptionally(context, throwable);
instrumenter().end(context, request, null, throwable);
try (Scope ignored = parentContext.makeCurrent()) {
delegate.onThrowable(throwable);

View File

@ -6,7 +6,7 @@
package io.opentelemetry.javaagent.instrumentation.playws.v2_0;
import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext;
import static io.opentelemetry.javaagent.instrumentation.playws.PlayWsClientTracer.tracer;
import static io.opentelemetry.javaagent.instrumentation.playws.PlayWsClientSingletons.instrumenter;
import static java.util.Arrays.asList;
import com.google.auto.service.AutoService;
@ -44,27 +44,29 @@ public class PlayWsInstrumentationModule extends InstrumentationModule {
@Advice.Argument(value = 1, readOnly = false) AsyncHandler<?> asyncHandler,
@Advice.Local("otelContext") Context context) {
Context parentContext = currentContext();
if (!tracer().shouldStartSpan(parentContext)) {
if (!instrumenter().shouldStart(parentContext, request)) {
return;
}
context = tracer().startSpan(parentContext, request, request.getHeaders());
context = instrumenter().start(parentContext, request);
if (asyncHandler instanceof StreamedAsyncHandler) {
asyncHandler =
new StreamedAsyncHandlerWrapper(
(StreamedAsyncHandler<?>) asyncHandler, context, parentContext);
(StreamedAsyncHandler<?>) asyncHandler, request, context, parentContext);
} else if (!(asyncHandler instanceof WebSocketUpgradeHandler)) {
// websocket upgrade handlers aren't supported
asyncHandler = new AsyncHandlerWrapper(asyncHandler, context, parentContext);
asyncHandler = new AsyncHandlerWrapper(asyncHandler, request, context, parentContext);
}
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void methodExit(
@Advice.Thrown Throwable throwable, @Advice.Local("otelContext") Context context) {
@Advice.Argument(0) Request request,
@Advice.Thrown Throwable throwable,
@Advice.Local("otelContext") Context context) {
if (context != null && throwable != null) {
tracer().endExceptionally(context, throwable);
instrumenter().end(context, request, null, throwable);
}
}
}

View File

@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.playws.v2_0;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import org.reactivestreams.Publisher;
import play.shaded.ahc.org.asynchttpclient.Request;
import play.shaded.ahc.org.asynchttpclient.handler.StreamedAsyncHandler;
public class StreamedAsyncHandlerWrapper extends AsyncHandlerWrapper
@ -15,8 +16,8 @@ public class StreamedAsyncHandlerWrapper extends AsyncHandlerWrapper
private final StreamedAsyncHandler streamedDelegate;
public StreamedAsyncHandlerWrapper(
StreamedAsyncHandler delegate, Context context, Context parentContext) {
super(delegate, context, parentContext);
StreamedAsyncHandler delegate, Request request, Context context, Context parentContext) {
super(delegate, request, context, parentContext);
streamedDelegate = delegate;
}

View File

@ -5,7 +5,7 @@
package io.opentelemetry.javaagent.instrumentation.playws.v2_1;
import static io.opentelemetry.javaagent.instrumentation.playws.PlayWsClientTracer.tracer;
import static io.opentelemetry.javaagent.instrumentation.playws.PlayWsClientSingletons.instrumenter;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
@ -17,18 +17,22 @@ import play.shaded.ahc.io.netty.handler.codec.http.HttpHeaders;
import play.shaded.ahc.org.asynchttpclient.AsyncHandler;
import play.shaded.ahc.org.asynchttpclient.HttpResponseBodyPart;
import play.shaded.ahc.org.asynchttpclient.HttpResponseStatus;
import play.shaded.ahc.org.asynchttpclient.Request;
import play.shaded.ahc.org.asynchttpclient.Response;
import play.shaded.ahc.org.asynchttpclient.netty.request.NettyRequest;
public class AsyncHandlerWrapper implements AsyncHandler {
private final AsyncHandler delegate;
private final Request request;
private final Context context;
private final Context parentContext;
private final Response.ResponseBuilder builder = new Response.ResponseBuilder();
public AsyncHandlerWrapper(AsyncHandler delegate, Context context, Context parentContext) {
public AsyncHandlerWrapper(
AsyncHandler delegate, Request request, Context context, Context parentContext) {
this.delegate = delegate;
this.request = request;
this.context = context;
this.parentContext = parentContext;
}
@ -59,7 +63,7 @@ public class AsyncHandlerWrapper implements AsyncHandler {
@Override
public Object onCompleted() throws Exception {
Response response = builder.build();
tracer().end(context, response);
instrumenter().end(context, request, response, null);
try (Scope ignored = parentContext.makeCurrent()) {
return delegate.onCompleted();
@ -68,7 +72,7 @@ public class AsyncHandlerWrapper implements AsyncHandler {
@Override
public void onThrowable(Throwable throwable) {
tracer().endExceptionally(context, throwable);
instrumenter().end(context, request, null, throwable);
try (Scope ignored = parentContext.makeCurrent()) {
delegate.onThrowable(throwable);

View File

@ -6,7 +6,7 @@
package io.opentelemetry.javaagent.instrumentation.playws.v2_1;
import static io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge.currentContext;
import static io.opentelemetry.javaagent.instrumentation.playws.PlayWsClientTracer.tracer;
import static io.opentelemetry.javaagent.instrumentation.playws.PlayWsClientSingletons.instrumenter;
import static java.util.Arrays.asList;
import com.google.auto.service.AutoService;
@ -44,27 +44,29 @@ public class PlayWsInstrumentationModule extends InstrumentationModule {
@Advice.Argument(value = 1, readOnly = false) AsyncHandler<?> asyncHandler,
@Advice.Local("otelContext") Context context) {
Context parentContext = currentContext();
if (!tracer().shouldStartSpan(parentContext)) {
if (!instrumenter().shouldStart(parentContext, request)) {
return;
}
context = tracer().startSpan(parentContext, request, request.getHeaders());
context = instrumenter().start(parentContext, request);
if (asyncHandler instanceof StreamedAsyncHandler) {
asyncHandler =
new StreamedAsyncHandlerWrapper(
(StreamedAsyncHandler<?>) asyncHandler, context, parentContext);
(StreamedAsyncHandler<?>) asyncHandler, request, context, parentContext);
} else if (!(asyncHandler instanceof WebSocketUpgradeHandler)) {
// websocket upgrade handlers aren't supported
asyncHandler = new AsyncHandlerWrapper(asyncHandler, context, parentContext);
asyncHandler = new AsyncHandlerWrapper(asyncHandler, request, context, parentContext);
}
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void methodExit(
@Advice.Thrown Throwable throwable, @Advice.Local("otelContext") Context context) {
@Advice.Argument(0) Request request,
@Advice.Thrown Throwable throwable,
@Advice.Local("otelContext") Context context) {
if (context != null && throwable != null) {
tracer().endExceptionally(context, throwable);
instrumenter().end(context, request, null, throwable);
}
}
}

View File

@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.playws.v2_1;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import org.reactivestreams.Publisher;
import play.shaded.ahc.org.asynchttpclient.Request;
import play.shaded.ahc.org.asynchttpclient.handler.StreamedAsyncHandler;
public class StreamedAsyncHandlerWrapper extends AsyncHandlerWrapper
@ -15,8 +16,8 @@ public class StreamedAsyncHandlerWrapper extends AsyncHandlerWrapper
private final StreamedAsyncHandler streamedDelegate;
public StreamedAsyncHandlerWrapper(
StreamedAsyncHandler delegate, Context context, Context parentContext) {
super(delegate, context, parentContext);
StreamedAsyncHandler delegate, Request request, Context context, Context parentContext) {
super(delegate, request, context, parentContext);
streamedDelegate = delegate;
}

View File

@ -1,19 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.playws;
import io.opentelemetry.context.propagation.TextMapSetter;
import play.shaded.ahc.io.netty.handler.codec.http.HttpHeaders;
public class HeadersInjectAdapter implements TextMapSetter<HttpHeaders> {
public static final HeadersInjectAdapter SETTER = new HeadersInjectAdapter();
@Override
public void set(HttpHeaders carrier, String key, String value) {
carrier.set(key, value);
}
}

View File

@ -0,0 +1,17 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.playws;
import io.opentelemetry.context.propagation.TextMapSetter;
import play.shaded.ahc.org.asynchttpclient.Request;
public class HttpHeaderSetter implements TextMapSetter<Request> {
@Override
public void set(Request carrier, String key, String value) {
carrier.getHeaders().set(key, value);
}
}

View File

@ -0,0 +1,101 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.playws;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpAttributesExtractor;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import org.checkerframework.checker.nullness.qual.Nullable;
import play.shaded.ahc.org.asynchttpclient.Request;
import play.shaded.ahc.org.asynchttpclient.Response;
import play.shaded.ahc.org.asynchttpclient.uri.Uri;
final class PlayWsClientHttpAttributesExtractor extends HttpAttributesExtractor<Request, Response> {
@Override
protected String method(Request request) {
return request.getMethod();
}
@Override
protected String url(Request request) {
return request.getUri().toUrl();
}
@Override
protected String target(Request request) {
Uri uri = request.getUri();
String query = uri.getQuery();
return query != null ? uri.getPath() + "?" + query : uri.getPath();
}
@Override
@Nullable
protected String host(Request request) {
String host = request.getHeaders().get("Host");
if (host != null) {
return host;
}
return request.getVirtualHost();
}
@Override
@Nullable
protected String scheme(Request request) {
return request.getUri().getScheme();
}
@Override
@Nullable
protected String userAgent(Request request) {
return null;
}
@Override
@Nullable
protected Long requestContentLength(Request request, @Nullable Response response) {
return null;
}
@Override
@Nullable
protected Long requestContentLengthUncompressed(Request request, @Nullable Response response) {
return null;
}
@Override
protected Integer statusCode(Request request, Response response) {
return response.getStatusCode();
}
@Override
protected String flavor(Request request, @Nullable Response response) {
return SemanticAttributes.HttpFlavorValues.HTTP_1_1;
}
@Override
@Nullable
protected Long responseContentLength(Request request, Response response) {
return null;
}
@Override
@Nullable
protected Long responseContentLengthUncompressed(Request request, Response response) {
return null;
}
@Override
@Nullable
protected String serverName(Request request, @Nullable Response response) {
return null;
}
@Override
@Nullable
protected String route(Request request) {
return null;
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.playws;
import io.opentelemetry.instrumentation.api.instrumenter.net.InetSocketAddressNetAttributesExtractor;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.net.InetSocketAddress;
import org.checkerframework.checker.nullness.qual.Nullable;
import play.shaded.ahc.org.asynchttpclient.Request;
import play.shaded.ahc.org.asynchttpclient.Response;
final class PlayWsClientNetAttributesExtractor
extends InetSocketAddressNetAttributesExtractor<Request, Response> {
@Override
public String transport(Request request) {
return SemanticAttributes.NetTransportValues.IP_TCP;
}
@Override
public @Nullable InetSocketAddress getAddress(Request request, @Nullable Response response) {
if (response != null && response.getRemoteAddress() instanceof InetSocketAddress) {
return (InetSocketAddress) response.getRemoteAddress();
}
return null;
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.playws;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.SpanStatusExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
import io.opentelemetry.javaagent.instrumentation.api.instrumenter.PeerServiceAttributesExtractor;
import play.shaded.ahc.org.asynchttpclient.Request;
import play.shaded.ahc.org.asynchttpclient.Response;
public class PlayWsClientSingletons {
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.play-ws-common";
private static final Instrumenter<Request, Response> INSTRUMENTER;
static {
HttpAttributesExtractor<Request, Response> httpAttributesExtractor =
new PlayWsClientHttpAttributesExtractor();
SpanNameExtractor<? super Request> spanNameExtractor =
HttpSpanNameExtractor.create(httpAttributesExtractor);
SpanStatusExtractor<? super Request, ? super Response> spanStatusExtractor =
HttpSpanStatusExtractor.create(httpAttributesExtractor);
PlayWsClientNetAttributesExtractor netAttributesExtractor =
new PlayWsClientNetAttributesExtractor();
INSTRUMENTER =
Instrumenter.<Request, Response>newBuilder(
GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, spanNameExtractor)
.setSpanStatusExtractor(spanStatusExtractor)
.addAttributesExtractor(httpAttributesExtractor)
.addAttributesExtractor(netAttributesExtractor)
.addAttributesExtractor(PeerServiceAttributesExtractor.create(netAttributesExtractor))
.addRequestMetrics(HttpClientMetrics.get())
.newClientInstrumenter(new HttpHeaderSetter());
}
public static Instrumenter<Request, Response> instrumenter() {
return INSTRUMENTER;
}
private PlayWsClientSingletons() {}
}

View File

@ -1,64 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.instrumentation.playws;
import static io.opentelemetry.javaagent.instrumentation.playws.HeadersInjectAdapter.SETTER;
import io.opentelemetry.context.propagation.TextMapSetter;
import io.opentelemetry.instrumentation.api.tracer.HttpClientTracer;
import io.opentelemetry.instrumentation.api.tracer.net.NetPeerAttributes;
import java.net.URI;
import java.net.URISyntaxException;
import play.shaded.ahc.io.netty.handler.codec.http.HttpHeaders;
import play.shaded.ahc.org.asynchttpclient.Request;
import play.shaded.ahc.org.asynchttpclient.Response;
public class PlayWsClientTracer extends HttpClientTracer<Request, HttpHeaders, Response> {
private static final PlayWsClientTracer TRACER = new PlayWsClientTracer();
private PlayWsClientTracer() {
super(NetPeerAttributes.INSTANCE);
}
public static PlayWsClientTracer tracer() {
return TRACER;
}
@Override
protected String method(Request request) {
return request.getMethod();
}
@Override
protected URI url(Request request) throws URISyntaxException {
return request.getUri().toJavaNetURI();
}
@Override
protected Integer status(Response response) {
return response.getStatusCode();
}
@Override
protected String requestHeader(Request request, String name) {
return request.getHeaders().get(name);
}
@Override
protected String responseHeader(Response response, String name) {
return response.getHeaders().get(name);
}
@Override
protected TextMapSetter<HttpHeaders> getSetter() {
return SETTER;
}
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.play-ws-common";
}
}

View File

@ -6,8 +6,10 @@
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.ActorMaterializerSettings
import io.opentelemetry.api.common.AttributeKey
import io.opentelemetry.instrumentation.test.AgentTestTrait
import io.opentelemetry.instrumentation.test.base.HttpClientTest
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import play.shaded.ahc.io.netty.resolver.InetNameResolver
import play.shaded.ahc.io.netty.util.concurrent.EventExecutor
import play.shaded.ahc.io.netty.util.concurrent.ImmediateEventExecutor
@ -60,6 +62,20 @@ abstract class PlayWsClientTestBaseBase<REQUEST> extends HttpClientTest<REQUEST>
int maxRedirects() {
3
}
@Override
Set<AttributeKey<?>> httpAttributes(URI uri) {
Set<AttributeKey<?>> extra = [
SemanticAttributes.HTTP_SCHEME,
SemanticAttributes.HTTP_TARGET
]
def attributes = super.httpAttributes(uri) + extra
if (uri.toString().endsWith("/circular-redirect")) {
attributes.remove(SemanticAttributes.NET_PEER_NAME)
attributes.remove(SemanticAttributes.NET_PEER_PORT)
}
return attributes
}
}
class CustomNameResolver extends InetNameResolver {

View File

@ -12,11 +12,11 @@ import io.opentelemetry.api.trace.SpanId
import io.opentelemetry.instrumentation.test.InstrumentationSpecification
import io.opentelemetry.instrumentation.test.asserts.TraceAssert
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpClientTest
import io.opentelemetry.instrumentation.testing.junit.http.HttpClientTestOptions
import io.opentelemetry.instrumentation.testing.junit.http.HttpClientTestServer
import io.opentelemetry.instrumentation.testing.junit.http.SingleConnection
import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions
import io.opentelemetry.sdk.trace.data.SpanData
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import spock.lang.Requires
import spock.lang.Shared
import spock.lang.Unroll
@ -427,12 +427,7 @@ abstract class HttpClientTest<REQUEST> extends InstrumentationSpecification {
/** A list of additional HTTP client span attributes extracted by the instrumentation per URI. */
Set<AttributeKey<?>> httpAttributes(URI uri) {
[
SemanticAttributes.HTTP_URL,
SemanticAttributes.HTTP_METHOD,
SemanticAttributes.HTTP_FLAVOR,
SemanticAttributes.HTTP_USER_AGENT
]
new HashSet<>(HttpClientTestOptions.DEFAULT_HTTP_ATTRIBUTES)
}
//This method should create either a single connection to the target uri or a http client

View File

@ -910,8 +910,12 @@ public abstract class AbstractHttpClientTest<REQUEST> {
}
}
} else {
assertThat(attrs).containsEntry(SemanticAttributes.NET_PEER_NAME, uri.getHost());
assertThat(attrs).containsEntry(SemanticAttributes.NET_PEER_PORT, uri.getPort());
if (httpClientAttributes.contains(SemanticAttributes.NET_PEER_NAME)) {
assertThat(attrs).containsEntry(SemanticAttributes.NET_PEER_NAME, uri.getHost());
}
if (httpClientAttributes.contains(SemanticAttributes.NET_PEER_PORT)) {
assertThat(attrs).containsEntry(SemanticAttributes.NET_PEER_PORT, uri.getPort());
}
}
// Optional

View File

@ -21,6 +21,8 @@ public final class HttpClientTestOptions {
Collections.unmodifiableSet(
new HashSet<>(
Arrays.asList(
SemanticAttributes.NET_PEER_NAME,
SemanticAttributes.NET_PEER_PORT,
SemanticAttributes.HTTP_URL,
SemanticAttributes.HTTP_METHOD,
SemanticAttributes.HTTP_FLAVOR,