Convert play-ws to instrumenter api (#3944)
This commit is contained in:
parent
564f51c706
commit
629801d9ab
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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() {}
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue