From bdb35113629350aaf6bd64abce86de0aac7f6274 Mon Sep 17 00:00:00 2001 From: Mateusz Rzeszutek Date: Thu, 28 Oct 2021 01:39:10 +0200 Subject: [PATCH] Migrate vertx HTTP client to Instrumenter API (#4510) * Migrate vertx HTTP client to Instrumenter API * Fix vertx-reactive tests * Code review comments --- .../client/HttpRequestInstrumentation.java | 16 +++-- .../client/Vertx3HttpAttributesExtractor.java | 24 +++++++ .../v3_0/client/VertxClientSingletons.java | 24 +++++++ .../vertx/v3_0/client/VertxClientTracer.java | 36 ---------- .../groovy/client/VertxHttpClientTest.groovy | 11 ++++ .../client/HttpRequestInstrumentation.java | 15 +++-- .../client/Vertx4HttpAttributesExtractor.java | 52 +++++++++++++++ .../client/Vertx4NetAttributesExtractor.java | 38 +++++++++++ .../v4_0/client/VertxClientSingletons.java | 26 ++++++++ .../vertx/v4_0/client/VertxClientTracer.java | 40 ------------ .../client/AbstractVertxClientTracer.java | 55 ---------------- .../AbstractVertxHttpAttributesExtractor.java | 65 +++++++++++++++++++ .../vertx/client/ExceptionHandlerWrapper.java | 14 ++-- .../vertx/client/HttpRequestHeaderSetter.java | 19 ++++++ .../VertxClientInstrumenterFactory.java | 48 ++++++++++++++ .../VertxRxCircuitBreakerWebClientTest.groovy | 11 ++++ .../groovy/client/VertxRxWebClientTest.groovy | 11 ++++ 17 files changed, 354 insertions(+), 151 deletions(-) create mode 100644 instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/Vertx3HttpAttributesExtractor.java create mode 100644 instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientSingletons.java delete mode 100644 instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientTracer.java create mode 100644 instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/Vertx4HttpAttributesExtractor.java create mode 100644 instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/Vertx4NetAttributesExtractor.java create mode 100644 instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientSingletons.java delete mode 100644 instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientTracer.java delete mode 100644 instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/AbstractVertxClientTracer.java create mode 100644 instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/AbstractVertxHttpAttributesExtractor.java create mode 100644 instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/HttpRequestHeaderSetter.java create mode 100644 instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/VertxClientInstrumenterFactory.java diff --git a/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java b/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java index 32f057e14c..26857a7e81 100644 --- a/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java +++ b/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/HttpRequestInstrumentation.java @@ -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 virtualField = VirtualField.find(HttpClientRequest.class, Contexts.class); - handler = ExceptionHandlerWrapper.wrap(tracer(), request, virtualField, handler); + handler = ExceptionHandlerWrapper.wrap(instrumenter(), request, virtualField, handler); } } } diff --git a/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/Vertx3HttpAttributesExtractor.java b/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/Vertx3HttpAttributesExtractor.java new file mode 100644 index 0000000000..a63ee31381 --- /dev/null +++ b/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/Vertx3HttpAttributesExtractor.java @@ -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(); + } +} diff --git a/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientSingletons.java b/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientSingletons.java new file mode 100644 index 0000000000..1121d0a65d --- /dev/null +++ b/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientSingletons.java @@ -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 INSTRUMENTER = + VertxClientInstrumenterFactory.create( + "io.opentelemetry.vertx-http-client-3.0", new Vertx3HttpAttributesExtractor(), null); + + public static Instrumenter instrumenter() { + return INSTRUMENTER; + } + + private VertxClientSingletons() {} +} diff --git a/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientTracer.java b/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientTracer.java deleted file mode 100644 index 7d562b21c1..0000000000 --- a/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v3_0/client/VertxClientTracer.java +++ /dev/null @@ -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()); - } -} diff --git a/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/test/groovy/client/VertxHttpClientTest.groovy b/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/test/groovy/client/VertxHttpClientTest.groovy index 69b8d5e0a2..bd1c698be8 100644 --- a/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/test/groovy/client/VertxHttpClientTest.groovy +++ b/instrumentation/vertx-http-client/vertx-http-client-3.0/javaagent/src/test/groovy/client/VertxHttpClientTest.groovy @@ -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 implements A false } + @Override + Set> 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 diff --git a/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java b/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java index 39eb462dd4..811ecfe72b 100644 --- a/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java +++ b/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/HttpRequestInstrumentation.java @@ -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 virtualField = VirtualField.find(HttpClientRequest.class, Contexts.class); - handler = ExceptionHandlerWrapper.wrap(tracer(), request, virtualField, handler); + handler = ExceptionHandlerWrapper.wrap(instrumenter(), request, virtualField, handler); } } } diff --git a/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/Vertx4HttpAttributesExtractor.java b/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/Vertx4HttpAttributesExtractor.java new file mode 100644 index 0000000000..8f38f54a9f --- /dev/null +++ b/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/Vertx4HttpAttributesExtractor.java @@ -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; + } +} diff --git a/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/Vertx4NetAttributesExtractor.java b/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/Vertx4NetAttributesExtractor.java new file mode 100644 index 0000000000..b1137c064d --- /dev/null +++ b/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/Vertx4NetAttributesExtractor.java @@ -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 { + + @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; + } +} diff --git a/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientSingletons.java b/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientSingletons.java new file mode 100644 index 0000000000..331ab830f2 --- /dev/null +++ b/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientSingletons.java @@ -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 INSTRUMENTER = + VertxClientInstrumenterFactory.create( + "io.opentelemetry.vertx-http-client-4.0", + new Vertx4HttpAttributesExtractor(), + new Vertx4NetAttributesExtractor()); + + public static Instrumenter instrumenter() { + return INSTRUMENTER; + } + + private VertxClientSingletons() {} +} diff --git a/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientTracer.java b/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientTracer.java deleted file mode 100644 index 722f69335f..0000000000 --- a/instrumentation/vertx-http-client/vertx-http-client-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/v4_0/client/VertxClientTracer.java +++ /dev/null @@ -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; - } -} diff --git a/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/AbstractVertxClientTracer.java b/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/AbstractVertxClientTracer.java deleted file mode 100644 index 294910e734..0000000000 --- a/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/AbstractVertxClientTracer.java +++ /dev/null @@ -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 { - - 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 getSetter() { - return Propagator.INSTANCE; - } - - private static class Propagator implements TextMapSetter { - private static final Propagator INSTANCE = new Propagator(); - - @Override - public void set(HttpClientRequest carrier, String key, String value) { - if (carrier != null) { - carrier.putHeader(key, value); - } - } - } -} diff --git a/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/AbstractVertxHttpAttributesExtractor.java b/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/AbstractVertxHttpAttributesExtractor.java new file mode 100644 index 0000000000..fd880da71a --- /dev/null +++ b/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/AbstractVertxHttpAttributesExtractor.java @@ -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 { + + @Nullable + @Override + protected String flavor(HttpClientRequest request, @Nullable HttpClientResponse response) { + return null; + } + + @Override + protected List 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 responseHeader( + HttpClientRequest request, HttpClientResponse response, String name) { + return response.headers().getAll(name); + } +} diff --git a/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/ExceptionHandlerWrapper.java b/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/ExceptionHandlerWrapper.java index 0eafbfe24a..8489e080a2 100644 --- a/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/ExceptionHandlerWrapper.java +++ b/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/ExceptionHandlerWrapper.java @@ -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 { - private final AbstractVertxClientTracer tracer; + private final Instrumenter instrumenter; private final HttpClientRequest request; private final VirtualField virtualField; private final Handler handler; private ExceptionHandlerWrapper( - AbstractVertxClientTracer tracer, + Instrumenter instrumenter, HttpClientRequest request, VirtualField virtualField, Handler handler) { - this.tracer = tracer; + this.instrumenter = instrumenter; this.request = request; this.virtualField = virtualField; this.handler = handler; } public static Handler wrap( - AbstractVertxClientTracer tracer, + Instrumenter instrumenter, HttpClientRequest request, VirtualField virtualField, Handler handler) { @@ -36,7 +38,7 @@ public class ExceptionHandlerWrapper implements Handler { 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 { return; } - tracer.endExceptionally(contexts.context, throwable); + instrumenter.end(contexts.context, request, null, throwable); try (Scope ignored = contexts.parentContext.makeCurrent()) { callHandler(throwable); diff --git a/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/HttpRequestHeaderSetter.java b/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/HttpRequestHeaderSetter.java new file mode 100644 index 0000000000..daeb4e00b0 --- /dev/null +++ b/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/HttpRequestHeaderSetter.java @@ -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 { + + @Override + public void set(HttpClientRequest carrier, String key, String value) { + if (carrier != null) { + carrier.putHeader(key, value); + } + } +} diff --git a/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/VertxClientInstrumenterFactory.java b/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/VertxClientInstrumenterFactory.java new file mode 100644 index 0000000000..8fdeb8c731 --- /dev/null +++ b/instrumentation/vertx-http-client/vertx-http-client-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/vertx/client/VertxClientInstrumenterFactory.java @@ -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 create( + String instrumentationName, + AbstractVertxHttpAttributesExtractor httpAttributesExtractor, + @Nullable + NetClientAttributesExtractor + netAttributesExtractor) { + + InstrumenterBuilder builder = + Instrumenter.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() {} +} diff --git a/instrumentation/vertx-reactive-3.5/javaagent/src/version35Test/groovy/client/VertxRxCircuitBreakerWebClientTest.groovy b/instrumentation/vertx-reactive-3.5/javaagent/src/version35Test/groovy/client/VertxRxCircuitBreakerWebClientTest.groovy index ece83a2a40..a7db45c2b3 100644 --- a/instrumentation/vertx-reactive-3.5/javaagent/src/version35Test/groovy/client/VertxRxCircuitBreakerWebClientTest.groovy +++ b/instrumentation/vertx-reactive-3.5/javaagent/src/version35Test/groovy/client/VertxRxCircuitBreakerWebClientTest.groovy @@ -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> false } + @Override + Set> 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) diff --git a/instrumentation/vertx-reactive-3.5/javaagent/src/version35Test/groovy/client/VertxRxWebClientTest.groovy b/instrumentation/vertx-reactive-3.5/javaagent/src/version35Test/groovy/client/VertxRxWebClientTest.groovy index b7c229a4bb..11d3afdee9 100644 --- a/instrumentation/vertx-reactive-3.5/javaagent/src/version35Test/groovy/client/VertxRxWebClientTest.groovy +++ b/instrumentation/vertx-reactive-3.5/javaagent/src/version35Test/groovy/client/VertxRxWebClientTest.groovy @@ -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> implement false } + @Override + Set> 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)