Refactor HttpClient typed Decorators to Tracers (#893)

* initial work

* Change OkHttp decorators to tracers

* Change AkkaHttpClient decorator to tracer

* Change ClientDecorator to GrizzlyClientTracer

* Change NettyClientDecorator to Tracer

* Change netty3.8 client decorator to tracer

* Update netty4.1 client decorator to tracer

* Override startScope in child tracers when applicable

* Change KHttpDecorator to tracer

* Change HttpUrlConnectionDecorator to tracer

* Fix muzzle validation failure for grizzly client

* Fix a ratpack client test failure

* Address feedback

* Update delegate for setPeer

* Remove nested try

* Remove unnecessary null check

* Remove asserts

* Add a comment for overriding startSpan(String spanName)

* Remove an irrelevant comment

* Throw an exception when getSetter is null

* Change onPeerConnection to static

* Change getSetter() to be abstract
This commit is contained in:
Helen Y 2020-08-06 17:14:19 -07:00 committed by GitHub
parent 46dfa263af
commit 1fcb807590
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
46 changed files with 656 additions and 482 deletions

View File

@ -18,10 +18,14 @@ package io.opentelemetry.auto.bootstrap.instrumentation.decorator;
import io.grpc.Context;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.config.Config;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Status;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.trace.attributes.SemanticAttributes;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;
public abstract class BaseTracer {
@ -127,7 +131,44 @@ public abstract class BaseTracer {
span.recordException(throwable);
}
public static void onPeerConnection(final Span span, final InetSocketAddress remoteConnection) {
if (remoteConnection != null) {
InetAddress remoteAddress = remoteConnection.getAddress();
if (remoteAddress != null) {
onPeerConnection(span, remoteAddress);
} else {
// Failed DNS lookup, the host string is the name.
setPeer(span, remoteConnection.getHostString(), null);
}
span.setAttribute(SemanticAttributes.NET_PEER_PORT.key(), remoteConnection.getPort());
}
}
public static void onPeerConnection(final Span span, final InetAddress remoteAddress) {
setPeer(span, remoteAddress.getHostName(), remoteAddress.getHostAddress());
}
public static void setPeer(final Span span, String peerName, String peerIp) {
BaseDecorator.setPeer(span, peerName, peerIp);
if (peerName != null && !peerName.equals(peerIp)) {
SemanticAttributes.NET_PEER_NAME.set(span, peerName);
}
if (peerIp != null) {
SemanticAttributes.NET_PEER_IP.set(span, peerIp);
}
String peerService = mapToPeer(peerName);
if (peerService == null) {
peerService = mapToPeer(peerIp);
}
if (peerService != null) {
SemanticAttributes.PEER_SERVICE.set(span, peerService);
}
}
protected static String mapToPeer(String endpoint) {
if (endpoint == null) {
return null;
}
return Config.get().getEndpointPeerServiceMapping().get(endpoint);
}
}

View File

@ -27,7 +27,6 @@ import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Status;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.trace.attributes.SemanticAttributes;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;
@ -120,23 +119,10 @@ public abstract class DatabaseClientTracer<CONNECTION, QUERY> extends BaseTracer
}
}
protected void onPeerConnection(Span span, final CONNECTION connection) {
protected void onPeerConnection(final Span span, final CONNECTION connection) {
onPeerConnection(span, peerAddress(connection));
}
protected void onPeerConnection(final Span span, final InetSocketAddress remoteConnection) {
if (remoteConnection != null) {
onPeerConnection(span, remoteConnection.getAddress());
span.setAttribute(SemanticAttributes.NET_PEER_PORT.key(), remoteConnection.getPort());
}
}
protected void onPeerConnection(final Span span, final InetAddress remoteAddress) {
if (remoteAddress != null) {
setPeer(span, remoteAddress.getHostName(), remoteAddress.getHostAddress());
}
}
protected void onStatement(final Span span, final String statement) {
span.setAttribute(SemanticAttributes.DB_STATEMENT.key(), statement);
}

View File

@ -0,0 +1,182 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.auto.bootstrap.instrumentation.decorator;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import io.grpc.Context;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.config.Config;
import io.opentelemetry.auto.instrumentation.api.MoreAttributes;
import io.opentelemetry.context.Scope;
import io.opentelemetry.context.propagation.HttpTextFormat;
import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
import io.opentelemetry.trace.DefaultSpan;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Span.Kind;
import io.opentelemetry.trace.TracingContextUtils;
import io.opentelemetry.trace.attributes.SemanticAttributes;
import java.net.URI;
import java.net.URISyntaxException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class HttpClientTracer<REQUEST, RESPONSE> extends BaseTracer {
private static final Logger log = LoggerFactory.getLogger(HttpClientTracer.class);
public static final String DEFAULT_SPAN_NAME = "HTTP request";
protected static final String USER_AGENT = "User-Agent";
protected abstract String method(REQUEST request);
protected abstract URI url(REQUEST request) throws URISyntaxException;
protected abstract Integer status(RESPONSE response);
protected abstract String requestHeader(REQUEST request, String name);
protected abstract String responseHeader(RESPONSE response, String name);
protected abstract HttpTextFormat.Setter<REQUEST> getSetter();
public Span startSpan(REQUEST request) {
return startSpan(request, spanNameForRequest(request));
}
public Scope startScope(Span span, REQUEST request) {
Context context = withSpan(span, Context.current());
Setter<REQUEST> setter = getSetter();
if (setter == null) {
throw new IllegalStateException(
"getSetter() not defined but calling startScope(), either getSetter must be implemented or the scope should be setup manually");
}
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, request, setter);
return withScopedContext(context);
}
public void end(Span span, RESPONSE response) {
onResponse(span, response);
super.end(span);
}
public void endExceptionally(Span span, RESPONSE response, Throwable throwable) {
onResponse(span, response);
super.endExceptionally(span, throwable);
}
/**
* Returns a new client {@link Span} if there is no client {@link Span} in the current {@link
* Context}, or an invalid {@link Span} otherwise.
*/
private Span startSpan(REQUEST request, String name) {
Context context = Context.current();
Span clientSpan = ClientDecorator.CONTEXT_CLIENT_SPAN_KEY.get(context);
if (clientSpan != null) {
// We don't want to create two client spans for a given client call, suppress inner spans.
return DefaultSpan.getInvalid();
}
Span current = TracingContextUtils.getSpan(context);
Span span = tracer.spanBuilder(name).setSpanKind(Kind.CLIENT).setParent(current).startSpan();
onRequest(span, request);
return span;
}
private Span onRequest(final Span span, final REQUEST request) {
assert span != null;
if (request != null) {
span.setAttribute(SemanticAttributes.HTTP_METHOD.key(), method(request));
String userAgent = requestHeader(request, USER_AGENT);
if (userAgent != null) {
SemanticAttributes.HTTP_USER_AGENT.set(span, userAgent);
}
// Copy of HttpServerDecorator url handling
try {
URI url = url(request);
if (url != null) {
StringBuilder urlBuilder = new StringBuilder();
if (url.getScheme() != null) {
urlBuilder.append(url.getScheme());
urlBuilder.append("://");
}
if (url.getHost() != null) {
urlBuilder.append(url.getHost());
setPeer(span, url.getHost(), null);
if (url.getPort() > 0) {
span.setAttribute(SemanticAttributes.NET_PEER_PORT.key(), url.getPort());
if (url.getPort() != 80 && url.getPort() != 443) {
urlBuilder.append(":");
urlBuilder.append(url.getPort());
}
}
}
String path = url.getPath();
if (path.isEmpty()) {
urlBuilder.append("/");
} else {
urlBuilder.append(path);
}
String query = url.getQuery();
if (query != null) {
urlBuilder.append("?").append(query);
}
String fragment = url.getFragment();
if (fragment != null) {
urlBuilder.append("#").append(fragment);
}
span.setAttribute(SemanticAttributes.HTTP_URL.key(), urlBuilder.toString());
if (Config.get().isHttpClientTagQueryString()) {
span.setAttribute(MoreAttributes.HTTP_QUERY, query);
span.setAttribute(MoreAttributes.HTTP_FRAGMENT, fragment);
}
}
} catch (final Exception e) {
log.debug("Error tagging url", e);
}
}
return span;
}
private Span onResponse(final Span span, final RESPONSE response) {
assert span != null;
if (response != null) {
Integer status = status(response);
System.out.println("status: " + status);
if (status != null) {
span.setAttribute(SemanticAttributes.HTTP_STATUS_CODE.key(), status);
span.setStatus(HttpStatusConverter.statusFromHttpStatus(status));
}
}
return span;
}
private String spanNameForRequest(final REQUEST request) {
if (request == null) {
return DEFAULT_SPAN_NAME;
}
String method = method(request);
return method != null ? "HTTP " + method : DEFAULT_SPAN_NAME;
}
}

View File

@ -16,10 +16,8 @@
package io.opentelemetry.auto.instrumentation.akkahttp;
import static io.opentelemetry.auto.instrumentation.akkahttp.AkkaHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.akkahttp.AkkaHttpClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.akkahttp.AkkaHttpClientTracer.TRACER;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
@ -31,9 +29,9 @@ import akka.http.scaladsl.model.HttpResponse;
import com.google.auto.service.AutoService;
import io.grpc.Context;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap;
import io.opentelemetry.auto.instrumentation.api.SpanWithScope;
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap.Depth;
import io.opentelemetry.auto.tooling.Instrumenter;
import io.opentelemetry.context.Scope;
import io.opentelemetry.context.propagation.HttpTextFormat;
import io.opentelemetry.trace.Span;
import java.util.HashMap;
@ -62,7 +60,7 @@ public final class AkkaHttpClientInstrumentation extends Instrumenter.Default {
return new String[] {
AkkaHttpClientInstrumentation.class.getName() + "$OnCompleteHandler",
AkkaHttpClientInstrumentation.class.getName() + "$AkkaHttpHeaders",
packageName + ".AkkaHttpClientDecorator",
packageName + ".AkkaHttpClientTracer",
};
}
@ -83,33 +81,30 @@ public final class AkkaHttpClientInstrumentation extends Instrumenter.Default {
public static class SingleRequestAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static SpanWithScope methodEnter(
@Advice.Argument(value = 0, readOnly = false) HttpRequest request) {
public static void methodEnter(
@Advice.Argument(value = 0, readOnly = false) HttpRequest request,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelScope") Scope scope,
@Advice.Local("otelCallDepth") Depth callDepth) {
/*
Versions 10.0 and 10.1 have slightly different structure that is hard to distinguish so here
we cast 'wider net' and avoid instrumenting twice.
In the future we may want to separate these, but since lots of code is reused we would need to come up
with way of continuing to reusing it.
*/
int callDepth = CallDepthThreadLocalMap.incrementCallDepth(HttpExt.class);
if (callDepth > 0) {
return null;
callDepth = TRACER.getCallDepth();
if (callDepth.getAndIncrement() == 0) {
span = TRACER.startSpan(request);
Context context = withSpan(span, Context.current());
if (request != null) {
AkkaHttpHeaders headers = new AkkaHttpHeaders(request);
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, request, headers);
// Request is immutable, so we have to assign new value once we update headers
request = headers.getRequest();
}
scope = withScopedContext(context);
}
Span span =
TRACER.spanBuilder(DECORATE.spanNameForRequest(request)).setSpanKind(CLIENT).startSpan();
DECORATE.afterStart(span);
DECORATE.onRequest(span, request);
Context context = withSpan(span, Context.current());
if (request != null) {
AkkaHttpHeaders headers = new AkkaHttpHeaders(request);
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, request, headers);
// Request is immutable, so we have to assign new value once we update headers
request = headers.getRequest();
}
return new SpanWithScope(span, withScopedContext(context));
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
@ -117,23 +112,18 @@ public final class AkkaHttpClientInstrumentation extends Instrumenter.Default {
@Advice.Argument(0) final HttpRequest request,
@Advice.This final HttpExt thiz,
@Advice.Return final Future<HttpResponse> responseFuture,
@Advice.Enter final SpanWithScope spanWithScope,
@Advice.Thrown final Throwable throwable) {
if (spanWithScope == null) {
return;
@Advice.Thrown final Throwable throwable,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelScope") Scope scope,
@Advice.Local("otelCallDepth") Depth callDepth) {
if (callDepth.decrementAndGet() == 0 && scope != null) {
scope.close();
if (throwable == null) {
responseFuture.onComplete(new OnCompleteHandler(span), thiz.system().dispatcher());
} else {
TRACER.endExceptionally(span, throwable);
}
}
CallDepthThreadLocalMap.reset(HttpExt.class);
Span span = spanWithScope.getSpan();
if (throwable == null) {
responseFuture.onComplete(new OnCompleteHandler(span), thiz.system().dispatcher());
} else {
DECORATE.onError(span, throwable);
DECORATE.beforeFinish(span);
span.end();
}
spanWithScope.closeScope();
}
}
@ -147,12 +137,10 @@ public final class AkkaHttpClientInstrumentation extends Instrumenter.Default {
@Override
public Void apply(final Try<HttpResponse> result) {
if (result.isSuccess()) {
DECORATE.onResponse(span, result.get());
TRACER.end(span, result.get());
} else {
DECORATE.onError(span, result.failed().get());
TRACER.endExceptionally(span, result.failed().get());
}
DECORATE.beforeFinish(span);
span.end();
return null;
}
}

View File

@ -17,19 +17,22 @@
package io.opentelemetry.auto.instrumentation.akkahttp;
import akka.http.javadsl.model.HttpHeader;
import akka.http.scaladsl.HttpExt;
import akka.http.scaladsl.model.HttpRequest;
import akka.http.scaladsl.model.HttpResponse;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap;
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap.Depth;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientTracer;
import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
import java.net.URI;
import java.net.URISyntaxException;
public class AkkaHttpClientDecorator extends HttpClientDecorator<HttpRequest, HttpResponse> {
public static final AkkaHttpClientDecorator DECORATE = new AkkaHttpClientDecorator();
public class AkkaHttpClientTracer extends HttpClientTracer<HttpRequest, HttpResponse> {
public static final AkkaHttpClientTracer TRACER = new AkkaHttpClientTracer();
public static final Tracer TRACER =
OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.akka-http-10.0");
public Depth getCallDepth() {
return CallDepthThreadLocalMap.getCallDepth(HttpExt.class);
}
@Override
protected String method(final HttpRequest httpRequest) {
@ -55,4 +58,14 @@ public class AkkaHttpClientDecorator extends HttpClientDecorator<HttpRequest, Ht
protected String responseHeader(HttpResponse httpResponse, String name) {
return httpResponse.getHeader(name).map(HttpHeader::value).orElse(null);
}
@Override
protected Setter<HttpRequest> getSetter() {
return null;
}
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.auto.akka-http-10.0";
}
}

View File

@ -16,14 +16,9 @@
package io.opentelemetry.auto.instrumentation.apachehttpclient.v2_0;
import static io.opentelemetry.auto.instrumentation.apachehttpclient.v2_0.CommonsHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.apachehttpclient.v2_0.CommonsHttpClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.apachehttpclient.v2_0.HttpHeadersInjectAdapter.SETTER;
import static io.opentelemetry.auto.instrumentation.apachehttpclient.v2_0.CommonsHttpClientTracer.TRACER;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
@ -31,10 +26,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.grpc.Context;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap;
import io.opentelemetry.auto.instrumentation.api.SpanWithScope;
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap.Depth;
import io.opentelemetry.auto.tooling.Instrumenter;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
@ -43,7 +35,6 @@ import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
@AutoService(Instrumenter.class)
@ -67,7 +58,7 @@ public class CommonsHttpClientInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".CommonsHttpClientDecorator", packageName + ".HttpHeadersInjectAdapter",
packageName + ".CommonsHttpClientTracer", packageName + ".HttpHeadersInjectAdapter",
};
}
@ -84,47 +75,36 @@ public class CommonsHttpClientInstrumentation extends Instrumenter.Default {
public static class ExecAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static SpanWithScope methodEnter(@Advice.Argument(1) final HttpMethod httpMethod) {
int callDepth = CallDepthThreadLocalMap.incrementCallDepth(HttpClient.class);
if (callDepth > 0) {
return null;
public static void methodEnter(
@Advice.Argument(1) final HttpMethod httpMethod,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelScope") Scope scope,
@Advice.Local("otelCallDepth") Depth callDepth) {
callDepth = TRACER.getCallDepth();
if (callDepth.getAndIncrement() == 0) {
span = TRACER.startSpan(httpMethod);
if (span.getContext().isValid()) {
scope = TRACER.startScope(span, httpMethod);
}
}
Span span =
TRACER
.spanBuilder(DECORATE.spanNameForRequest(httpMethod))
.setSpanKind(CLIENT)
.startSpan();
DECORATE.afterStart(span);
DECORATE.onRequest(span, httpMethod);
Context context = withSpan(span, Context.current());
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, httpMethod, SETTER);
Scope scope = withScopedContext(context);
return new SpanWithScope(span, scope);
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void methodExit(
@Advice.Enter final SpanWithScope spanWithScope,
@Advice.Argument(1) final HttpMethod httpMethod,
@Advice.Thrown final Throwable throwable) {
@Advice.Thrown final Throwable throwable,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelScope") Scope scope,
@Advice.Local("otelCallDepth") Depth callDepth) {
if (spanWithScope == null) {
return;
}
CallDepthThreadLocalMap.reset(HttpClient.class);
try {
Span span = spanWithScope.getSpan();
DECORATE.onResponse(span, httpMethod);
DECORATE.onError(span, throwable);
DECORATE.beforeFinish(span);
span.end();
} finally {
spanWithScope.closeScope();
if (callDepth.decrementAndGet() == 0 && scope != null) {
scope.close();
if (throwable == null) {
TRACER.end(span, httpMethod);
} else {
TRACER.endExceptionally(span, httpMethod, throwable);
}
}
}
}

View File

@ -16,21 +16,29 @@
package io.opentelemetry.auto.instrumentation.apachehttpclient.v2_0;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap;
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap.Depth;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientTracer;
import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.StatusLine;
import org.apache.commons.httpclient.URIException;
public class CommonsHttpClientDecorator extends HttpClientDecorator<HttpMethod, HttpMethod> {
public static final CommonsHttpClientDecorator DECORATE = new CommonsHttpClientDecorator();
public class CommonsHttpClientTracer extends HttpClientTracer<HttpMethod, HttpMethod> {
public static final CommonsHttpClientTracer TRACER = new CommonsHttpClientTracer();
public static final Tracer TRACER =
OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.apache-httpclient-2.0");
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.auto.apache-httpclient-2.0";
}
public Depth getCallDepth() {
return CallDepthThreadLocalMap.getCallDepth(HttpClient.class);
}
@Override
protected String method(final HttpMethod httpMethod) {
@ -64,4 +72,9 @@ public class CommonsHttpClientDecorator extends HttpClientDecorator<HttpMethod,
Header header = httpMethod.getResponseHeader(name);
return header != null ? header.getValue() : null;
}
@Override
protected Setter<HttpMethod> getSetter() {
return HttpHeadersInjectAdapter.SETTER;
}
}

View File

@ -30,7 +30,7 @@ import com.couchbase.client.java.transcoder.crypto.JsonCryptoTranscoder;
import com.google.auto.service.AutoService;
import io.opentelemetry.auto.bootstrap.ContextStore;
import io.opentelemetry.auto.bootstrap.InstrumentationContext;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseTracer;
import io.opentelemetry.auto.tooling.Instrumenter;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.attributes.SemanticAttributes;
@ -91,7 +91,7 @@ public class CouchbaseNetworkInstrumentation extends Instrumenter.Default {
Span span = contextStore.get(request);
if (span != null) {
BaseDecorator.setPeer(span, remoteHostname, null);
BaseTracer.setPeer(span, remoteHostname, null);
if (remoteSocket != null) {
int splitIndex = remoteSocket.lastIndexOf(":");

View File

@ -19,7 +19,7 @@ package io.opentelemetry.auto.instrumentation.elasticsearch.transport.v2_0;
import static io.opentelemetry.auto.instrumentation.elasticsearch.transport.ElasticsearchTransportClientDecorator.DECORATE;
import com.google.common.base.Joiner;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseTracer;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.attributes.SemanticAttributes;
import org.elasticsearch.action.ActionListener;
@ -70,7 +70,7 @@ public class TransportActionListener<T extends ActionResponse> implements Action
@Override
public void onResponse(final T response) {
if (response.remoteAddress() != null) {
BaseDecorator.setPeer(
BaseTracer.setPeer(
span, response.remoteAddress().getHost(), response.remoteAddress().getAddress());
span.setAttribute(SemanticAttributes.NET_PEER_PORT.key(), response.remoteAddress().getPort());
}

View File

@ -16,10 +16,10 @@
package io.opentelemetry.auto.instrumentation.elasticsearch.transport.v5_0;
import static io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseDecorator.setPeer;
import static io.opentelemetry.auto.instrumentation.elasticsearch.transport.ElasticsearchTransportClientDecorator.DECORATE;
import com.google.common.base.Joiner;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseTracer;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.attributes.SemanticAttributes;
import org.elasticsearch.action.ActionListener;
@ -72,7 +72,8 @@ public class TransportActionListener<T extends ActionResponse> implements Action
@Override
public void onResponse(final T response) {
if (response.remoteAddress() != null) {
setPeer(span, response.remoteAddress().getHost(), response.remoteAddress().getAddress());
BaseTracer.setPeer(
span, response.remoteAddress().getHost(), response.remoteAddress().getAddress());
span.setAttribute(SemanticAttributes.NET_PEER_PORT.key(), response.remoteAddress().getPort());
}

View File

@ -16,11 +16,8 @@
package io.opentelemetry.auto.instrumentation.googlehttpclient;
import static io.opentelemetry.auto.instrumentation.googlehttpclient.GoogleHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.googlehttpclient.GoogleHttpClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.googlehttpclient.GoogleHttpClientTracer.TRACER;
import static io.opentelemetry.auto.instrumentation.googlehttpclient.HeadersInjectAdapter.SETTER;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
@ -37,7 +34,6 @@ import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.ContextStore;
import io.opentelemetry.auto.bootstrap.InstrumentationContext;
import io.opentelemetry.auto.tooling.Instrumenter;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Status;
import java.util.HashMap;
@ -69,7 +65,7 @@ public class GoogleHttpClientInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".GoogleHttpClientDecorator",
packageName + ".GoogleHttpClientTracer",
packageName + ".RequestState",
packageName + ".HeadersInjectAdapter"
};
@ -103,20 +99,12 @@ public class GoogleHttpClientInstrumentation extends Instrumenter.Default {
RequestState state = contextStore.get(request);
if (state == null) {
state =
new RequestState(
TRACER
.spanBuilder(DECORATE.spanNameForRequest(request))
.setSpanKind(CLIENT)
.startSpan());
state = new RequestState(TRACER.startSpan(request));
contextStore.put(request, state);
}
Span span = state.getSpan();
DECORATE.afterStart(span);
DECORATE.onRequest(span, request);
Context context = withSpan(span, Context.current());
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, request, SETTER);
}
@ -134,18 +122,15 @@ public class GoogleHttpClientInstrumentation extends Instrumenter.Default {
if (state != null) {
Span span = state.getSpan();
try (Scope scope = currentContextWith(span)) {
DECORATE.onResponse(span, response);
DECORATE.onError(span, throwable);
// If HttpRequest.setThrowExceptionOnExecuteError is set to false, there are no exceptions
// for a failed request. Thus, check the response code
if (response != null && !response.isSuccessStatusCode()) {
span.setStatus(Status.UNKNOWN);
}
DECORATE.beforeFinish(span);
span.end();
if (throwable == null) {
TRACER.end(span, response);
} else {
TRACER.endExceptionally(span, response, throwable);
}
// If HttpRequest.setThrowExceptionOnExecuteError is set to false, there are no exceptions
// for a failed request. Thus, check the response code
if (response != null && !response.isSuccessStatusCode()) {
span.setStatus(Status.UNKNOWN);
}
}
}
@ -155,8 +140,7 @@ public class GoogleHttpClientInstrumentation extends Instrumenter.Default {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static void methodEnter(@Advice.This final HttpRequest request) {
Span span =
TRACER.spanBuilder(DECORATE.spanNameForRequest(request)).setSpanKind(CLIENT).startSpan();
Span span = TRACER.startSpan(request);
ContextStore<HttpRequest, RequestState> contextStore =
InstrumentationContext.get(HttpRequest.class, RequestState.class);
@ -178,12 +162,7 @@ public class GoogleHttpClientInstrumentation extends Instrumenter.Default {
if (state != null) {
Span span = state.getSpan();
try (Scope scope = currentContextWith(span)) {
DECORATE.onError(span, throwable);
DECORATE.beforeFinish(span);
span.end();
}
TRACER.endExceptionally(span, throwable);
}
}
}

View File

@ -19,17 +19,18 @@ package io.opentelemetry.auto.instrumentation.googlehttpclient;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpResponse;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientTracer;
import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
import java.net.URI;
import java.net.URISyntaxException;
public class GoogleHttpClientDecorator extends HttpClientDecorator<HttpRequest, HttpResponse> {
public static final GoogleHttpClientDecorator DECORATE = new GoogleHttpClientDecorator();
public class GoogleHttpClientTracer extends HttpClientTracer<HttpRequest, HttpResponse> {
public static final GoogleHttpClientTracer TRACER = new GoogleHttpClientTracer();
public static final Tracer TRACER =
OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.google-http-client-1.19");
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.auto.google-http-client-1.19";
}
@Override
protected String method(final HttpRequest httpRequest) {
@ -60,6 +61,11 @@ public class GoogleHttpClientDecorator extends HttpClientDecorator<HttpRequest,
return header(httpResponse.getHeaders(), name);
}
@Override
protected Setter<HttpRequest> getSetter() {
return HeadersInjectAdapter.SETTER;
}
private static String header(HttpHeaders headers, String name) {
return headers.getFirstHeaderStringValue(name);
}

View File

@ -16,25 +16,18 @@
package io.opentelemetry.auto.instrumentation.grizzly.client;
import static io.opentelemetry.auto.instrumentation.grizzly.client.ClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.grizzly.client.ClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.grizzly.client.InjectAdapter.SETTER;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.getSpan;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import static io.opentelemetry.auto.instrumentation.grizzly.client.GrizzlyClientTracer.TRACER;
import com.ning.http.client.AsyncHandler;
import com.ning.http.client.Request;
import io.grpc.Context;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.InstrumentationContext;
import io.opentelemetry.auto.bootstrap.instrumentation.api.Pair;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
import net.bytebuddy.asm.Advice;
public class ClientRequestAdvice {
public class GrizzlyClientRequestAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static Scope onEnter(
@ -42,22 +35,10 @@ public class ClientRequestAdvice {
@Advice.Argument(1) final AsyncHandler<?> handler) {
Context parentContext = Context.current();
Span span =
TRACER
.spanBuilder(DECORATE.spanNameForRequest(request))
.setSpanKind(CLIENT)
.setParent(getSpan(parentContext))
.startSpan();
DECORATE.afterStart(span);
DECORATE.onRequest(span, request);
Span span = TRACER.startSpan(request);
InstrumentationContext.get(AsyncHandler.class, Pair.class)
.put(handler, Pair.of(parentContext, span));
Context newContext = withSpan(span, parentContext);
OpenTelemetry.getPropagators().getHttpTextFormat().inject(newContext, request, SETTER);
return withScopedContext(newContext);
return TRACER.startScope(span, request);
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)

View File

@ -30,9 +30,9 @@ import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class)
public final class ClientRequestInstrumentation extends Instrumenter.Default {
public final class GrizzlyClientRequestInstrumentation extends Instrumenter.Default {
public ClientRequestInstrumentation() {
public GrizzlyClientRequestInstrumentation() {
super("grizzly-client", "ning");
}
@ -48,7 +48,9 @@ public final class ClientRequestInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {packageName + ".ClientDecorator", packageName + ".InjectAdapter"};
return new String[] {
packageName + ".GrizzlyClientTracer", packageName + ".GrizzlyInjectAdapter"
};
}
@Override
@ -63,6 +65,6 @@ public final class ClientRequestInstrumentation extends Instrumenter.Default {
.and(takesArgument(0, named("com.ning.http.client.Request")))
.and(takesArgument(1, named("com.ning.http.client.AsyncHandler")))
.and(isPublic()),
packageName + ".ClientRequestAdvice");
packageName + ".GrizzlyClientRequestAdvice");
}
}

View File

@ -16,7 +16,7 @@
package io.opentelemetry.auto.instrumentation.grizzly.client;
import static io.opentelemetry.auto.instrumentation.grizzly.client.ClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.grizzly.client.GrizzlyClientTracer.TRACER;
import com.ning.http.client.AsyncCompletionHandler;
import com.ning.http.client.AsyncHandler;
@ -30,7 +30,7 @@ import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
import net.bytebuddy.asm.Advice;
public class ClientResponseAdvice {
public class GrizzlyClientResponseAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static Scope onEnter(
@ -46,9 +46,7 @@ public class ClientResponseAdvice {
contextStore.put(handler, null);
}
if (spanWithParent.hasRight()) {
DECORATE.onResponse(spanWithParent.getRight(), response);
DECORATE.beforeFinish(spanWithParent.getRight());
spanWithParent.getRight().end();
TRACER.end(spanWithParent.getRight(), response);
}
return spanWithParent.hasLeft()
? ContextUtils.withScopedContext(spanWithParent.getLeft())

View File

@ -32,9 +32,9 @@ import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.matcher.ElementMatcher;
@AutoService(Instrumenter.class)
public final class ClientResponseInstrumentation extends Instrumenter.Default {
public final class GrizzlyClientResponseInstrumentation extends Instrumenter.Default {
public ClientResponseInstrumentation() {
public GrizzlyClientResponseInstrumentation() {
super("grizzly-client", "ning");
}
@ -60,7 +60,9 @@ public final class ClientResponseInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {packageName + ".ClientDecorator"};
return new String[] {
packageName + ".GrizzlyClientTracer", packageName + ".GrizzlyInjectAdapter"
};
}
@Override
@ -69,6 +71,6 @@ public final class ClientResponseInstrumentation extends Instrumenter.Default {
named("onCompleted")
.and(takesArgument(0, named("com.ning.http.client.Response")))
.and(isPublic()),
packageName + ".ClientResponseAdvice");
packageName + ".GrizzlyClientResponseAdvice");
}
}

View File

@ -18,18 +18,14 @@ package io.opentelemetry.auto.instrumentation.grizzly.client;
import com.ning.http.client.Request;
import com.ning.http.client.Response;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientTracer;
import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
import java.net.URI;
import java.net.URISyntaxException;
public class ClientDecorator extends HttpClientDecorator<Request, Response> {
public class GrizzlyClientTracer extends HttpClientTracer<Request, Response> {
public static final ClientDecorator DECORATE = new ClientDecorator();
public static final Tracer TRACER =
OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.grizzly-client-1.9");
public static final GrizzlyClientTracer TRACER = new GrizzlyClientTracer();
@Override
protected String method(final Request request) {
@ -55,4 +51,14 @@ public class ClientDecorator extends HttpClientDecorator<Request, Response> {
protected String responseHeader(Response response, String name) {
return response.getHeaders().getFirstValue(name);
}
@Override
protected Setter<Request> getSetter() {
return GrizzlyInjectAdapter.SETTER;
}
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.auto.grizzly-client-1.9";
}
}

View File

@ -19,9 +19,9 @@ package io.opentelemetry.auto.instrumentation.grizzly.client;
import com.ning.http.client.Request;
import io.opentelemetry.context.propagation.HttpTextFormat;
public class InjectAdapter implements HttpTextFormat.Setter<Request> {
public class GrizzlyInjectAdapter implements HttpTextFormat.Setter<Request> {
public static final InjectAdapter SETTER = new InjectAdapter();
public static final GrizzlyInjectAdapter SETTER = new GrizzlyInjectAdapter();
@Override
public void set(final Request carrier, final String key, final String value) {

View File

@ -17,7 +17,7 @@
package io.opentelemetry.auto.instrumentation.grpc.common;
import io.grpc.Status.Code;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseDecorator;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseTracer;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Status;
import io.opentelemetry.trace.Status.CanonicalCode;
@ -74,13 +74,13 @@ public final class GrpcHelper {
span.setAttribute(
SemanticAttributes.NET_PEER_IP.key(), peerAddress.getAddress().getHostAddress());
} else {
BaseDecorator.setPeer(span, peerAddress.getHostName(), null);
BaseTracer.setPeer(span, peerAddress.getHostName(), null);
}
} else {
// The spec says these fields must be populated, so put some values in even if we don't have
// an address recorded.
span.setAttribute(SemanticAttributes.NET_PEER_PORT.key(), 0);
BaseDecorator.setPeer(span, "(unknown)", null);
BaseTracer.setPeer(span, "(unknown)", null);
}
}

View File

@ -17,11 +17,9 @@
package io.opentelemetry.auto.instrumentation.httpurlconnection;
import static io.opentelemetry.auto.instrumentation.httpurlconnection.HeadersInjectAdapter.SETTER;
import static io.opentelemetry.auto.instrumentation.httpurlconnection.HttpUrlConnectionDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.httpurlconnection.HttpUrlConnectionDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.httpurlconnection.HttpUrlConnectionTracer.TRACER;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
import static io.opentelemetry.auto.tooling.matcher.NameMatchers.namedOneOf;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import static java.util.Collections.singletonMap;
@ -67,7 +65,7 @@ public class HttpUrlConnectionInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".HttpUrlConnectionDecorator",
packageName + ".HttpUrlConnectionTracer",
packageName + ".HeadersInjectAdapter",
HttpUrlConnectionInstrumentation.class.getName() + "$HttpUrlState",
HttpUrlConnectionInstrumentation.class.getName() + "$HttpUrlState$1",
@ -152,16 +150,8 @@ public class HttpUrlConnectionInstrumentation extends Instrumenter.Default {
private volatile boolean finished = false;
public Span start(final HttpURLConnection connection) {
span =
TRACER
.spanBuilder(DECORATE.spanNameForRequest(connection))
.setSpanKind(CLIENT)
.startSpan();
try (Scope scope = currentContextWith(span)) {
DECORATE.afterStart(span);
DECORATE.onRequest(span, connection);
return span;
}
span = TRACER.startSpan(connection);
return span;
}
public boolean hasSpan() {
@ -174,9 +164,7 @@ public class HttpUrlConnectionInstrumentation extends Instrumenter.Default {
public void finishSpan(final Throwable throwable) {
try (Scope scope = currentContextWith(span)) {
DECORATE.onError(span, throwable);
DECORATE.beforeFinish(span);
span.end();
TRACER.endExceptionally(span, throwable);
span = null;
finished = true;
}
@ -190,9 +178,7 @@ public class HttpUrlConnectionInstrumentation extends Instrumenter.Default {
*/
if (responseCode > 0) {
try (Scope scope = currentContextWith(span)) {
DECORATE.onResponse(span, responseCode);
DECORATE.beforeFinish(span);
span.end();
TRACER.end(span, responseCode);
span = null;
finished = true;
}

View File

@ -16,18 +16,17 @@
package io.opentelemetry.auto.instrumentation.httpurlconnection;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientTracer;
import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Span.Kind;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
public class HttpUrlConnectionDecorator extends HttpClientDecorator<HttpURLConnection, Integer> {
public class HttpUrlConnectionTracer extends HttpClientTracer<HttpURLConnection, Integer> {
public static final HttpUrlConnectionDecorator DECORATE = new HttpUrlConnectionDecorator();
public static final Tracer TRACER =
OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.http-url-connection");
public static final HttpUrlConnectionTracer TRACER = new HttpUrlConnectionTracer();
@Override
protected String method(final HttpURLConnection connection) {
@ -53,4 +52,23 @@ public class HttpUrlConnectionDecorator extends HttpClientDecorator<HttpURLConne
protected String responseHeader(Integer integer, String name) {
return null;
}
@Override
protected Setter<HttpURLConnection> getSetter() {
return null;
}
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.auto.http-url-connection";
}
/**
* This method is used to generate an acceptable CLIENT span (operation) name based on a given
* name.
*/
@Override
public Span startSpan(String spanName) {
return tracer.spanBuilder(spanName).setSpanKind(Kind.CLIENT).startSpan();
}
}

View File

@ -16,10 +16,7 @@
package io.opentelemetry.auto.instrumentation.httpurlconnection;
import static io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseDecorator.setPeer;
import static io.opentelemetry.auto.instrumentation.httpurlconnection.HttpUrlConnectionDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.httpurlconnection.HttpUrlConnectionDecorator.TRACER;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.auto.instrumentation.httpurlconnection.HttpUrlConnectionTracer.TRACER;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.is;
@ -29,6 +26,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
import com.google.auto.service.AutoService;
import io.opentelemetry.auto.bootstrap.InternalJarURLHandler;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseTracer;
import io.opentelemetry.auto.tooling.Instrumenter;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
@ -63,7 +61,7 @@ public class UrlInstrumentation extends Instrumenter.Default {
@Override
public String[] helperClassNames() {
return new String[] {
packageName + ".HttpUrlConnectionDecorator",
packageName + ".HttpUrlConnectionTracer",
};
}
@ -85,19 +83,17 @@ public class UrlInstrumentation extends Instrumenter.Default {
String protocol = url.getProtocol();
protocol = protocol != null ? protocol : "url";
Span span = TRACER.spanBuilder(protocol + ".request").setSpanKind(CLIENT).startSpan();
Span span = TRACER.startSpan(protocol + ".request");
try (Scope scope = currentContextWith(span)) {
span.setAttribute(SemanticAttributes.HTTP_URL.key(), url.toString());
span.setAttribute(
SemanticAttributes.NET_PEER_PORT.key(), url.getPort() == -1 ? 80 : url.getPort());
String host = url.getHost();
if (host != null && !host.isEmpty()) {
setPeer(span, host, null);
BaseTracer.setPeer(span, host, null);
}
DECORATE.onError(span, throwable);
span.end();
TRACER.endExceptionally(span, throwable);
}
}
}

View File

@ -16,68 +16,58 @@
package io.opentelemetry.auto.instrumentation.khttp;
import static io.opentelemetry.auto.instrumentation.khttp.KHttpDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.khttp.KHttpDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.khttp.KHttpHeadersInjectAdapter.SETTER;
import static io.opentelemetry.auto.instrumentation.khttp.KHttpHeadersInjectAdapter.asWritable;
import static io.opentelemetry.auto.instrumentation.khttp.KHttpTracer.TRACER;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import io.grpc.Context;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap;
import io.opentelemetry.auto.instrumentation.api.SpanWithScope;
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap.Depth;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
import java.util.Map;
import khttp.KHttp;
import khttp.responses.Response;
import net.bytebuddy.asm.Advice;
public class KHttpAdvice {
@Advice.OnMethodEnter(suppress = Throwable.class)
public static SpanWithScope methodEnter(
public static void methodEnter(
@Advice.Argument(value = 0) String method,
@Advice.Argument(value = 1) String uri,
@Advice.Argument(value = 2, readOnly = false) Map<String, String> headers) {
@Advice.Argument(value = 2, readOnly = false) Map<String, String> headers,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelScope") Scope scope,
@Advice.Local("otelCallDepth") Depth callDepth) {
int callDepth = CallDepthThreadLocalMap.incrementCallDepth(KHttp.class);
if (callDepth > 0) {
return null;
callDepth = TRACER.getCallDepth();
if (callDepth.getAndIncrement() == 0) {
span = TRACER.startSpan(new RequestWrapper(method, uri, headers));
if (span.getContext().isValid()) {
Context context = withSpan(span, Context.current());
headers = asWritable(headers);
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, headers, SETTER);
scope = withScopedContext(context);
}
}
Span span = TRACER.spanBuilder("HTTP " + method).setSpanKind(CLIENT).startSpan();
DECORATE.afterStart(span);
DECORATE.onRequest(span, new RequestWrapper(method, uri, headers));
Context context = withSpan(span, Context.current());
headers = asWritable(headers);
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, headers, SETTER);
return new SpanWithScope(span, withScopedContext(context));
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
public static void methodExit(
@Advice.Enter final SpanWithScope spanWithScope,
@Advice.Return final Response result,
@Advice.Thrown final Throwable throwable) {
if (spanWithScope == null) {
return;
}
CallDepthThreadLocalMap.reset(KHttp.class);
try {
Span span = spanWithScope.getSpan();
DECORATE.onResponse(span, result);
DECORATE.onError(span, throwable);
DECORATE.beforeFinish(span);
span.end();
} finally {
spanWithScope.closeScope();
@Advice.Return final Response response,
@Advice.Thrown final Throwable throwable,
@Advice.Local("otelSpan") Span span,
@Advice.Local("otelScope") Scope scope,
@Advice.Local("otelCallDepth") Depth callDepth) {
if (callDepth.decrementAndGet() == 0 && scope != null) {
scope.close();
if (throwable == null) {
TRACER.end(span, response);
} else {
TRACER.endExceptionally(span, response, throwable);
}
}
}
}

View File

@ -54,7 +54,7 @@ public class KHttpInstrumentation extends Instrumenter.Default {
public String[] helperClassNames() {
return new String[] {
packageName + ".KHttpHeadersInjectAdapter",
packageName + ".KHttpDecorator",
packageName + ".KHttpTracer",
packageName + ".RequestWrapper",
};
}

View File

@ -16,18 +16,21 @@
package io.opentelemetry.auto.instrumentation.khttp;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap;
import io.opentelemetry.auto.bootstrap.CallDepthThreadLocalMap.Depth;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientTracer;
import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
import java.net.URI;
import java.net.URISyntaxException;
import khttp.KHttp;
import khttp.responses.Response;
public class KHttpDecorator extends HttpClientDecorator<RequestWrapper, Response> {
public static final KHttpDecorator DECORATE = new KHttpDecorator();
public class KHttpTracer extends HttpClientTracer<RequestWrapper, Response> {
public static final KHttpTracer TRACER = new KHttpTracer();
public static final Tracer TRACER =
OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.khttp-0.1");
public Depth getCallDepth() {
return CallDepthThreadLocalMap.getCallDepth(KHttp.class);
}
@Override
protected String method(RequestWrapper requestWrapper) {
@ -53,4 +56,14 @@ public class KHttpDecorator extends HttpClientDecorator<RequestWrapper, Response
protected String responseHeader(Response response, String name) {
return response.getHeaders().get(name);
}
@Override
protected Setter<RequestWrapper> getSetter() {
return null;
}
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.auto.khttp-0.1";
}
}

View File

@ -18,7 +18,7 @@ package io.opentelemetry.auto.instrumentation.netty.v3_8;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
@ -27,7 +27,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.opentelemetry.auto.bootstrap.ContextStore;
import io.opentelemetry.auto.bootstrap.InstrumentationContext;
import io.opentelemetry.auto.instrumentation.netty.v3_8.client.NettyHttpClientDecorator;
import io.opentelemetry.auto.instrumentation.netty.v3_8.client.NettyHttpClientTracer;
import io.opentelemetry.auto.tooling.Instrumenter;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
@ -66,7 +66,8 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
packageName + ".AbstractNettyAdvice",
packageName + ".ChannelTraceContext",
packageName + ".ChannelTraceContext$Factory",
packageName + ".client.NettyHttpClientDecorator",
packageName + ".client.NettyHttpClientTracer",
packageName + ".client.NettyResponseInjectAdapter",
packageName + ".server.NettyHttpServerTracer",
packageName + ".server.NettyRequestExtractAdapter"
};
@ -111,16 +112,9 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
if (continuation == null) {
return null;
}
Scope parentScope = NettyHttpClientDecorator.TRACER.withSpan(continuation);
Span errorSpan =
NettyHttpClientDecorator.TRACER.spanBuilder("CONNECT").setSpanKind(CLIENT).startSpan();
try (Scope scope = NettyHttpClientDecorator.TRACER.withSpan(errorSpan)) {
NettyHttpClientDecorator.DECORATE.onError(errorSpan, cause);
NettyHttpClientDecorator.DECORATE.beforeFinish(errorSpan);
errorSpan.end();
}
Scope parentScope = currentContextWith(continuation);
Span errorSpan = NettyHttpClientTracer.TRACER.startSpan("CONNECT");
NettyHttpClientTracer.TRACER.endExceptionally(errorSpan, cause);
return parentScope;
}

View File

@ -82,7 +82,7 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
// Util
packageName + ".util.CombinedSimpleChannelHandler",
// client helpers
packageName + ".client.NettyHttpClientDecorator",
packageName + ".client.NettyHttpClientTracer",
packageName + ".client.NettyResponseInjectAdapter",
packageName + ".client.HttpClientRequestTracingHandler",
packageName + ".client.HttpClientResponseTracingHandler",

View File

@ -16,15 +16,15 @@
package io.opentelemetry.auto.instrumentation.netty.v3_8.client;
import static io.opentelemetry.auto.instrumentation.netty.v3_8.client.NettyHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.netty.v3_8.client.NettyHttpClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.netty.v3_8.client.NettyHttpClientTracer.TRACER;
import static io.opentelemetry.auto.instrumentation.netty.v3_8.client.NettyResponseInjectAdapter.SETTER;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import io.grpc.Context;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.ContextStore;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseTracer;
import io.opentelemetry.auto.instrumentation.netty.v3_8.ChannelTraceContext;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
@ -57,34 +57,25 @@ public class HttpClientRequestTracingHandler extends SimpleChannelDownstreamHand
Scope parentScope = null;
Span continuation = channelTraceContext.getConnectionContinuation();
if (continuation != null) {
parentScope = TRACER.withSpan(continuation);
parentScope = currentContextWith(continuation);
channelTraceContext.setConnectionContinuation(null);
}
channelTraceContext.setClientParentSpan(TRACER.getCurrentSpan());
HttpRequest request = (HttpRequest) msg.getMessage();
channelTraceContext.setClientParentSpan(TRACER.getCurrentSpan());
Span span = TRACER.startSpan(request);
BaseTracer.onPeerConnection(span, (InetSocketAddress) ctx.getChannel().getRemoteAddress());
Context context = withSpan(span, Context.current());
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, request.headers(), SETTER);
Span span =
TRACER.spanBuilder(DECORATE.spanNameForRequest(request)).setSpanKind(CLIENT).startSpan();
try (Scope scope = TRACER.withSpan(span)) {
DECORATE.afterStart(span);
DECORATE.onRequest(span, request);
DECORATE.onPeerConnection(span, (InetSocketAddress) ctx.getChannel().getRemoteAddress());
channelTraceContext.setClientSpan(span);
Context context = withSpan(span, Context.current());
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, request.headers(), SETTER);
channelTraceContext.setClientSpan(span);
try {
ctx.sendDownstream(msg);
} catch (final Throwable throwable) {
DECORATE.onError(span, throwable);
DECORATE.beforeFinish(span);
span.end();
throw throwable;
}
try (Scope scope = currentContextWith(span)) {
ctx.sendDownstream(msg);
} catch (final Throwable throwable) {
TRACER.endExceptionally(span, throwable);
throw throwable;
} finally {
if (parentScope != null) {
parentScope.close();

View File

@ -16,14 +16,14 @@
package io.opentelemetry.auto.instrumentation.netty.v3_8.client;
import static io.opentelemetry.auto.instrumentation.netty.v3_8.client.NettyHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.netty.v3_8.client.NettyHttpClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.netty.v3_8.client.NettyHttpClientTracer.TRACER;
import io.opentelemetry.auto.bootstrap.ContextStore;
import io.opentelemetry.auto.instrumentation.netty.v3_8.ChannelTraceContext;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.DefaultSpan;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.TracingContextUtils;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.MessageEvent;
@ -54,15 +54,11 @@ public class HttpClientResponseTracingHandler extends SimpleChannelUpstreamHandl
boolean finishSpan = msg.getMessage() instanceof HttpResponse;
if (span != null && finishSpan) {
try (Scope scope = TRACER.withSpan(span)) {
DECORATE.onResponse(span, (HttpResponse) msg.getMessage());
DECORATE.beforeFinish(span);
span.end();
}
TRACER.end(span, (HttpResponse) msg.getMessage());
}
// We want the callback in the scope of the parent, not the client span
try (Scope scope = TRACER.withSpan(parent)) {
try (Scope scope = TracingContextUtils.currentContextWith(parent)) {
ctx.sendUpstream(msg);
}
}

View File

@ -16,21 +16,24 @@
package io.opentelemetry.auto.instrumentation.netty.v3_8.client;
import static io.opentelemetry.auto.instrumentation.netty.v3_8.client.NettyResponseInjectAdapter.SETTER;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.HOST;
import io.grpc.Context;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientTracer;
import io.opentelemetry.context.Scope;
import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
import io.opentelemetry.trace.Span;
import java.net.URI;
import java.net.URISyntaxException;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
public class NettyHttpClientDecorator extends HttpClientDecorator<HttpRequest, HttpResponse> {
public static final NettyHttpClientDecorator DECORATE = new NettyHttpClientDecorator();
public static final Tracer TRACER =
OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.netty-3.8");
public class NettyHttpClientTracer extends HttpClientTracer<HttpRequest, HttpResponse> {
public static final NettyHttpClientTracer TRACER = new NettyHttpClientTracer();
@Override
protected String method(final HttpRequest httpRequest) {
@ -61,4 +64,21 @@ public class NettyHttpClientDecorator extends HttpClientDecorator<HttpRequest, H
protected String responseHeader(HttpResponse httpResponse, String name) {
return httpResponse.headers().get(name);
}
@Override
protected Setter<HttpRequest> getSetter() {
return null;
}
@Override
public Scope startScope(Span span, HttpRequest request) {
Context context = withSpan(span, Context.current());
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, request.headers(), SETTER);
return withScopedContext(context);
}
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.auto.netty-3.8";
}
}

View File

@ -18,7 +18,6 @@ package io.opentelemetry.auto.instrumentation.netty.v4_0;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
@ -27,7 +26,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.netty.channel.ChannelFuture;
import io.opentelemetry.auto.instrumentation.netty.v4_0.client.NettyHttpClientDecorator;
import io.opentelemetry.auto.instrumentation.netty.v4_0.client.NettyHttpClientTracer;
import io.opentelemetry.auto.tooling.Instrumenter;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
@ -63,7 +62,7 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
packageName + ".AttributeKeys",
packageName + ".AttributeKeys$1",
// client helpers
packageName + ".client.NettyHttpClientDecorator",
packageName + ".client.NettyHttpClientTracer",
packageName + ".client.NettyResponseInjectAdapter",
packageName + ".client.HttpClientRequestTracingHandler",
packageName + ".client.HttpClientResponseTracingHandler",
@ -104,15 +103,8 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
return null;
}
Scope parentScope = currentContextWith(parentSpan);
Span errorSpan =
NettyHttpClientDecorator.TRACER.spanBuilder("CONNECT").setSpanKind(CLIENT).startSpan();
try (Scope scope = currentContextWith(errorSpan)) {
NettyHttpClientDecorator.DECORATE.onError(errorSpan, cause);
NettyHttpClientDecorator.DECORATE.beforeFinish(errorSpan);
errorSpan.end();
}
Span span = NettyHttpClientTracer.TRACER.startSpan("CONNECT");
NettyHttpClientTracer.TRACER.endExceptionally(span, cause);
return parentScope;
}

View File

@ -78,7 +78,7 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
packageName + ".AttributeKeys",
packageName + ".AttributeKeys$1",
// client helpers
packageName + ".client.NettyHttpClientDecorator",
packageName + ".client.NettyHttpClientTracer",
packageName + ".client.NettyResponseInjectAdapter",
packageName + ".client.HttpClientRequestTracingHandler",
packageName + ".client.HttpClientResponseTracingHandler",

View File

@ -16,10 +16,8 @@
package io.opentelemetry.auto.instrumentation.netty.v4_0.client;
import static io.opentelemetry.auto.instrumentation.netty.v4_0.client.NettyHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.netty.v4_0.client.NettyHttpClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.netty.v4_0.client.NettyHttpClientTracer.TRACER;
import static io.opentelemetry.auto.instrumentation.netty.v4_0.client.NettyResponseInjectAdapter.SETTER;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
@ -29,6 +27,7 @@ import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.http.HttpRequest;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseTracer;
import io.opentelemetry.auto.instrumentation.netty.v4_0.AttributeKeys;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
@ -59,12 +58,9 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY).set(null);
}
Span span =
TRACER.spanBuilder(DECORATE.spanNameForRequest(request)).setSpanKind(CLIENT).startSpan();
try (Scope scope = TRACER.withSpan(span)) {
DECORATE.afterStart(span);
DECORATE.onRequest(span, request);
DECORATE.onPeerConnection(span, (InetSocketAddress) ctx.channel().remoteAddress());
Span span = TRACER.startSpan(request);
try (Scope scope = currentContextWith(span)) {
BaseTracer.onPeerConnection(span, (InetSocketAddress) ctx.channel().remoteAddress());
// AWS calls are often signed, so we can't add headers without breaking the signature.
if (!request.headers().contains("amz-sdk-invocation-id")) {
@ -79,9 +75,7 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
try {
ctx.write(msg, prm);
} catch (final Throwable throwable) {
DECORATE.onError(span, throwable);
DECORATE.beforeFinish(span);
span.end();
TRACER.endExceptionally(span, throwable);
throw throwable;
}
} finally {

View File

@ -16,7 +16,7 @@
package io.opentelemetry.auto.instrumentation.netty.v4_0.client;
import static io.opentelemetry.auto.instrumentation.netty.v4_0.client.NettyHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.netty.v4_0.client.NettyHttpClientTracer.TRACER;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import io.netty.channel.ChannelHandlerContext;
@ -41,9 +41,7 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt
if (span != null && finishSpan) {
try (Scope scope = currentContextWith(span)) {
DECORATE.onResponse(span, (HttpResponse) msg);
DECORATE.beforeFinish(span);
span.end();
TRACER.end(span, (HttpResponse) msg);
}
}

View File

@ -17,20 +17,23 @@
package io.opentelemetry.auto.instrumentation.netty.v4_0.client;
import static io.netty.handler.codec.http.HttpHeaders.Names.HOST;
import static io.opentelemetry.auto.instrumentation.netty.v4_0.client.NettyResponseInjectAdapter.SETTER;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import io.grpc.Context;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientTracer;
import io.opentelemetry.context.Scope;
import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
import io.opentelemetry.trace.Span;
import java.net.URI;
import java.net.URISyntaxException;
public class NettyHttpClientDecorator extends HttpClientDecorator<HttpRequest, HttpResponse> {
public static final NettyHttpClientDecorator DECORATE = new NettyHttpClientDecorator();
public static final Tracer TRACER =
OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.netty-4.0");
public class NettyHttpClientTracer extends HttpClientTracer<HttpRequest, HttpResponse> {
public static final NettyHttpClientTracer TRACER = new NettyHttpClientTracer();
@Override
protected String method(final HttpRequest httpRequest) {
@ -61,4 +64,21 @@ public class NettyHttpClientDecorator extends HttpClientDecorator<HttpRequest, H
protected String responseHeader(HttpResponse httpResponse, String name) {
return httpResponse.headers().get(name);
}
@Override
protected Setter<HttpRequest> getSetter() {
return null;
}
@Override
public Scope startScope(Span span, HttpRequest request) {
Context context = withSpan(span, Context.current());
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, request.headers(), SETTER);
return withScopedContext(context);
}
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.auto.netty-4.0";
}
}

View File

@ -18,7 +18,6 @@ package io.opentelemetry.auto.instrumentation.netty.v4_1;
import static io.opentelemetry.auto.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.auto.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
@ -27,7 +26,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.netty.channel.ChannelFuture;
import io.opentelemetry.auto.instrumentation.netty.v4_1.client.NettyHttpClientDecorator;
import io.opentelemetry.auto.instrumentation.netty.v4_1.client.NettyHttpClientTracer;
import io.opentelemetry.auto.tooling.Instrumenter;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
@ -63,7 +62,7 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
packageName + ".AttributeKeys",
packageName + ".AttributeKeys$1",
// client helpers
packageName + ".client.NettyHttpClientDecorator",
packageName + ".client.NettyHttpClientTracer",
packageName + ".client.NettyResponseInjectAdapter",
packageName + ".client.HttpClientRequestTracingHandler",
packageName + ".client.HttpClientResponseTracingHandler",
@ -104,15 +103,8 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
return null;
}
Scope parentScope = currentContextWith(parentSpan);
Span errorSpan =
NettyHttpClientDecorator.TRACER.spanBuilder("CONNECT").setSpanKind(CLIENT).startSpan();
try (Scope ignored = currentContextWith(errorSpan)) {
NettyHttpClientDecorator.DECORATE.onError(errorSpan, cause);
NettyHttpClientDecorator.DECORATE.beforeFinish(errorSpan);
errorSpan.end();
}
Span errorSpan = NettyHttpClientTracer.TRACER.startSpan("CONNECT");
NettyHttpClientTracer.TRACER.endExceptionally(errorSpan, cause);
return parentScope;
}

View File

@ -78,7 +78,7 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
packageName + ".AttributeKeys",
packageName + ".AttributeKeys$1",
// client helpers
packageName + ".client.NettyHttpClientDecorator",
packageName + ".client.NettyHttpClientTracer",
packageName + ".client.NettyResponseInjectAdapter",
packageName + ".client.HttpClientRequestTracingHandler",
packageName + ".client.HttpClientResponseTracingHandler",

View File

@ -16,10 +16,8 @@
package io.opentelemetry.auto.instrumentation.netty.v4_1.client;
import static io.opentelemetry.auto.instrumentation.netty.v4_1.client.NettyHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.netty.v4_1.client.NettyHttpClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.netty.v4_1.client.NettyHttpClientTracer.TRACER;
import static io.opentelemetry.auto.instrumentation.netty.v4_1.client.NettyResponseInjectAdapter.SETTER;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
@ -29,6 +27,7 @@ import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
import io.netty.handler.codec.http.HttpRequest;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.BaseTracer;
import io.opentelemetry.auto.instrumentation.netty.v4_1.AttributeKeys;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
@ -59,13 +58,9 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY).set(null);
}
Span span =
TRACER.spanBuilder(DECORATE.spanNameForRequest(request)).setSpanKind(CLIENT).startSpan();
try (Scope scope = TRACER.withSpan(span)) {
DECORATE.afterStart(span);
DECORATE.onRequest(span, request);
DECORATE.onPeerConnection(span, (InetSocketAddress) ctx.channel().remoteAddress());
Span span = TRACER.startSpan(request);
try (Scope scope = currentContextWith(span)) {
BaseTracer.onPeerConnection(span, (InetSocketAddress) ctx.channel().remoteAddress());
// AWS calls are often signed, so we can't add headers without breaking the signature.
if (!request.headers().contains("amz-sdk-invocation-id")) {
Context context = withSpan(span, Context.current());
@ -79,9 +74,7 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
try {
ctx.write(msg, prm);
} catch (final Throwable throwable) {
DECORATE.onError(span, throwable);
DECORATE.beforeFinish(span);
span.end();
TRACER.endExceptionally(span, throwable);
throw throwable;
}
} finally {

View File

@ -16,7 +16,7 @@
package io.opentelemetry.auto.instrumentation.netty.v4_1.client;
import static io.opentelemetry.auto.instrumentation.netty.v4_1.client.NettyHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.netty.v4_1.client.NettyHttpClientTracer.TRACER;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import io.netty.channel.ChannelHandlerContext;
@ -41,9 +41,7 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt
if (span != null && finishSpan) {
try (Scope scope = currentContextWith(span)) {
DECORATE.onResponse(span, (HttpResponse) msg);
DECORATE.beforeFinish(span);
span.end();
TRACER.end(span, (HttpResponse) msg);
}
}

View File

@ -17,20 +17,23 @@
package io.opentelemetry.auto.instrumentation.netty.v4_1.client;
import static io.netty.handler.codec.http.HttpHeaderNames.HOST;
import static io.opentelemetry.auto.instrumentation.netty.v4_1.client.NettyResponseInjectAdapter.SETTER;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import io.grpc.Context;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpResponse;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientTracer;
import io.opentelemetry.context.Scope;
import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
import io.opentelemetry.trace.Span;
import java.net.URI;
import java.net.URISyntaxException;
public class NettyHttpClientDecorator extends HttpClientDecorator<HttpRequest, HttpResponse> {
public static final NettyHttpClientDecorator DECORATE = new NettyHttpClientDecorator();
public static final Tracer TRACER =
OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.netty-4.1");
public class NettyHttpClientTracer extends HttpClientTracer<HttpRequest, HttpResponse> {
public static final NettyHttpClientTracer TRACER = new NettyHttpClientTracer();
@Override
protected String method(final HttpRequest httpRequest) {
@ -61,4 +64,21 @@ public class NettyHttpClientDecorator extends HttpClientDecorator<HttpRequest, H
protected String responseHeader(HttpResponse httpResponse, String name) {
return httpResponse.headers().get(name);
}
@Override
protected Setter<HttpRequest> getSetter() {
return null;
}
@Override
public Scope startScope(Span span, HttpRequest request) {
Context context = withSpan(span, Context.current());
OpenTelemetry.getPropagators().getHttpTextFormat().inject(context, request.headers(), SETTER);
return withScopedContext(context);
}
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.auto.netty-4.1";
}
}

View File

@ -45,7 +45,7 @@ public class OkHttp2Instrumentation extends Instrumenter.Default {
public String[] helperClassNames() {
return new String[] {
packageName + ".RequestBuilderInjectAdapter",
packageName + ".OkHttpClientDecorator",
packageName + ".OkHttpClientTracer",
packageName + ".TracingInterceptor",
};
}

View File

@ -18,17 +18,13 @@ package io.opentelemetry.auto.instrumentation.okhttp.v2_2;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientTracer;
import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
import java.net.URI;
import java.net.URISyntaxException;
public class OkHttpClientDecorator extends HttpClientDecorator<Request, Response> {
public static final OkHttpClientDecorator DECORATE = new OkHttpClientDecorator();
public static final Tracer TRACER =
OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.okhttp-2.2");
public class OkHttpClientTracer extends HttpClientTracer<Request, Response> {
public static final OkHttpClientTracer TRACER = new OkHttpClientTracer();
@Override
protected String method(final Request request) {
@ -54,4 +50,14 @@ public class OkHttpClientDecorator extends HttpClientDecorator<Request, Response
protected String responseHeader(Response response, String name) {
return response.header(name);
}
@Override
protected Setter<Request> getSetter() {
return null;
}
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.auto.okhttp-2.2";
}
}

View File

@ -16,10 +16,8 @@
package io.opentelemetry.auto.instrumentation.okhttp.v2_2;
import static io.opentelemetry.auto.instrumentation.okhttp.v2_2.OkHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.okhttp.v2_2.OkHttpClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.okhttp.v2_2.OkHttpClientTracer.TRACER;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import com.squareup.okhttp.Interceptor;
@ -34,17 +32,8 @@ import java.io.IOException;
public class TracingInterceptor implements Interceptor {
@Override
public Response intercept(final Chain chain) throws IOException {
Span span =
TRACER
.spanBuilder(DECORATE.spanNameForRequest(chain.request()))
.setSpanKind(CLIENT)
.startSpan();
DECORATE.afterStart(span);
DECORATE.onRequest(span, chain.request());
Span span = TRACER.startSpan(chain.request());
Context context = withSpan(span, Context.current());
Request.Builder requestBuilder = chain.request().newBuilder();
OpenTelemetry.getPropagators()
.getHttpTextFormat()
@ -54,13 +43,10 @@ public class TracingInterceptor implements Interceptor {
try (Scope scope = withScopedContext(context)) {
response = chain.proceed(requestBuilder.build());
} catch (final Exception e) {
DECORATE.onError(span, e);
span.end();
TRACER.endExceptionally(span, e);
throw e;
}
DECORATE.onResponse(span, response);
DECORATE.beforeFinish(span);
span.end();
TRACER.end(span, response);
return response;
}
}

View File

@ -47,7 +47,7 @@ public class OkHttp3Instrumentation extends Instrumenter.Default {
public String[] helperClassNames() {
return new String[] {
packageName + ".RequestBuilderInjectAdapter",
packageName + ".OkHttpClientDecorator",
packageName + ".OkHttpClientTracer",
packageName + ".TracingInterceptor",
};
}

View File

@ -16,18 +16,14 @@
package io.opentelemetry.auto.instrumentation.okhttp.v3_0;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientDecorator;
import io.opentelemetry.trace.Tracer;
import io.opentelemetry.auto.bootstrap.instrumentation.decorator.HttpClientTracer;
import io.opentelemetry.context.propagation.HttpTextFormat.Setter;
import java.net.URI;
import okhttp3.Request;
import okhttp3.Response;
public class OkHttpClientDecorator extends HttpClientDecorator<Request, Response> {
public static final OkHttpClientDecorator DECORATE = new OkHttpClientDecorator();
public static final Tracer TRACER =
OpenTelemetry.getTracerProvider().get("io.opentelemetry.auto.okhttp-3.0");
public class OkHttpClientTracer extends HttpClientTracer<Request, Response> {
public static final OkHttpClientTracer TRACER = new OkHttpClientTracer();
@Override
protected String method(final Request httpRequest) {
@ -53,4 +49,14 @@ public class OkHttpClientDecorator extends HttpClientDecorator<Request, Response
protected String responseHeader(Response response, String name) {
return response.header(name);
}
@Override
protected Setter<Request> getSetter() {
return null;
}
@Override
protected String getInstrumentationName() {
return "io.opentelemetry.auto.okhttp-3.0";
}
}

View File

@ -16,10 +16,8 @@
package io.opentelemetry.auto.instrumentation.okhttp.v3_0;
import static io.opentelemetry.auto.instrumentation.okhttp.v3_0.OkHttpClientDecorator.DECORATE;
import static io.opentelemetry.auto.instrumentation.okhttp.v3_0.OkHttpClientDecorator.TRACER;
import static io.opentelemetry.auto.instrumentation.okhttp.v3_0.OkHttpClientTracer.TRACER;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.trace.Span.Kind.CLIENT;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import io.grpc.Context;
@ -35,15 +33,7 @@ public class TracingInterceptor implements Interceptor {
@Override
public Response intercept(final Chain chain) throws IOException {
Span span =
TRACER
.spanBuilder(DECORATE.spanNameForRequest(chain.request()))
.setSpanKind(CLIENT)
.startSpan();
DECORATE.afterStart(span);
DECORATE.onRequest(span, chain.request());
Span span = TRACER.startSpan(chain.request());
Context context = withSpan(span, Context.current());
Request.Builder requestBuilder = chain.request().newBuilder();
@ -55,13 +45,10 @@ public class TracingInterceptor implements Interceptor {
try (Scope scope = withScopedContext(context)) {
response = chain.proceed(requestBuilder.build());
} catch (final Exception e) {
DECORATE.onError(span, e);
span.end();
TRACER.endExceptionally(span, e);
throw e;
}
DECORATE.onResponse(span, response);
DECORATE.beforeFinish(span);
span.end();
TRACER.end(span, response);
return response;
}
}