From 629801d9ab08c9575c158c8e6f2d9c6383649ee2 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Wed, 25 Aug 2021 19:31:50 +0300 Subject: [PATCH] Convert play-ws to instrumenter api (#3944) --- .../playws/v1_0/AsyncHandlerWrapper.java | 12 ++- .../v1_0/PlayWsInstrumentationModule.java | 13 +-- .../v1_0/StreamedAsyncHandlerWrapper.java | 5 +- .../playws/v2_0/AsyncHandlerWrapper.java | 12 ++- .../v2_0/PlayWsInstrumentationModule.java | 16 +-- .../v2_0/StreamedAsyncHandlerWrapper.java | 5 +- .../playws/v2_1/AsyncHandlerWrapper.java | 12 ++- .../v2_1/PlayWsInstrumentationModule.java | 16 +-- .../v2_1/StreamedAsyncHandlerWrapper.java | 5 +- .../playws/HeadersInjectAdapter.java | 19 ---- .../playws/HttpHeaderSetter.java | 17 +++ .../PlayWsClientHttpAttributesExtractor.java | 101 ++++++++++++++++++ .../PlayWsClientNetAttributesExtractor.java | 30 ++++++ .../playws/PlayWsClientSingletons.java | 51 +++++++++ .../playws/PlayWsClientTracer.java | 64 ----------- .../groovy/PlayWsClientTestBaseBase.groovy | 16 +++ .../test/base/HttpClientTest.groovy | 9 +- .../junit/http/AbstractHttpClientTest.java | 8 +- .../junit/http/HttpClientTestOptions.java | 2 + 19 files changed, 283 insertions(+), 130 deletions(-) delete mode 100644 instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/HeadersInjectAdapter.java create mode 100644 instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/HttpHeaderSetter.java create mode 100644 instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientHttpAttributesExtractor.java create mode 100644 instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientNetAttributesExtractor.java create mode 100644 instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientSingletons.java delete mode 100644 instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientTracer.java diff --git a/instrumentation/play-ws/play-ws-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v1_0/AsyncHandlerWrapper.java b/instrumentation/play-ws/play-ws-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v1_0/AsyncHandlerWrapper.java index a03c0c9464..078382f854 100644 --- a/instrumentation/play-ws/play-ws-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v1_0/AsyncHandlerWrapper.java +++ b/instrumentation/play-ws/play-ws-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v1_0/AsyncHandlerWrapper.java @@ -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); diff --git a/instrumentation/play-ws/play-ws-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v1_0/PlayWsInstrumentationModule.java b/instrumentation/play-ws/play-ws-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v1_0/PlayWsInstrumentationModule.java index 6f93ebdab3..2dcc5e1941 100644 --- a/instrumentation/play-ws/play-ws-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v1_0/PlayWsInstrumentationModule.java +++ b/instrumentation/play-ws/play-ws-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v1_0/PlayWsInstrumentationModule.java @@ -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); } } } diff --git a/instrumentation/play-ws/play-ws-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v1_0/StreamedAsyncHandlerWrapper.java b/instrumentation/play-ws/play-ws-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v1_0/StreamedAsyncHandlerWrapper.java index 116b70a82a..9041835e61 100644 --- a/instrumentation/play-ws/play-ws-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v1_0/StreamedAsyncHandlerWrapper.java +++ b/instrumentation/play-ws/play-ws-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v1_0/StreamedAsyncHandlerWrapper.java @@ -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; } diff --git a/instrumentation/play-ws/play-ws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_0/AsyncHandlerWrapper.java b/instrumentation/play-ws/play-ws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_0/AsyncHandlerWrapper.java index 7ef28dab84..9621c527ca 100644 --- a/instrumentation/play-ws/play-ws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_0/AsyncHandlerWrapper.java +++ b/instrumentation/play-ws/play-ws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_0/AsyncHandlerWrapper.java @@ -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); diff --git a/instrumentation/play-ws/play-ws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_0/PlayWsInstrumentationModule.java b/instrumentation/play-ws/play-ws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_0/PlayWsInstrumentationModule.java index 86ef50cfbd..0c635e40c4 100644 --- a/instrumentation/play-ws/play-ws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_0/PlayWsInstrumentationModule.java +++ b/instrumentation/play-ws/play-ws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_0/PlayWsInstrumentationModule.java @@ -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); } } } diff --git a/instrumentation/play-ws/play-ws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_0/StreamedAsyncHandlerWrapper.java b/instrumentation/play-ws/play-ws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_0/StreamedAsyncHandlerWrapper.java index 9059628fc4..44ca9f872f 100644 --- a/instrumentation/play-ws/play-ws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_0/StreamedAsyncHandlerWrapper.java +++ b/instrumentation/play-ws/play-ws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_0/StreamedAsyncHandlerWrapper.java @@ -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; } diff --git a/instrumentation/play-ws/play-ws-2.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_1/AsyncHandlerWrapper.java b/instrumentation/play-ws/play-ws-2.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_1/AsyncHandlerWrapper.java index ab0b1acfdf..aa4db447a2 100644 --- a/instrumentation/play-ws/play-ws-2.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_1/AsyncHandlerWrapper.java +++ b/instrumentation/play-ws/play-ws-2.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_1/AsyncHandlerWrapper.java @@ -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); diff --git a/instrumentation/play-ws/play-ws-2.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_1/PlayWsInstrumentationModule.java b/instrumentation/play-ws/play-ws-2.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_1/PlayWsInstrumentationModule.java index 9610793e90..f2ace2b3be 100644 --- a/instrumentation/play-ws/play-ws-2.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_1/PlayWsInstrumentationModule.java +++ b/instrumentation/play-ws/play-ws-2.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_1/PlayWsInstrumentationModule.java @@ -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); } } } diff --git a/instrumentation/play-ws/play-ws-2.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_1/StreamedAsyncHandlerWrapper.java b/instrumentation/play-ws/play-ws-2.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_1/StreamedAsyncHandlerWrapper.java index 5fd2ec82b2..c134d6898d 100644 --- a/instrumentation/play-ws/play-ws-2.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_1/StreamedAsyncHandlerWrapper.java +++ b/instrumentation/play-ws/play-ws-2.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/v2_1/StreamedAsyncHandlerWrapper.java @@ -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; } diff --git a/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/HeadersInjectAdapter.java b/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/HeadersInjectAdapter.java deleted file mode 100644 index 8273c518cc..0000000000 --- a/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/HeadersInjectAdapter.java +++ /dev/null @@ -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 { - - public static final HeadersInjectAdapter SETTER = new HeadersInjectAdapter(); - - @Override - public void set(HttpHeaders carrier, String key, String value) { - carrier.set(key, value); - } -} diff --git a/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/HttpHeaderSetter.java b/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/HttpHeaderSetter.java new file mode 100644 index 0000000000..08a83e2b69 --- /dev/null +++ b/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/HttpHeaderSetter.java @@ -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 { + + @Override + public void set(Request carrier, String key, String value) { + carrier.getHeaders().set(key, value); + } +} diff --git a/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientHttpAttributesExtractor.java b/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientHttpAttributesExtractor.java new file mode 100644 index 0000000000..fbf737c4df --- /dev/null +++ b/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientHttpAttributesExtractor.java @@ -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 { + + @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; + } +} diff --git a/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientNetAttributesExtractor.java b/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientNetAttributesExtractor.java new file mode 100644 index 0000000000..6c50ae237c --- /dev/null +++ b/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientNetAttributesExtractor.java @@ -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 { + + @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; + } +} diff --git a/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientSingletons.java b/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientSingletons.java new file mode 100644 index 0000000000..74fc3a7703 --- /dev/null +++ b/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientSingletons.java @@ -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 INSTRUMENTER; + + static { + HttpAttributesExtractor httpAttributesExtractor = + new PlayWsClientHttpAttributesExtractor(); + SpanNameExtractor spanNameExtractor = + HttpSpanNameExtractor.create(httpAttributesExtractor); + SpanStatusExtractor spanStatusExtractor = + HttpSpanStatusExtractor.create(httpAttributesExtractor); + PlayWsClientNetAttributesExtractor netAttributesExtractor = + new PlayWsClientNetAttributesExtractor(); + + INSTRUMENTER = + Instrumenter.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 instrumenter() { + return INSTRUMENTER; + } + + private PlayWsClientSingletons() {} +} diff --git a/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientTracer.java b/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientTracer.java deleted file mode 100644 index c6b1ebf3c7..0000000000 --- a/instrumentation/play-ws/play-ws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/playws/PlayWsClientTracer.java +++ /dev/null @@ -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 { - 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 getSetter() { - return SETTER; - } - - @Override - protected String getInstrumentationName() { - return "io.opentelemetry.play-ws-common"; - } -} diff --git a/instrumentation/play-ws/play-ws-testing/src/main/groovy/PlayWsClientTestBaseBase.groovy b/instrumentation/play-ws/play-ws-testing/src/main/groovy/PlayWsClientTestBaseBase.groovy index 0b7ba3247a..943bdf3219 100644 --- a/instrumentation/play-ws/play-ws-testing/src/main/groovy/PlayWsClientTestBaseBase.groovy +++ b/instrumentation/play-ws/play-ws-testing/src/main/groovy/PlayWsClientTestBaseBase.groovy @@ -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 extends HttpClientTest int maxRedirects() { 3 } + + @Override + Set> httpAttributes(URI uri) { + Set> 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 { diff --git a/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpClientTest.groovy b/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpClientTest.groovy index b6f3cf47a4..bac75d168b 100644 --- a/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpClientTest.groovy +++ b/testing-common/src/main/groovy/io/opentelemetry/instrumentation/test/base/HttpClientTest.groovy @@ -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 extends InstrumentationSpecification { /** A list of additional HTTP client span attributes extracted by the instrumentation per URI. */ Set> 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 diff --git a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/http/AbstractHttpClientTest.java b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/http/AbstractHttpClientTest.java index a0a7ade040..dc38db8fe8 100644 --- a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/http/AbstractHttpClientTest.java +++ b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/http/AbstractHttpClientTest.java @@ -910,8 +910,12 @@ public abstract class AbstractHttpClientTest { } } } 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 diff --git a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/http/HttpClientTestOptions.java b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/http/HttpClientTestOptions.java index dd22074555..acad7093d9 100644 --- a/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/http/HttpClientTestOptions.java +++ b/testing-common/src/main/java/io/opentelemetry/instrumentation/testing/junit/http/HttpClientTestOptions.java @@ -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,