Update netty-4.0 to new agent api
This commit is contained in:
parent
b576c394af
commit
bb500f9c54
|
@ -2,10 +2,10 @@ package datadog.trace.instrumentation.netty40;
|
||||||
|
|
||||||
import datadog.trace.bootstrap.WeakMap;
|
import datadog.trace.bootstrap.WeakMap;
|
||||||
import datadog.trace.context.TraceScope;
|
import datadog.trace.context.TraceScope;
|
||||||
|
import datadog.trace.instrumentation.api.AgentSpan;
|
||||||
import datadog.trace.instrumentation.netty40.client.HttpClientTracingHandler;
|
import datadog.trace.instrumentation.netty40.client.HttpClientTracingHandler;
|
||||||
import datadog.trace.instrumentation.netty40.server.HttpServerTracingHandler;
|
import datadog.trace.instrumentation.netty40.server.HttpServerTracingHandler;
|
||||||
import io.netty.util.AttributeKey;
|
import io.netty.util.AttributeKey;
|
||||||
import io.opentracing.Span;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@ -26,13 +26,13 @@ public class AttributeKeys {
|
||||||
PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY =
|
PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY =
|
||||||
attributeKey("datadog.trace.instrumentation.netty40.parent.connect.continuation");
|
attributeKey("datadog.trace.instrumentation.netty40.parent.connect.continuation");
|
||||||
|
|
||||||
public static final AttributeKey<Span> SERVER_ATTRIBUTE_KEY =
|
public static final AttributeKey<AgentSpan> SERVER_ATTRIBUTE_KEY =
|
||||||
attributeKey(HttpServerTracingHandler.class.getName() + ".span");
|
attributeKey(HttpServerTracingHandler.class.getName() + ".span");
|
||||||
|
|
||||||
public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY =
|
public static final AttributeKey<AgentSpan> CLIENT_ATTRIBUTE_KEY =
|
||||||
attributeKey(HttpClientTracingHandler.class.getName() + ".span");
|
attributeKey(HttpClientTracingHandler.class.getName() + ".span");
|
||||||
|
|
||||||
public static final AttributeKey<Span> CLIENT_PARENT_ATTRIBUTE_KEY =
|
public static final AttributeKey<AgentSpan> CLIENT_PARENT_ATTRIBUTE_KEY =
|
||||||
attributeKey(HttpClientTracingHandler.class.getName() + ".parent");
|
attributeKey(HttpClientTracingHandler.class.getName() + ".parent");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package datadog.trace.instrumentation.netty40;
|
package datadog.trace.instrumentation.netty40;
|
||||||
|
|
||||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||||
|
import static datadog.trace.instrumentation.api.AgentTracer.activateSpan;
|
||||||
|
import static datadog.trace.instrumentation.api.AgentTracer.startSpan;
|
||||||
import static java.util.Collections.singletonMap;
|
import static java.util.Collections.singletonMap;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
|
@ -11,12 +13,11 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import datadog.trace.agent.tooling.Instrumenter;
|
import datadog.trace.agent.tooling.Instrumenter;
|
||||||
import datadog.trace.context.TraceScope;
|
import datadog.trace.context.TraceScope;
|
||||||
|
import datadog.trace.instrumentation.api.AgentScope;
|
||||||
|
import datadog.trace.instrumentation.api.AgentSpan;
|
||||||
import datadog.trace.instrumentation.netty40.server.NettyHttpServerDecorator;
|
import datadog.trace.instrumentation.netty40.server.NettyHttpServerDecorator;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.opentracing.Scope;
|
|
||||||
import io.opentracing.Span;
|
|
||||||
import io.opentracing.tag.Tags;
|
import io.opentracing.tag.Tags;
|
||||||
import io.opentracing.util.GlobalTracer;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
import net.bytebuddy.description.method.MethodDescription;
|
import net.bytebuddy.description.method.MethodDescription;
|
||||||
|
@ -94,12 +95,9 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
|
||||||
}
|
}
|
||||||
final TraceScope parentScope = continuation.activate();
|
final TraceScope parentScope = continuation.activate();
|
||||||
|
|
||||||
final Span errorSpan =
|
final AgentSpan errorSpan =
|
||||||
GlobalTracer.get()
|
startSpan("netty.connect").setTag(Tags.COMPONENT.getKey(), "netty");
|
||||||
.buildSpan("netty.connect")
|
try (final AgentScope scope = activateSpan(errorSpan, false)) {
|
||||||
.withTag(Tags.COMPONENT.getKey(), "netty")
|
|
||||||
.start();
|
|
||||||
try (final Scope scope = GlobalTracer.get().scopeManager().activate(errorSpan, false)) {
|
|
||||||
NettyHttpServerDecorator.DECORATE.onError(errorSpan, cause);
|
NettyHttpServerDecorator.DECORATE.onError(errorSpan, cause);
|
||||||
NettyHttpServerDecorator.DECORATE.beforeFinish(errorSpan);
|
NettyHttpServerDecorator.DECORATE.beforeFinish(errorSpan);
|
||||||
errorSpan.finish();
|
errorSpan.finish();
|
||||||
|
@ -111,7 +109,7 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void deactivateScope(@Advice.Enter final TraceScope scope) {
|
public static void deactivateScope(@Advice.Enter final TraceScope scope) {
|
||||||
if (scope != null) {
|
if (scope != null) {
|
||||||
((Scope) scope).close();
|
scope.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package datadog.trace.instrumentation.netty40;
|
package datadog.trace.instrumentation.netty40;
|
||||||
|
|
||||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||||
|
import static datadog.trace.instrumentation.api.AgentTracer.activeScope;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
|
||||||
|
@ -28,8 +29,6 @@ import io.netty.handler.codec.http.HttpResponseDecoder;
|
||||||
import io.netty.handler.codec.http.HttpResponseEncoder;
|
import io.netty.handler.codec.http.HttpResponseEncoder;
|
||||||
import io.netty.handler.codec.http.HttpServerCodec;
|
import io.netty.handler.codec.http.HttpServerCodec;
|
||||||
import io.netty.util.Attribute;
|
import io.netty.util.Attribute;
|
||||||
import io.opentracing.Scope;
|
|
||||||
import io.opentracing.util.GlobalTracer;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
@ -149,9 +148,9 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
|
||||||
public static class ChannelPipelineConnectAdvice {
|
public static class ChannelPipelineConnectAdvice {
|
||||||
@Advice.OnMethodEnter
|
@Advice.OnMethodEnter
|
||||||
public static void addParentSpan(@Advice.This final ChannelPipeline pipeline) {
|
public static void addParentSpan(@Advice.This final ChannelPipeline pipeline) {
|
||||||
final Scope scope = GlobalTracer.get().scopeManager().active();
|
final TraceScope scope = activeScope();
|
||||||
if (scope instanceof TraceScope) {
|
if (scope != null) {
|
||||||
final TraceScope.Continuation continuation = ((TraceScope) scope).capture();
|
final TraceScope.Continuation continuation = scope.capture();
|
||||||
if (null != continuation) {
|
if (null != continuation) {
|
||||||
final Attribute<TraceScope.Continuation> attribute =
|
final Attribute<TraceScope.Continuation> attribute =
|
||||||
pipeline.channel().attr(AttributeKeys.PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY);
|
pipeline.channel().attr(AttributeKeys.PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY);
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
package datadog.trace.instrumentation.netty40.client;
|
package datadog.trace.instrumentation.netty40.client;
|
||||||
|
|
||||||
|
import static datadog.trace.instrumentation.api.AgentTracer.activateSpan;
|
||||||
|
import static datadog.trace.instrumentation.api.AgentTracer.activeSpan;
|
||||||
|
import static datadog.trace.instrumentation.api.AgentTracer.propagate;
|
||||||
|
import static datadog.trace.instrumentation.api.AgentTracer.startSpan;
|
||||||
import static datadog.trace.instrumentation.netty40.client.NettyHttpClientDecorator.DECORATE;
|
import static datadog.trace.instrumentation.netty40.client.NettyHttpClientDecorator.DECORATE;
|
||||||
|
import static datadog.trace.instrumentation.netty40.client.NettyResponseInjectAdapter.SETTER;
|
||||||
|
|
||||||
import datadog.trace.context.TraceScope;
|
import datadog.trace.context.TraceScope;
|
||||||
|
import datadog.trace.instrumentation.api.AgentScope;
|
||||||
|
import datadog.trace.instrumentation.api.AgentSpan;
|
||||||
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.handler.codec.http.HttpRequest;
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
import io.opentracing.Scope;
|
|
||||||
import io.opentracing.Span;
|
|
||||||
import io.opentracing.Tracer;
|
|
||||||
import io.opentracing.propagation.Format;
|
|
||||||
import io.opentracing.util.GlobalTracer;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@ -35,19 +37,17 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
|
|
||||||
final HttpRequest request = (HttpRequest) msg;
|
final HttpRequest request = (HttpRequest) msg;
|
||||||
|
|
||||||
final Tracer tracer = GlobalTracer.get();
|
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY).set(activeSpan());
|
||||||
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY).set(tracer.activeSpan());
|
|
||||||
|
|
||||||
final Span span = tracer.buildSpan("netty.client.request").start();
|
final AgentSpan span = startSpan("netty.client.request");
|
||||||
try (final Scope scope = tracer.scopeManager().activate(span, false)) {
|
try (final AgentScope scope = activateSpan(span, false)) {
|
||||||
DECORATE.afterStart(span);
|
DECORATE.afterStart(span);
|
||||||
DECORATE.onRequest(span, request);
|
DECORATE.onRequest(span, request);
|
||||||
DECORATE.onPeerConnection(span, (InetSocketAddress) ctx.channel().remoteAddress());
|
DECORATE.onPeerConnection(span, (InetSocketAddress) ctx.channel().remoteAddress());
|
||||||
|
|
||||||
// AWS calls are often signed, so we can't add headers without breaking the signature.
|
// AWS calls are often signed, so we can't add headers without breaking the signature.
|
||||||
if (!request.headers().contains("amz-sdk-invocation-id")) {
|
if (!request.headers().contains("amz-sdk-invocation-id")) {
|
||||||
tracer.inject(
|
propagate().inject(span, request, SETTER);
|
||||||
span.context(), Format.Builtin.HTTP_HEADERS, new NettyResponseInjectAdapter(request));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.channel().attr(AttributeKeys.CLIENT_ATTRIBUTE_KEY).set(span);
|
ctx.channel().attr(AttributeKeys.CLIENT_ATTRIBUTE_KEY).set(span);
|
||||||
|
|
|
@ -1,32 +1,31 @@
|
||||||
package datadog.trace.instrumentation.netty40.client;
|
package datadog.trace.instrumentation.netty40.client;
|
||||||
|
|
||||||
|
import static datadog.trace.instrumentation.api.AgentTracer.activateSpan;
|
||||||
|
import static datadog.trace.instrumentation.api.AgentTracer.noopSpan;
|
||||||
import static datadog.trace.instrumentation.netty40.client.NettyHttpClientDecorator.DECORATE;
|
import static datadog.trace.instrumentation.netty40.client.NettyHttpClientDecorator.DECORATE;
|
||||||
|
|
||||||
import datadog.trace.context.TraceScope;
|
import datadog.trace.instrumentation.api.AgentScope;
|
||||||
|
import datadog.trace.instrumentation.api.AgentSpan;
|
||||||
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
import io.netty.handler.codec.http.HttpResponse;
|
import io.netty.handler.codec.http.HttpResponse;
|
||||||
import io.netty.util.Attribute;
|
import io.netty.util.Attribute;
|
||||||
import io.opentracing.Scope;
|
|
||||||
import io.opentracing.Span;
|
|
||||||
import io.opentracing.noop.NoopSpan;
|
|
||||||
import io.opentracing.util.GlobalTracer;
|
|
||||||
|
|
||||||
public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapter {
|
public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
|
public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
|
||||||
final Attribute<Span> parentAttr =
|
final Attribute<AgentSpan> parentAttr =
|
||||||
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY);
|
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY);
|
||||||
parentAttr.setIfAbsent(NoopSpan.INSTANCE);
|
parentAttr.setIfAbsent(noopSpan());
|
||||||
final Span parent = parentAttr.get();
|
final AgentSpan parent = parentAttr.get();
|
||||||
final Span span = ctx.channel().attr(AttributeKeys.CLIENT_ATTRIBUTE_KEY).get();
|
final AgentSpan span = ctx.channel().attr(AttributeKeys.CLIENT_ATTRIBUTE_KEY).get();
|
||||||
|
|
||||||
final boolean finishSpan = msg instanceof HttpResponse;
|
final boolean finishSpan = msg instanceof HttpResponse;
|
||||||
|
|
||||||
if (span != null && finishSpan) {
|
if (span != null && finishSpan) {
|
||||||
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
try (final AgentScope scope = activateSpan(span, false)) {
|
||||||
DECORATE.onResponse(span, (HttpResponse) msg);
|
DECORATE.onResponse(span, (HttpResponse) msg);
|
||||||
DECORATE.beforeFinish(span);
|
DECORATE.beforeFinish(span);
|
||||||
span.finish();
|
span.finish();
|
||||||
|
@ -34,10 +33,8 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt
|
||||||
}
|
}
|
||||||
|
|
||||||
// We want the callback in the scope of the parent, not the client span
|
// We want the callback in the scope of the parent, not the client span
|
||||||
try (final Scope scope = GlobalTracer.get().scopeManager().activate(parent, false)) {
|
try (final AgentScope scope = activateSpan(parent, false)) {
|
||||||
if (scope instanceof TraceScope) {
|
scope.setAsyncPropagation(true);
|
||||||
((TraceScope) scope).setAsyncPropagation(true);
|
|
||||||
}
|
|
||||||
ctx.fireChannelRead(msg);
|
ctx.fireChannelRead(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,14 @@
|
||||||
package datadog.trace.instrumentation.netty40.client;
|
package datadog.trace.instrumentation.netty40.client;
|
||||||
|
|
||||||
import io.netty.handler.codec.http.HttpHeaders;
|
import datadog.trace.instrumentation.api.AgentPropagation;
|
||||||
import io.netty.handler.codec.http.HttpRequest;
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
import io.opentracing.propagation.TextMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class NettyResponseInjectAdapter implements TextMap {
|
public class NettyResponseInjectAdapter implements AgentPropagation.Setter<HttpRequest> {
|
||||||
private final HttpHeaders headers;
|
|
||||||
|
|
||||||
NettyResponseInjectAdapter(final HttpRequest request) {
|
public static final NettyResponseInjectAdapter SETTER = new NettyResponseInjectAdapter();
|
||||||
this.headers = request.headers();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Map.Entry<String, String>> iterator() {
|
public void set(final HttpRequest carrier, final String key, final String value) {
|
||||||
throw new UnsupportedOperationException("This class should be used only with Tracer.inject()!");
|
carrier.headers().set(key, value);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void put(final String key, final String value) {
|
|
||||||
headers.set(key, value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,34 +1,31 @@
|
||||||
package datadog.trace.instrumentation.netty40.server;
|
package datadog.trace.instrumentation.netty40.server;
|
||||||
|
|
||||||
|
import static datadog.trace.instrumentation.api.AgentTracer.activateSpan;
|
||||||
|
import static datadog.trace.instrumentation.api.AgentTracer.propagate;
|
||||||
|
import static datadog.trace.instrumentation.api.AgentTracer.startSpan;
|
||||||
import static datadog.trace.instrumentation.netty40.server.NettyHttpServerDecorator.DECORATE;
|
import static datadog.trace.instrumentation.netty40.server.NettyHttpServerDecorator.DECORATE;
|
||||||
|
import static datadog.trace.instrumentation.netty40.server.NettyRequestExtractAdapter.GETTER;
|
||||||
|
|
||||||
import datadog.trace.context.TraceScope;
|
import datadog.trace.instrumentation.api.AgentScope;
|
||||||
|
import datadog.trace.instrumentation.api.AgentSpan;
|
||||||
|
import datadog.trace.instrumentation.api.AgentSpan.Context;
|
||||||
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
import io.netty.handler.codec.http.HttpRequest;
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
import io.opentracing.Scope;
|
|
||||||
import io.opentracing.Span;
|
|
||||||
import io.opentracing.SpanContext;
|
|
||||||
import io.opentracing.Tracer;
|
|
||||||
import io.opentracing.propagation.Format;
|
|
||||||
import io.opentracing.util.GlobalTracer;
|
|
||||||
|
|
||||||
public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapter {
|
public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
|
public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
|
||||||
final Tracer tracer = GlobalTracer.get();
|
|
||||||
|
|
||||||
if (!(msg instanceof HttpRequest)) {
|
if (!(msg instanceof HttpRequest)) {
|
||||||
final Span span = ctx.channel().attr(AttributeKeys.SERVER_ATTRIBUTE_KEY).get();
|
final AgentSpan span = ctx.channel().attr(AttributeKeys.SERVER_ATTRIBUTE_KEY).get();
|
||||||
if (span == null) {
|
if (span == null) {
|
||||||
ctx.fireChannelRead(msg); // superclass does not throw
|
ctx.fireChannelRead(msg); // superclass does not throw
|
||||||
} else {
|
} else {
|
||||||
try (final Scope scope = tracer.scopeManager().activate(span, false)) {
|
try (final AgentScope scope = activateSpan(span, false)) {
|
||||||
if (scope instanceof TraceScope) {
|
scope.setAsyncPropagation(true);
|
||||||
((TraceScope) scope).setAsyncPropagation(true);
|
|
||||||
}
|
|
||||||
ctx.fireChannelRead(msg); // superclass does not throw
|
ctx.fireChannelRead(msg); // superclass does not throw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,19 +34,15 @@ public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapte
|
||||||
|
|
||||||
final HttpRequest request = (HttpRequest) msg;
|
final HttpRequest request = (HttpRequest) msg;
|
||||||
|
|
||||||
final SpanContext extractedContext =
|
final Context context = propagate().extract(request, GETTER);
|
||||||
tracer.extract(Format.Builtin.HTTP_HEADERS, new NettyRequestExtractAdapter(request));
|
|
||||||
|
|
||||||
final Span span =
|
final AgentSpan span = startSpan("netty.request", context);
|
||||||
tracer.buildSpan("netty.request").asChildOf(extractedContext).ignoreActiveSpan().start();
|
try (final AgentScope scope = activateSpan(span, false)) {
|
||||||
try (final Scope scope = tracer.scopeManager().activate(span, false)) {
|
|
||||||
DECORATE.afterStart(span);
|
DECORATE.afterStart(span);
|
||||||
DECORATE.onConnection(span, ctx.channel());
|
DECORATE.onConnection(span, ctx.channel());
|
||||||
DECORATE.onRequest(span, request);
|
DECORATE.onRequest(span, request);
|
||||||
|
|
||||||
if (scope instanceof TraceScope) {
|
scope.setAsyncPropagation(true);
|
||||||
((TraceScope) scope).setAsyncPropagation(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.channel().attr(AttributeKeys.SERVER_ATTRIBUTE_KEY).set(span);
|
ctx.channel().attr(AttributeKeys.SERVER_ATTRIBUTE_KEY).set(span);
|
||||||
|
|
||||||
|
|
|
@ -2,19 +2,19 @@ package datadog.trace.instrumentation.netty40.server;
|
||||||
|
|
||||||
import static datadog.trace.instrumentation.netty40.server.NettyHttpServerDecorator.DECORATE;
|
import static datadog.trace.instrumentation.netty40.server.NettyHttpServerDecorator.DECORATE;
|
||||||
|
|
||||||
|
import datadog.trace.instrumentation.api.AgentSpan;
|
||||||
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.handler.codec.http.HttpResponse;
|
import io.netty.handler.codec.http.HttpResponse;
|
||||||
import io.opentracing.Span;
|
|
||||||
import io.opentracing.tag.Tags;
|
import io.opentracing.tag.Tags;
|
||||||
|
|
||||||
public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdapter {
|
public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdapter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise prm) {
|
public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise prm) {
|
||||||
final Span span = ctx.channel().attr(AttributeKeys.SERVER_ATTRIBUTE_KEY).get();
|
final AgentSpan span = ctx.channel().attr(AttributeKeys.SERVER_ATTRIBUTE_KEY).get();
|
||||||
if (span == null || !(msg instanceof HttpResponse)) {
|
if (span == null || !(msg instanceof HttpResponse)) {
|
||||||
ctx.write(msg, prm);
|
ctx.write(msg, prm);
|
||||||
return;
|
return;
|
||||||
|
@ -26,7 +26,7 @@ public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdap
|
||||||
ctx.write(msg, prm);
|
ctx.write(msg, prm);
|
||||||
} catch (final Throwable throwable) {
|
} catch (final Throwable throwable) {
|
||||||
DECORATE.onError(span, throwable);
|
DECORATE.onError(span, throwable);
|
||||||
Tags.HTTP_STATUS.set(span, 500);
|
span.setTag(Tags.HTTP_STATUS.getKey(), 500);
|
||||||
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
||||||
throw throwable;
|
throw throwable;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,19 @@
|
||||||
package datadog.trace.instrumentation.netty40.server;
|
package datadog.trace.instrumentation.netty40.server;
|
||||||
|
|
||||||
import io.netty.handler.codec.http.HttpHeaders;
|
import datadog.trace.instrumentation.api.AgentPropagation;
|
||||||
import io.netty.handler.codec.http.HttpRequest;
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
import io.opentracing.propagation.TextMap;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public class NettyRequestExtractAdapter implements TextMap {
|
public class NettyRequestExtractAdapter implements AgentPropagation.Getter<HttpRequest> {
|
||||||
private final HttpHeaders headers;
|
|
||||||
|
|
||||||
NettyRequestExtractAdapter(final HttpRequest request) {
|
public static final NettyRequestExtractAdapter GETTER = new NettyRequestExtractAdapter();
|
||||||
this.headers = request.headers();
|
|
||||||
|
@Override
|
||||||
|
public Iterable<String> keys(final HttpRequest carrier) {
|
||||||
|
return carrier.headers().names();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Map.Entry<String, String>> iterator() {
|
public String get(final HttpRequest carrier, final String key) {
|
||||||
return headers.iterator();
|
return carrier.headers().get(key);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void put(final String key, final String value) {
|
|
||||||
throw new UnsupportedOperationException("This class should be used only with Tracer.inject()!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue