Migrate vertx HTTP client to Instrumenter API (#4510)
* Migrate vertx HTTP client to Instrumenter API * Fix vertx-reactive tests * Code review comments
This commit is contained in:
parent
3e3024d2b9
commit
bdb3511362
|
@ -7,7 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client;
|
|||
|
||||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
|
||||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface;
|
||||
import static io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client.VertxClientTracer.tracer;
|
||||
import static io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client.VertxClientSingletons.instrumenter;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPrivate;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||
|
@ -88,13 +88,14 @@ public class HttpRequestInstrumentation implements TypeInstrumentation {
|
|||
@Advice.This HttpClientRequest request,
|
||||
@Advice.Local("otelContext") Context context,
|
||||
@Advice.Local("otelScope") Scope scope) {
|
||||
|
||||
Context parentContext = Java8BytecodeBridge.currentContext();
|
||||
|
||||
if (!tracer().shouldStartSpan(parentContext)) {
|
||||
if (!instrumenter().shouldStart(parentContext, request)) {
|
||||
return;
|
||||
}
|
||||
|
||||
context = tracer().startSpan(parentContext, request, request);
|
||||
context = instrumenter().start(parentContext, request);
|
||||
Contexts contexts = new Contexts(parentContext, context);
|
||||
VirtualField.find(HttpClientRequest.class, Contexts.class).set(request, contexts);
|
||||
|
||||
|
@ -103,6 +104,7 @@ public class HttpRequestInstrumentation implements TypeInstrumentation {
|
|||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void endScope(
|
||||
@Advice.This HttpClientRequest request,
|
||||
@Advice.Local("otelContext") Context context,
|
||||
@Advice.Local("otelScope") Scope scope,
|
||||
@Advice.Thrown Throwable throwable) {
|
||||
|
@ -110,7 +112,7 @@ public class HttpRequestInstrumentation implements TypeInstrumentation {
|
|||
scope.close();
|
||||
}
|
||||
if (throwable != null) {
|
||||
tracer().endExceptionally(context, throwable);
|
||||
instrumenter().end(context, request, null, throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +131,7 @@ public class HttpRequestInstrumentation implements TypeInstrumentation {
|
|||
return;
|
||||
}
|
||||
|
||||
tracer().endExceptionally(contexts.context, t);
|
||||
instrumenter().end(contexts.context, request, null, t);
|
||||
|
||||
// Scoping all potential callbacks etc to the parent context
|
||||
scope = contexts.parentContext.makeCurrent();
|
||||
|
@ -157,7 +159,7 @@ public class HttpRequestInstrumentation implements TypeInstrumentation {
|
|||
return;
|
||||
}
|
||||
|
||||
tracer().end(contexts.context, response);
|
||||
instrumenter().end(contexts.context, request, response, null);
|
||||
|
||||
// Scoping all potential callbacks etc to the parent context
|
||||
scope = contexts.parentContext.makeCurrent();
|
||||
|
@ -203,7 +205,7 @@ public class HttpRequestInstrumentation implements TypeInstrumentation {
|
|||
if (handler != null) {
|
||||
VirtualField<HttpClientRequest, Contexts> virtualField =
|
||||
VirtualField.find(HttpClientRequest.class, Contexts.class);
|
||||
handler = ExceptionHandlerWrapper.wrap(tracer(), request, virtualField, handler);
|
||||
handler = ExceptionHandlerWrapper.wrap(instrumenter(), request, virtualField, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client;
|
||||
|
||||
import io.opentelemetry.javaagent.instrumentation.vertx.client.AbstractVertxHttpAttributesExtractor;
|
||||
import io.vertx.core.http.HttpClientRequest;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
final class Vertx3HttpAttributesExtractor extends AbstractVertxHttpAttributesExtractor {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected String url(HttpClientRequest request) {
|
||||
return request.uri();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String method(HttpClientRequest request) {
|
||||
return request.method().name();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.javaagent.instrumentation.vertx.client.VertxClientInstrumenterFactory;
|
||||
import io.vertx.core.http.HttpClientRequest;
|
||||
import io.vertx.core.http.HttpClientResponse;
|
||||
|
||||
public final class VertxClientSingletons {
|
||||
|
||||
private static final Instrumenter<HttpClientRequest, HttpClientResponse> INSTRUMENTER =
|
||||
VertxClientInstrumenterFactory.create(
|
||||
"io.opentelemetry.vertx-http-client-3.0", new Vertx3HttpAttributesExtractor(), null);
|
||||
|
||||
public static Instrumenter<HttpClientRequest, HttpClientResponse> instrumenter() {
|
||||
return INSTRUMENTER;
|
||||
}
|
||||
|
||||
private VertxClientSingletons() {}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.vertx.v3_0.client;
|
||||
|
||||
import io.opentelemetry.javaagent.instrumentation.vertx.client.AbstractVertxClientTracer;
|
||||
import io.vertx.core.http.HttpClientRequest;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class VertxClientTracer extends AbstractVertxClientTracer {
|
||||
private static final VertxClientTracer TRACER = new VertxClientTracer();
|
||||
|
||||
public static VertxClientTracer tracer() {
|
||||
return TRACER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInstrumentationName() {
|
||||
return "io.opentelemetry.vertx-http-client-3.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String method(HttpClientRequest request) {
|
||||
return request.method().name();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected URI url(HttpClientRequest request) throws URISyntaxException {
|
||||
return new URI(request.uri());
|
||||
}
|
||||
}
|
|
@ -5,10 +5,12 @@
|
|||
|
||||
package client
|
||||
|
||||
import io.opentelemetry.api.common.AttributeKey
|
||||
import io.opentelemetry.instrumentation.test.AgentTestTrait
|
||||
import io.opentelemetry.instrumentation.test.base.HttpClientTest
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpClientTest
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.SingleConnection
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import io.vertx.core.Vertx
|
||||
import io.vertx.core.VertxOptions
|
||||
import io.vertx.core.http.HttpClientOptions
|
||||
|
@ -76,6 +78,15 @@ class VertxHttpClientTest extends HttpClientTest<HttpClientRequest> implements A
|
|||
false
|
||||
}
|
||||
|
||||
@Override
|
||||
Set<AttributeKey<?>> httpAttributes(URI uri) {
|
||||
def attributes = super.httpAttributes(uri)
|
||||
attributes.remove(SemanticAttributes.HTTP_FLAVOR)
|
||||
attributes.remove(SemanticAttributes.NET_PEER_NAME)
|
||||
attributes.remove(SemanticAttributes.NET_PEER_PORT)
|
||||
return attributes
|
||||
}
|
||||
|
||||
@Override
|
||||
SingleConnection createSingleConnection(String host, int port) {
|
||||
//This test fails on Vert.x 3.0 and only works starting from 3.1
|
||||
|
|
|
@ -7,7 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.vertx.v4_0.client;
|
|||
|
||||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
|
||||
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.implementsInterface;
|
||||
import static io.opentelemetry.javaagent.instrumentation.vertx.v4_0.client.VertxClientTracer.tracer;
|
||||
import static io.opentelemetry.javaagent.instrumentation.vertx.v4_0.client.VertxClientSingletons.instrumenter;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.isPrivate;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||
|
@ -92,11 +92,11 @@ public class HttpRequestInstrumentation implements TypeInstrumentation {
|
|||
@Advice.Local("otelScope") Scope scope) {
|
||||
Context parentContext = Java8BytecodeBridge.currentContext();
|
||||
|
||||
if (!tracer().shouldStartSpan(parentContext)) {
|
||||
if (!instrumenter().shouldStart(parentContext, request)) {
|
||||
return;
|
||||
}
|
||||
|
||||
context = tracer().startSpan(parentContext, request, request);
|
||||
context = instrumenter().start(parentContext, request);
|
||||
Contexts contexts = new Contexts(parentContext, context);
|
||||
VirtualField.find(HttpClientRequest.class, Contexts.class).set(request, contexts);
|
||||
|
||||
|
@ -105,6 +105,7 @@ public class HttpRequestInstrumentation implements TypeInstrumentation {
|
|||
|
||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||
public static void endScope(
|
||||
@Advice.This HttpClientRequest request,
|
||||
@Advice.Local("otelContext") Context context,
|
||||
@Advice.Local("otelScope") Scope scope,
|
||||
@Advice.Thrown Throwable throwable) {
|
||||
|
@ -112,7 +113,7 @@ public class HttpRequestInstrumentation implements TypeInstrumentation {
|
|||
scope.close();
|
||||
}
|
||||
if (throwable != null) {
|
||||
tracer().endExceptionally(context, throwable);
|
||||
instrumenter().end(context, request, null, throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +132,7 @@ public class HttpRequestInstrumentation implements TypeInstrumentation {
|
|||
return;
|
||||
}
|
||||
|
||||
tracer().endExceptionally(contexts.context, t);
|
||||
instrumenter().end(contexts.context, request, null, t);
|
||||
|
||||
// Scoping all potential callbacks etc to the parent context
|
||||
scope = contexts.parentContext.makeCurrent();
|
||||
|
@ -159,7 +160,7 @@ public class HttpRequestInstrumentation implements TypeInstrumentation {
|
|||
return;
|
||||
}
|
||||
|
||||
tracer().end(contexts.context, response);
|
||||
instrumenter().end(contexts.context, request, response, null);
|
||||
|
||||
// Scoping all potential callbacks etc to the parent context
|
||||
scope = contexts.parentContext.makeCurrent();
|
||||
|
@ -205,7 +206,7 @@ public class HttpRequestInstrumentation implements TypeInstrumentation {
|
|||
if (handler != null) {
|
||||
VirtualField<HttpClientRequest, Contexts> virtualField =
|
||||
VirtualField.find(HttpClientRequest.class, Contexts.class);
|
||||
handler = ExceptionHandlerWrapper.wrap(tracer(), request, virtualField, handler);
|
||||
handler = ExceptionHandlerWrapper.wrap(instrumenter(), request, virtualField, handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.vertx.v4_0.client;
|
||||
|
||||
import io.opentelemetry.javaagent.instrumentation.vertx.client.AbstractVertxHttpAttributesExtractor;
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||
import io.vertx.core.http.HttpClientRequest;
|
||||
import io.vertx.core.http.HttpClientResponse;
|
||||
import io.vertx.core.http.HttpVersion;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
final class Vertx4HttpAttributesExtractor extends AbstractVertxHttpAttributesExtractor {
|
||||
|
||||
@Override
|
||||
protected String url(HttpClientRequest request) {
|
||||
String uri = request.getURI();
|
||||
if (!isAbsolute(uri)) {
|
||||
uri = request.absoluteURI();
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
|
||||
private static boolean isAbsolute(String uri) {
|
||||
return uri.startsWith("http://") || uri.startsWith("https://");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String method(HttpClientRequest request) {
|
||||
return request.getMethod().name();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected String flavor(HttpClientRequest request, @Nullable HttpClientResponse response) {
|
||||
HttpVersion version = request.version();
|
||||
if (version == null) {
|
||||
return null;
|
||||
}
|
||||
switch (version) {
|
||||
case HTTP_1_0:
|
||||
return SemanticAttributes.HttpFlavorValues.HTTP_1_0;
|
||||
case HTTP_1_1:
|
||||
return SemanticAttributes.HttpFlavorValues.HTTP_1_1;
|
||||
case HTTP_2:
|
||||
return SemanticAttributes.HttpFlavorValues.HTTP_2_0;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.vertx.v4_0.client;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor;
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
|
||||
import io.vertx.core.http.HttpClientRequest;
|
||||
import io.vertx.core.http.HttpClientResponse;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
final class Vertx4NetAttributesExtractor
|
||||
extends NetClientAttributesExtractor<HttpClientRequest, HttpClientResponse> {
|
||||
|
||||
@Override
|
||||
public String transport(HttpClientRequest request, @Nullable HttpClientResponse response) {
|
||||
return SemanticAttributes.NetTransportValues.IP_TCP;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String peerName(HttpClientRequest request, @Nullable HttpClientResponse response) {
|
||||
return request.getHost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer peerPort(HttpClientRequest request, @Nullable HttpClientResponse response) {
|
||||
return request.getPort();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String peerIp(HttpClientRequest request, @Nullable HttpClientResponse response) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.vertx.v4_0.client;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.javaagent.instrumentation.vertx.client.VertxClientInstrumenterFactory;
|
||||
import io.vertx.core.http.HttpClientRequest;
|
||||
import io.vertx.core.http.HttpClientResponse;
|
||||
|
||||
public final class VertxClientSingletons {
|
||||
|
||||
private static final Instrumenter<HttpClientRequest, HttpClientResponse> INSTRUMENTER =
|
||||
VertxClientInstrumenterFactory.create(
|
||||
"io.opentelemetry.vertx-http-client-4.0",
|
||||
new Vertx4HttpAttributesExtractor(),
|
||||
new Vertx4NetAttributesExtractor());
|
||||
|
||||
public static Instrumenter<HttpClientRequest, HttpClientResponse> instrumenter() {
|
||||
return INSTRUMENTER;
|
||||
}
|
||||
|
||||
private VertxClientSingletons() {}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.vertx.v4_0.client;
|
||||
|
||||
import io.opentelemetry.javaagent.instrumentation.vertx.client.AbstractVertxClientTracer;
|
||||
import io.vertx.core.http.HttpClientRequest;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class VertxClientTracer extends AbstractVertxClientTracer {
|
||||
private static final VertxClientTracer TRACER = new VertxClientTracer();
|
||||
|
||||
public static VertxClientTracer tracer() {
|
||||
return TRACER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getInstrumentationName() {
|
||||
return "io.opentelemetry.vertx-http-client-4.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String method(HttpClientRequest request) {
|
||||
return request.getMethod().name();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected URI url(HttpClientRequest request) throws URISyntaxException {
|
||||
URI uri = new URI(request.getURI());
|
||||
if (!uri.isAbsolute()) {
|
||||
uri = new URI(request.absoluteURI());
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.vertx.client;
|
||||
|
||||
import io.opentelemetry.context.propagation.TextMapSetter;
|
||||
import io.opentelemetry.instrumentation.api.tracer.HttpClientTracer;
|
||||
import io.opentelemetry.instrumentation.api.tracer.net.NetPeerAttributes;
|
||||
import io.vertx.core.http.HttpClientRequest;
|
||||
import io.vertx.core.http.HttpClientResponse;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class AbstractVertxClientTracer
|
||||
extends HttpClientTracer<HttpClientRequest, HttpClientRequest, HttpClientResponse> {
|
||||
|
||||
protected AbstractVertxClientTracer() {
|
||||
super(NetPeerAttributes.INSTANCE);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected Integer status(HttpClientResponse response) {
|
||||
return response.statusCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected String requestHeader(HttpClientRequest request, String name) {
|
||||
return request.headers().get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected String responseHeader(HttpClientResponse response, String name) {
|
||||
return response.getHeader(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected TextMapSetter<HttpClientRequest> getSetter() {
|
||||
return Propagator.INSTANCE;
|
||||
}
|
||||
|
||||
private static class Propagator implements TextMapSetter<HttpClientRequest> {
|
||||
private static final Propagator INSTANCE = new Propagator();
|
||||
|
||||
@Override
|
||||
public void set(HttpClientRequest carrier, String key, String value) {
|
||||
if (carrier != null) {
|
||||
carrier.putHeader(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.vertx.client;
|
||||
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
|
||||
import io.vertx.core.http.HttpClientRequest;
|
||||
import io.vertx.core.http.HttpClientResponse;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class AbstractVertxHttpAttributesExtractor
|
||||
extends HttpClientAttributesExtractor<HttpClientRequest, HttpClientResponse> {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected String flavor(HttpClientRequest request, @Nullable HttpClientResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> requestHeader(HttpClientRequest request, String name) {
|
||||
return request.headers().getAll(name);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Long requestContentLength(
|
||||
HttpClientRequest request, @Nullable HttpClientResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Long requestContentLengthUncompressed(
|
||||
HttpClientRequest request, @Nullable HttpClientResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer statusCode(HttpClientRequest request, HttpClientResponse response) {
|
||||
return response.statusCode();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Long responseContentLength(HttpClientRequest request, HttpClientResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected Long responseContentLengthUncompressed(
|
||||
HttpClientRequest request, HttpClientResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> responseHeader(
|
||||
HttpClientRequest request, HttpClientResponse response, String name) {
|
||||
return response.headers().getAll(name);
|
||||
}
|
||||
}
|
|
@ -7,28 +7,30 @@ package io.opentelemetry.javaagent.instrumentation.vertx.client;
|
|||
|
||||
import io.opentelemetry.context.Scope;
|
||||
import io.opentelemetry.instrumentation.api.field.VirtualField;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.core.http.HttpClientRequest;
|
||||
import io.vertx.core.http.HttpClientResponse;
|
||||
|
||||
public class ExceptionHandlerWrapper implements Handler<Throwable> {
|
||||
private final AbstractVertxClientTracer tracer;
|
||||
private final Instrumenter<HttpClientRequest, HttpClientResponse> instrumenter;
|
||||
private final HttpClientRequest request;
|
||||
private final VirtualField<HttpClientRequest, Contexts> virtualField;
|
||||
private final Handler<Throwable> handler;
|
||||
|
||||
private ExceptionHandlerWrapper(
|
||||
AbstractVertxClientTracer tracer,
|
||||
Instrumenter<HttpClientRequest, HttpClientResponse> instrumenter,
|
||||
HttpClientRequest request,
|
||||
VirtualField<HttpClientRequest, Contexts> virtualField,
|
||||
Handler<Throwable> handler) {
|
||||
this.tracer = tracer;
|
||||
this.instrumenter = instrumenter;
|
||||
this.request = request;
|
||||
this.virtualField = virtualField;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public static Handler<Throwable> wrap(
|
||||
AbstractVertxClientTracer tracer,
|
||||
Instrumenter<HttpClientRequest, HttpClientResponse> instrumenter,
|
||||
HttpClientRequest request,
|
||||
VirtualField<HttpClientRequest, Contexts> virtualField,
|
||||
Handler<Throwable> handler) {
|
||||
|
@ -36,7 +38,7 @@ public class ExceptionHandlerWrapper implements Handler<Throwable> {
|
|||
return handler;
|
||||
}
|
||||
|
||||
return new ExceptionHandlerWrapper(tracer, request, virtualField, handler);
|
||||
return new ExceptionHandlerWrapper(instrumenter, request, virtualField, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -47,7 +49,7 @@ public class ExceptionHandlerWrapper implements Handler<Throwable> {
|
|||
return;
|
||||
}
|
||||
|
||||
tracer.endExceptionally(contexts.context, throwable);
|
||||
instrumenter.end(contexts.context, request, null, throwable);
|
||||
|
||||
try (Scope ignored = contexts.parentContext.makeCurrent()) {
|
||||
callHandler(throwable);
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.vertx.client;
|
||||
|
||||
import io.opentelemetry.context.propagation.TextMapSetter;
|
||||
import io.vertx.core.http.HttpClientRequest;
|
||||
|
||||
public class HttpRequestHeaderSetter implements TextMapSetter<HttpClientRequest> {
|
||||
|
||||
@Override
|
||||
public void set(HttpClientRequest carrier, String key, String value) {
|
||||
if (carrier != null) {
|
||||
carrier.putHeader(key, value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.javaagent.instrumentation.vertx.client;
|
||||
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
|
||||
import io.opentelemetry.instrumentation.api.instrumenter.PeerServiceAttributesExtractor;
|
||||
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.instrumentation.api.instrumenter.net.NetClientAttributesExtractor;
|
||||
import io.vertx.core.http.HttpClientRequest;
|
||||
import io.vertx.core.http.HttpClientResponse;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class VertxClientInstrumenterFactory {
|
||||
|
||||
public static Instrumenter<HttpClientRequest, HttpClientResponse> create(
|
||||
String instrumentationName,
|
||||
AbstractVertxHttpAttributesExtractor httpAttributesExtractor,
|
||||
@Nullable
|
||||
NetClientAttributesExtractor<HttpClientRequest, HttpClientResponse>
|
||||
netAttributesExtractor) {
|
||||
|
||||
InstrumenterBuilder<HttpClientRequest, HttpClientResponse> builder =
|
||||
Instrumenter.<HttpClientRequest, HttpClientResponse>builder(
|
||||
GlobalOpenTelemetry.get(),
|
||||
instrumentationName,
|
||||
HttpSpanNameExtractor.create(httpAttributesExtractor))
|
||||
.setSpanStatusExtractor(HttpSpanStatusExtractor.create(httpAttributesExtractor))
|
||||
.addAttributesExtractor(httpAttributesExtractor)
|
||||
.addRequestMetrics(HttpClientMetrics.get());
|
||||
|
||||
if (netAttributesExtractor != null) {
|
||||
builder
|
||||
.addAttributesExtractor(netAttributesExtractor)
|
||||
.addAttributesExtractor(PeerServiceAttributesExtractor.create(netAttributesExtractor));
|
||||
}
|
||||
|
||||
return builder.newClientInstrumenter(new HttpRequestHeaderSetter());
|
||||
}
|
||||
|
||||
private VertxClientInstrumenterFactory() {}
|
||||
}
|
|
@ -5,10 +5,12 @@
|
|||
|
||||
package client
|
||||
|
||||
import io.opentelemetry.api.common.AttributeKey
|
||||
import io.opentelemetry.instrumentation.test.AgentTestTrait
|
||||
import io.opentelemetry.instrumentation.test.base.HttpClientTest
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpClientTest
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.SingleConnection
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import io.vertx.circuitbreaker.CircuitBreakerOptions
|
||||
import io.vertx.core.AsyncResult
|
||||
import io.vertx.core.VertxOptions
|
||||
|
@ -97,6 +99,15 @@ class VertxRxCircuitBreakerWebClientTest extends HttpClientTest<HttpRequest<?>>
|
|||
false
|
||||
}
|
||||
|
||||
@Override
|
||||
Set<AttributeKey<?>> httpAttributes(URI uri) {
|
||||
def attributes = super.httpAttributes(uri)
|
||||
attributes.remove(SemanticAttributes.HTTP_FLAVOR)
|
||||
attributes.remove(SemanticAttributes.NET_PEER_NAME)
|
||||
attributes.remove(SemanticAttributes.NET_PEER_PORT)
|
||||
return attributes
|
||||
}
|
||||
|
||||
@Override
|
||||
SingleConnection createSingleConnection(String host, int port) {
|
||||
return new VertxRxCircuitBreakerSingleConnection(host, port, breaker)
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
|
||||
package client
|
||||
|
||||
import io.opentelemetry.api.common.AttributeKey
|
||||
import io.opentelemetry.instrumentation.test.AgentTestTrait
|
||||
import io.opentelemetry.instrumentation.test.base.HttpClientTest
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.AbstractHttpClientTest
|
||||
import io.opentelemetry.instrumentation.testing.junit.http.SingleConnection
|
||||
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
|
||||
import io.vertx.core.VertxOptions
|
||||
import io.vertx.core.http.HttpMethod
|
||||
import io.vertx.ext.web.client.WebClientOptions
|
||||
|
@ -83,6 +85,15 @@ class VertxRxWebClientTest extends HttpClientTest<HttpRequest<Buffer>> implement
|
|||
false
|
||||
}
|
||||
|
||||
@Override
|
||||
Set<AttributeKey<?>> httpAttributes(URI uri) {
|
||||
def attributes = super.httpAttributes(uri)
|
||||
attributes.remove(SemanticAttributes.HTTP_FLAVOR)
|
||||
attributes.remove(SemanticAttributes.NET_PEER_NAME)
|
||||
attributes.remove(SemanticAttributes.NET_PEER_PORT)
|
||||
return attributes
|
||||
}
|
||||
|
||||
@Override
|
||||
SingleConnection createSingleConnection(String host, int port) {
|
||||
return new VertxRxSingleConnection(host, port)
|
||||
|
|
Loading…
Reference in New Issue