diff --git a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/decorator/BaseDecorator.java b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/decorator/BaseDecorator.java index fc4960d7ad..629bea3b6f 100644 --- a/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/decorator/BaseDecorator.java +++ b/dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/decorator/BaseDecorator.java @@ -8,6 +8,10 @@ import io.opentracing.Scope; import io.opentracing.Span; import io.opentracing.tag.Tags; import java.lang.reflect.Method; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.InetSocketAddress; import java.util.Arrays; import java.util.Collections; import java.util.TreeSet; @@ -86,6 +90,22 @@ public abstract class BaseDecorator { return span; } + public Span onPeerConnection(final Span span, final InetSocketAddress remoteConnection) { + assert span != null; + if (remoteConnection != null) { + span.setTag(Tags.PEER_HOSTNAME.getKey(), remoteConnection.getHostName()); + span.setTag(Tags.PEER_PORT.getKey(), remoteConnection.getPort()); + + final InetAddress remoteAddress = remoteConnection.getAddress(); + if (remoteAddress instanceof Inet4Address) { + Tags.PEER_HOST_IPV4.set(span, remoteAddress.getHostAddress()); + } else if (remoteAddress instanceof Inet6Address) { + Tags.PEER_HOST_IPV6.set(span, remoteAddress.getHostAddress()); + } + } + return span; + } + /** * This method is used to generate an acceptable span (operation) name based on a given method * reference. Anonymous classes are named based on their parent. diff --git a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/decorator/BaseDecoratorTest.groovy b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/decorator/BaseDecoratorTest.groovy index fe94dbe768..22c49f017c 100644 --- a/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/decorator/BaseDecoratorTest.groovy +++ b/dd-java-agent/agent-tooling/src/test/groovy/datadog/trace/agent/decorator/BaseDecoratorTest.groovy @@ -28,6 +28,28 @@ class BaseDecoratorTest extends Specification { 0 * _ } + def "test onPeerConnection"() { + when: + decorator.onPeerConnection(span, connection) + + then: + 1 * span.setTag(Tags.PEER_HOSTNAME.key, connection.hostName) + 1 * span.setTag(Tags.PEER_PORT.key, connection.port) + if (connection.address instanceof Inet4Address) { + 1 * span.setTag(Tags.PEER_HOST_IPV4.key, connection.address.hostAddress) + } + if (connection.address instanceof Inet6Address) { + 1 * span.setTag(Tags.PEER_HOST_IPV6.key, connection.address.hostAddress) + } + 0 * _ + + where: + connection | _ + new InetSocketAddress("localhost", 888) | _ + new InetSocketAddress("ipv6.google.com", 999) | _ + new InetSocketAddress("bad.address.local", 999) | _ + } + def "test onError"() { when: decorator.onError(span, error) @@ -64,6 +86,12 @@ class BaseDecoratorTest extends Specification { then: thrown(AssertionError) + when: + decorator.onPeerConnection((Span) null, null) + + then: + thrown(AssertionError) + when: decorator.beforeFinish((Span) null) diff --git a/dd-java-agent/instrumentation/aws-java-sdk-2.2/src/test/groovy/AwsClientTest.groovy b/dd-java-agent/instrumentation/aws-java-sdk-2.2/src/test/groovy/AwsClientTest.groovy index c5f8def869..488c904838 100644 --- a/dd-java-agent/instrumentation/aws-java-sdk-2.2/src/test/groovy/AwsClientTest.groovy +++ b/dd-java-agent/instrumentation/aws-java-sdk-2.2/src/test/groovy/AwsClientTest.groovy @@ -193,6 +193,7 @@ class AwsClientTest extends AgentTestRunner { "$Tags.HTTP_STATUS.key" 200 "$Tags.HTTP_URL.key" expectedUrl "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" server.address.port "$Tags.HTTP_METHOD.key" "$method" "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/ChannelFutureListenerInstrumentation.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/ChannelFutureListenerInstrumentation.java index 9f81ab7f57..f23b57834c 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/ChannelFutureListenerInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/ChannelFutureListenerInstrumentation.java @@ -42,7 +42,11 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { public String[] helperClassNames() { return new String[] { packageName + ".AttributeKeys", + "datadog.trace.agent.decorator.BaseDecorator", // server helpers + "datadog.trace.agent.decorator.ServerDecorator", + "datadog.trace.agent.decorator.HttpServerDecorator", + packageName + ".server.NettyHttpServerDecorator", packageName + ".server.NettyRequestExtractAdapter", packageName + ".server.HttpServerRequestTracingHandler", packageName + ".server.HttpServerResponseTracingHandler", diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java index 8e075f748a..501d133134 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/NettyChannelPipelineInstrumentation.java @@ -56,12 +56,19 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { public String[] helperClassNames() { return new String[] { packageName + ".AttributeKeys", + "datadog.trace.agent.decorator.BaseDecorator", // client helpers + "datadog.trace.agent.decorator.ClientDecorator", + "datadog.trace.agent.decorator.HttpClientDecorator", + packageName + ".client.NettyHttpClientDecorator", packageName + ".client.NettyResponseInjectAdapter", packageName + ".client.HttpClientRequestTracingHandler", packageName + ".client.HttpClientResponseTracingHandler", packageName + ".client.HttpClientTracingHandler", // server helpers + "datadog.trace.agent.decorator.ServerDecorator", + "datadog.trace.agent.decorator.HttpServerDecorator", + packageName + ".server.NettyHttpServerDecorator", packageName + ".server.NettyRequestExtractAdapter", packageName + ".server.HttpServerRequestTracingHandler", packageName + ".server.HttpServerResponseTracingHandler", diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientRequestTracingHandler.java index 6e7fdcab5e..656847ebb6 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientRequestTracingHandler.java @@ -1,10 +1,7 @@ package datadog.trace.instrumentation.netty40.client; -import static io.netty.handler.codec.http.HttpHeaders.Names.HOST; -import static io.opentracing.log.Fields.ERROR_OBJECT; +import static datadog.trace.instrumentation.netty40.client.NettyHttpClientDecorator.DECORATE; -import datadog.trace.api.DDSpanTypes; -import datadog.trace.api.DDTags; import datadog.trace.context.TraceScope; import datadog.trace.instrumentation.netty40.AttributeKeys; import io.netty.channel.ChannelHandlerContext; @@ -13,12 +10,8 @@ import io.netty.channel.ChannelPromise; import io.netty.handler.codec.http.HttpRequest; import io.opentracing.Span; import io.opentracing.propagation.Format; -import io.opentracing.tag.Tags; import io.opentracing.util.GlobalTracer; import java.net.InetSocketAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Collections; import lombok.extern.slf4j.Slf4j; @Slf4j @@ -39,19 +32,11 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt } final HttpRequest request = (HttpRequest) msg; - final InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); - final Span span = - GlobalTracer.get() - .buildSpan("netty.client.request") - .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT) - .withTag(Tags.PEER_HOSTNAME.getKey(), remoteAddress.getHostName()) - .withTag(Tags.PEER_PORT.getKey(), remoteAddress.getPort()) - .withTag(Tags.HTTP_METHOD.getKey(), request.getMethod().name()) - .withTag(Tags.HTTP_URL.getKey(), formatUrl(request)) - .withTag(Tags.COMPONENT.getKey(), "netty-client") - .withTag(DDTags.SPAN_TYPE, DDSpanTypes.HTTP_CLIENT) - .start(); + final Span span = GlobalTracer.get().buildSpan("netty.client.request").start(); + DECORATE.afterStart(span); + DECORATE.onRequest(span, request); + DECORATE.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")) { @@ -65,9 +50,9 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt try { ctx.write(msg, prm); } catch (final Throwable throwable) { - Tags.ERROR.set(span, Boolean.TRUE); - span.log(Collections.singletonMap(ERROR_OBJECT, throwable)); - span.finish(); // Finish the span manually since finishSpanOnClose was false + DECORATE.onError(span, throwable); + DECORATE.beforeFinish(span); + span.finish(); throw throwable; } @@ -75,18 +60,4 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt scope.close(); } } - - private String formatUrl(final HttpRequest request) { - try { - URI uri = new URI(request.getUri()); - if ((uri.getHost() == null || uri.getHost().equals("")) && request.headers().contains(HOST)) { - uri = new URI("http://" + request.headers().get(HOST) + request.getUri()); - } - return new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null) - .toString(); - } catch (final URISyntaxException e) { - log.debug("Cannot parse netty uri: {}", request.getUri()); - return request.getUri(); - } - } } diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientResponseTracingHandler.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientResponseTracingHandler.java index a428b5a551..cb6979e17d 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientResponseTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/HttpClientResponseTracingHandler.java @@ -1,6 +1,6 @@ package datadog.trace.instrumentation.netty40.client; -import static io.opentracing.log.Fields.ERROR_OBJECT; +import static datadog.trace.instrumentation.netty40.client.NettyHttpClientDecorator.DECORATE; import datadog.trace.context.TraceScope; import datadog.trace.instrumentation.netty40.AttributeKeys; @@ -11,7 +11,6 @@ import io.opentracing.Scope; import io.opentracing.Span; import io.opentracing.tag.Tags; import io.opentracing.util.GlobalTracer; -import java.util.Collections; public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapter { @@ -33,8 +32,8 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt ctx.fireChannelRead(msg); } catch (final Throwable throwable) { if (finishSpan) { - Tags.ERROR.set(span, Boolean.TRUE); - span.log(Collections.singletonMap(ERROR_OBJECT, throwable)); + DECORATE.onError(span, throwable); + DECORATE.beforeFinish(span); Tags.HTTP_STATUS.set(span, 500); span.finish(); // Finish the span manually since finishSpanOnClose was false throw throwable; @@ -42,7 +41,8 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt } if (finishSpan) { - Tags.HTTP_STATUS.set(span, ((HttpResponse) msg).getStatus().code()); + DECORATE.onResponse(span, (HttpResponse) msg); + DECORATE.beforeFinish(span); span.finish(); // Finish the span manually since finishSpanOnClose was false } } diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/NettyHttpClientDecorator.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/NettyHttpClientDecorator.java new file mode 100644 index 0000000000..a6c865821c --- /dev/null +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/client/NettyHttpClientDecorator.java @@ -0,0 +1,61 @@ +package datadog.trace.instrumentation.netty40.client; + +import static io.netty.handler.codec.http.HttpHeaders.Names.HOST; + +import datadog.trace.agent.decorator.HttpClientDecorator; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; +import java.net.URI; +import java.net.URISyntaxException; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class NettyHttpClientDecorator extends HttpClientDecorator { + public static final NettyHttpClientDecorator DECORATE = new NettyHttpClientDecorator(); + + @Override + protected String[] instrumentationNames() { + return new String[] {"netty", "netty-4.0"}; + } + + @Override + protected String component() { + return "netty-client"; + } + + @Override + protected String method(final HttpRequest httpRequest) { + return httpRequest.getMethod().name(); + } + + @Override + protected String url(final HttpRequest request) { + // FIXME: This code is duplicated across netty integrations. + try { + URI uri = new URI(request.getUri()); + if ((uri.getHost() == null || uri.getHost().equals("")) && request.headers().contains(HOST)) { + uri = new URI("http://" + request.headers().get(HOST) + request.getUri()); + } + return new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null) + .toString(); + } catch (final URISyntaxException e) { + log.debug("Cannot parse netty uri: {}", request.getUri()); + return request.getUri(); + } + } + + @Override + protected String hostname(final HttpRequest httpRequest) { + return null; + } + + @Override + protected Integer port(final HttpRequest httpRequest) { + return null; + } + + @Override + protected Integer status(final HttpResponse httpResponse) { + return httpResponse.getStatus().code(); + } +} diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/HttpServerRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/HttpServerRequestTracingHandler.java index b0ec7d766e..933c40e6c1 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/HttpServerRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/HttpServerRequestTracingHandler.java @@ -1,10 +1,7 @@ package datadog.trace.instrumentation.netty40.server; -import static io.netty.handler.codec.http.HttpHeaders.Names.HOST; -import static io.opentracing.log.Fields.ERROR_OBJECT; +import static datadog.trace.instrumentation.netty40.server.NettyHttpServerDecorator.DECORATE; -import datadog.trace.api.DDSpanTypes; -import datadog.trace.api.DDTags; import datadog.trace.context.TraceScope; import datadog.trace.instrumentation.netty40.AttributeKeys; import io.netty.channel.ChannelHandlerContext; @@ -14,10 +11,8 @@ import io.opentracing.Scope; import io.opentracing.Span; import io.opentracing.SpanContext; import io.opentracing.propagation.Format; -import io.opentracing.tag.Tags; import io.opentracing.util.GlobalTracer; import java.net.InetSocketAddress; -import java.util.Collections; public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapter { @@ -34,35 +29,27 @@ public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapte GlobalTracer.get() .extract(Format.Builtin.HTTP_HEADERS, new NettyRequestExtractAdapter(request)); - String url = request.getUri(); - if (request.headers().contains(HOST)) { - url = "http://" + request.headers().get(HOST) + url; - } final Scope scope = GlobalTracer.get() .buildSpan("netty.request") .asChildOf(extractedContext) - .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER) - .withTag(Tags.PEER_HOSTNAME.getKey(), remoteAddress.getHostName()) - .withTag(Tags.PEER_PORT.getKey(), remoteAddress.getPort()) - .withTag(Tags.HTTP_METHOD.getKey(), request.getMethod().name()) - .withTag(Tags.HTTP_URL.getKey(), url) - .withTag(Tags.COMPONENT.getKey(), "netty") - .withTag(DDTags.SPAN_TYPE, DDSpanTypes.HTTP_SERVER) .startActive(false); + final Span span = scope.span(); + DECORATE.afterStart(span); + DECORATE.onRequest(span, request); + DECORATE.onPeerConnection(span, remoteAddress); if (scope instanceof TraceScope) { ((TraceScope) scope).setAsyncPropagation(true); } - final Span span = scope.span(); ctx.channel().attr(AttributeKeys.SERVER_ATTRIBUTE_KEY).set(span); try { ctx.fireChannelRead(msg); } catch (final Throwable throwable) { - Tags.ERROR.set(span, Boolean.TRUE); - span.log(Collections.singletonMap(ERROR_OBJECT, throwable)); + DECORATE.onError(span, throwable); + DECORATE.beforeFinish(span); span.finish(); // Finish the span manually since finishSpanOnClose was false throw throwable; } finally { diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/HttpServerResponseTracingHandler.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/HttpServerResponseTracingHandler.java index 260f25d355..a7d95ff6e2 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/HttpServerResponseTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/HttpServerResponseTracingHandler.java @@ -1,6 +1,6 @@ package datadog.trace.instrumentation.netty40.server; -import static io.opentracing.log.Fields.ERROR_OBJECT; +import static datadog.trace.instrumentation.netty40.server.NettyHttpServerDecorator.DECORATE; import datadog.trace.instrumentation.netty40.AttributeKeys; import io.netty.channel.ChannelHandlerContext; @@ -9,7 +9,6 @@ import io.netty.channel.ChannelPromise; import io.netty.handler.codec.http.HttpResponse; import io.opentracing.Span; import io.opentracing.tag.Tags; -import java.util.Collections; public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdapter { @@ -26,14 +25,13 @@ public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdap try { ctx.write(msg, prm); } catch (final Throwable throwable) { - Tags.ERROR.set(span, Boolean.TRUE); - span.log(Collections.singletonMap(ERROR_OBJECT, throwable)); + DECORATE.onError(span, throwable); Tags.HTTP_STATUS.set(span, 500); span.finish(); // Finish the span manually since finishSpanOnClose was false throw throwable; } - - Tags.HTTP_STATUS.set(span, response.getStatus().code()); + DECORATE.onResponse(span, response); + DECORATE.beforeFinish(span); span.finish(); // Finish the span manually since finishSpanOnClose was false } } diff --git a/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/NettyHttpServerDecorator.java b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/NettyHttpServerDecorator.java new file mode 100644 index 0000000000..0defd2883a --- /dev/null +++ b/dd-java-agent/instrumentation/netty-4.0/src/main/java/datadog/trace/instrumentation/netty40/server/NettyHttpServerDecorator.java @@ -0,0 +1,61 @@ +package datadog.trace.instrumentation.netty40.server; + +import static io.netty.handler.codec.http.HttpHeaders.Names.HOST; + +import datadog.trace.agent.decorator.HttpServerDecorator; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; +import java.net.URI; +import java.net.URISyntaxException; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class NettyHttpServerDecorator extends HttpServerDecorator { + public static final NettyHttpServerDecorator DECORATE = new NettyHttpServerDecorator(); + + @Override + protected String[] instrumentationNames() { + return new String[] {"netty", "netty-4.0"}; + } + + @Override + protected String component() { + return "netty"; + } + + @Override + protected String method(final HttpRequest httpRequest) { + return httpRequest.getMethod().name(); + } + + @Override + protected String url(final HttpRequest request) { + // FIXME: This code is duplicated across netty integrations. + try { + URI uri = new URI(request.getUri()); + if ((uri.getHost() == null || uri.getHost().equals("")) && request.headers().contains(HOST)) { + uri = new URI("http://" + request.headers().get(HOST) + request.getUri()); + } + return new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null) + .toString(); + } catch (final URISyntaxException e) { + log.debug("Cannot parse netty uri: {}", request.getUri()); + return request.getUri(); + } + } + + @Override + protected String hostname(final HttpRequest httpRequest) { + return null; + } + + @Override + protected Integer port(final HttpRequest httpRequest) { + return null; + } + + @Override + protected Integer status(final HttpResponse httpResponse) { + return httpResponse.getStatus().code(); + } +} diff --git a/dd-java-agent/instrumentation/netty-4.0/src/test/groovy/Netty40ClientTest.groovy b/dd-java-agent/instrumentation/netty-4.0/src/test/groovy/Netty40ClientTest.groovy index b6d9ae794f..05b4daa9bc 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/test/groovy/Netty40ClientTest.groovy +++ b/dd-java-agent/instrumentation/netty-4.0/src/test/groovy/Netty40ClientTest.groovy @@ -57,7 +57,8 @@ class Netty40ClientTest extends AgentTestRunner { "$Tags.HTTP_STATUS.key" 200 "$Tags.HTTP_URL.key" "$server.address/" "$Tags.PEER_HOSTNAME.key" "localhost" - "$Tags.PEER_PORT.key" Integer + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" + "$Tags.PEER_PORT.key" server.address.port "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT defaultTags() } diff --git a/dd-java-agent/instrumentation/netty-4.0/src/test/groovy/Netty40ServerTest.groovy b/dd-java-agent/instrumentation/netty-4.0/src/test/groovy/Netty40ServerTest.groovy index 804e7fecd9..5b55156dc6 100644 --- a/dd-java-agent/instrumentation/netty-4.0/src/test/groovy/Netty40ServerTest.groovy +++ b/dd-java-agent/instrumentation/netty-4.0/src/test/groovy/Netty40ServerTest.groovy @@ -13,7 +13,6 @@ import io.netty.channel.nio.NioEventLoopGroup import io.netty.channel.socket.nio.NioServerSocketChannel import io.netty.handler.codec.http.DefaultFullHttpResponse import io.netty.handler.codec.http.FullHttpResponse -import io.netty.handler.codec.http.HttpHeaders import io.netty.handler.codec.http.HttpRequestDecoder import io.netty.handler.codec.http.HttpResponseEncoder import io.netty.handler.codec.http.HttpResponseStatus @@ -26,9 +25,14 @@ import io.netty.util.CharsetUtil import io.opentracing.tag.Tags import okhttp3.OkHttpClient import okhttp3.Request +import spock.lang.Shared + +import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH +import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE class Netty40ServerTest extends AgentTestRunner { + @Shared OkHttpClient client = OkHttpUtils.client() def "test server request/response"() { @@ -66,6 +70,7 @@ class Netty40ServerTest extends AgentTestRunner { "$Tags.HTTP_STATUS.key" 200 "$Tags.HTTP_URL.key" "http://localhost:$port/" "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER defaultTags(true) @@ -111,6 +116,7 @@ class Netty40ServerTest extends AgentTestRunner { "$Tags.HTTP_STATUS.key" responseCode.code() "$Tags.HTTP_URL.key" "http://localhost:$port/" "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER if (error) { @@ -145,8 +151,8 @@ class Netty40ServerTest extends AgentTestRunner { if (msg instanceof LastHttpContent) { ByteBuf content = Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8) FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, responseCode, content) - response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "text/plain") - response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, content.readableBytes()) + response.headers().set(CONTENT_TYPE, "text/plain") + response.headers().set(CONTENT_LENGTH, content.readableBytes()) ctx.write(response) } }, diff --git a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/ChannelFutureListenerInstrumentation.java b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/ChannelFutureListenerInstrumentation.java index e7bb60b99d..f91f8cdcb5 100644 --- a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/ChannelFutureListenerInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/ChannelFutureListenerInstrumentation.java @@ -42,7 +42,11 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default { public String[] helperClassNames() { return new String[] { packageName + ".AttributeKeys", + "datadog.trace.agent.decorator.BaseDecorator", // server helpers + "datadog.trace.agent.decorator.ServerDecorator", + "datadog.trace.agent.decorator.HttpServerDecorator", + packageName + ".server.NettyHttpServerDecorator", packageName + ".server.NettyRequestExtractAdapter", packageName + ".server.HttpServerRequestTracingHandler", packageName + ".server.HttpServerResponseTracingHandler", diff --git a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelPipelineInstrumentation.java b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelPipelineInstrumentation.java index 6f1005c958..c36d6d7f54 100644 --- a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelPipelineInstrumentation.java +++ b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/NettyChannelPipelineInstrumentation.java @@ -56,12 +56,19 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default { public String[] helperClassNames() { return new String[] { packageName + ".AttributeKeys", + "datadog.trace.agent.decorator.BaseDecorator", // client helpers + "datadog.trace.agent.decorator.ClientDecorator", + "datadog.trace.agent.decorator.HttpClientDecorator", + packageName + ".client.NettyHttpClientDecorator", packageName + ".client.NettyResponseInjectAdapter", packageName + ".client.HttpClientRequestTracingHandler", packageName + ".client.HttpClientResponseTracingHandler", packageName + ".client.HttpClientTracingHandler", // server helpers + "datadog.trace.agent.decorator.ServerDecorator", + "datadog.trace.agent.decorator.HttpServerDecorator", + packageName + ".server.NettyHttpServerDecorator", packageName + ".server.NettyRequestExtractAdapter", packageName + ".server.HttpServerRequestTracingHandler", packageName + ".server.HttpServerResponseTracingHandler", diff --git a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/HttpClientRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/HttpClientRequestTracingHandler.java index 6b879eb302..6342472f12 100644 --- a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/HttpClientRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/HttpClientRequestTracingHandler.java @@ -1,10 +1,7 @@ package datadog.trace.instrumentation.netty41.client; -import static io.netty.handler.codec.http.HttpHeaderNames.HOST; -import static io.opentracing.log.Fields.ERROR_OBJECT; +import static datadog.trace.instrumentation.netty41.client.NettyHttpClientDecorator.DECORATE; -import datadog.trace.api.DDSpanTypes; -import datadog.trace.api.DDTags; import datadog.trace.context.TraceScope; import datadog.trace.instrumentation.netty41.AttributeKeys; import io.netty.channel.ChannelHandlerContext; @@ -13,12 +10,8 @@ import io.netty.channel.ChannelPromise; import io.netty.handler.codec.http.HttpRequest; import io.opentracing.Span; import io.opentracing.propagation.Format; -import io.opentracing.tag.Tags; import io.opentracing.util.GlobalTracer; import java.net.InetSocketAddress; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Collections; import lombok.extern.slf4j.Slf4j; @Slf4j @@ -39,19 +32,11 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt } final HttpRequest request = (HttpRequest) msg; - final InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); - final Span span = - GlobalTracer.get() - .buildSpan("netty.client.request") - .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT) - .withTag(Tags.PEER_HOSTNAME.getKey(), remoteAddress.getHostName()) - .withTag(Tags.PEER_PORT.getKey(), remoteAddress.getPort()) - .withTag(Tags.HTTP_METHOD.getKey(), request.method().name()) - .withTag(Tags.HTTP_URL.getKey(), formatUrl(request)) - .withTag(Tags.COMPONENT.getKey(), "netty-client") - .withTag(DDTags.SPAN_TYPE, DDSpanTypes.HTTP_CLIENT) - .start(); + final Span span = GlobalTracer.get().buildSpan("netty.client.request").start(); + DECORATE.afterStart(span); + DECORATE.onRequest(span, request); + DECORATE.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")) { @@ -65,9 +50,9 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt try { ctx.write(msg, prm); } catch (final Throwable throwable) { - Tags.ERROR.set(span, Boolean.TRUE); - span.log(Collections.singletonMap(ERROR_OBJECT, throwable)); - span.finish(); // Finish the span manually since finishSpanOnClose was false + DECORATE.onError(span, throwable); + DECORATE.beforeFinish(span); + span.finish(); throw throwable; } @@ -75,18 +60,4 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt scope.close(); } } - - private String formatUrl(final HttpRequest request) { - try { - URI uri = new URI(request.uri()); - if ((uri.getHost() == null || uri.getHost().equals("")) && request.headers().contains(HOST)) { - uri = new URI("http://" + request.headers().get(HOST) + request.uri()); - } - return new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null) - .toString(); - } catch (final URISyntaxException e) { - log.debug("Cannot parse netty uri: {}", request.uri()); - return request.uri(); - } - } } diff --git a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/HttpClientResponseTracingHandler.java b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/HttpClientResponseTracingHandler.java index b95dbfaa5b..a82d8e6eb4 100644 --- a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/HttpClientResponseTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/HttpClientResponseTracingHandler.java @@ -1,6 +1,6 @@ package datadog.trace.instrumentation.netty41.client; -import static io.opentracing.log.Fields.ERROR_OBJECT; +import static datadog.trace.instrumentation.netty41.client.NettyHttpClientDecorator.DECORATE; import datadog.trace.context.TraceScope; import datadog.trace.instrumentation.netty41.AttributeKeys; @@ -11,7 +11,6 @@ import io.opentracing.Scope; import io.opentracing.Span; import io.opentracing.tag.Tags; import io.opentracing.util.GlobalTracer; -import java.util.Collections; public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapter { @@ -33,8 +32,8 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt ctx.fireChannelRead(msg); } catch (final Throwable throwable) { if (finishSpan) { - Tags.ERROR.set(span, Boolean.TRUE); - span.log(Collections.singletonMap(ERROR_OBJECT, throwable)); + DECORATE.onError(span, throwable); + DECORATE.beforeFinish(span); Tags.HTTP_STATUS.set(span, 500); span.finish(); // Finish the span manually since finishSpanOnClose was false throw throwable; @@ -42,7 +41,8 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt } if (finishSpan) { - Tags.HTTP_STATUS.set(span, ((HttpResponse) msg).status().code()); + DECORATE.onResponse(span, (HttpResponse) msg); + DECORATE.beforeFinish(span); span.finish(); // Finish the span manually since finishSpanOnClose was false } } diff --git a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/NettyHttpClientDecorator.java b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/NettyHttpClientDecorator.java new file mode 100644 index 0000000000..30a3f97cfc --- /dev/null +++ b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/client/NettyHttpClientDecorator.java @@ -0,0 +1,61 @@ +package datadog.trace.instrumentation.netty41.client; + +import static io.netty.handler.codec.http.HttpHeaders.Names.HOST; + +import datadog.trace.agent.decorator.HttpClientDecorator; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; +import java.net.URI; +import java.net.URISyntaxException; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class NettyHttpClientDecorator extends HttpClientDecorator { + public static final NettyHttpClientDecorator DECORATE = new NettyHttpClientDecorator(); + + @Override + protected String[] instrumentationNames() { + return new String[] {"netty", "netty-4.0"}; + } + + @Override + protected String component() { + return "netty-client"; + } + + @Override + protected String method(final HttpRequest httpRequest) { + return httpRequest.method().name(); + } + + @Override + protected String url(final HttpRequest request) { + // FIXME: This code is duplicated across netty integrations. + try { + URI uri = new URI(request.uri()); + if ((uri.getHost() == null || uri.getHost().equals("")) && request.headers().contains(HOST)) { + uri = new URI("http://" + request.headers().get(HOST) + request.uri()); + } + return new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null) + .toString(); + } catch (final URISyntaxException e) { + log.debug("Cannot parse netty uri: {}", request.uri()); + return request.uri(); + } + } + + @Override + protected String hostname(final HttpRequest httpRequest) { + return null; + } + + @Override + protected Integer port(final HttpRequest httpRequest) { + return null; + } + + @Override + protected Integer status(final HttpResponse httpResponse) { + return httpResponse.status().code(); + } +} diff --git a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerRequestTracingHandler.java b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerRequestTracingHandler.java index e0ba355fbe..791549c1c1 100644 --- a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerRequestTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerRequestTracingHandler.java @@ -1,10 +1,7 @@ package datadog.trace.instrumentation.netty41.server; -import static io.netty.handler.codec.http.HttpHeaderNames.HOST; -import static io.opentracing.log.Fields.ERROR_OBJECT; +import static datadog.trace.instrumentation.netty41.server.NettyHttpServerDecorator.DECORATE; -import datadog.trace.api.DDSpanTypes; -import datadog.trace.api.DDTags; import datadog.trace.context.TraceScope; import datadog.trace.instrumentation.netty41.AttributeKeys; import io.netty.channel.ChannelHandlerContext; @@ -14,10 +11,8 @@ import io.opentracing.Scope; import io.opentracing.Span; import io.opentracing.SpanContext; import io.opentracing.propagation.Format; -import io.opentracing.tag.Tags; import io.opentracing.util.GlobalTracer; import java.net.InetSocketAddress; -import java.util.Collections; public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapter { @@ -34,35 +29,27 @@ public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapte GlobalTracer.get() .extract(Format.Builtin.HTTP_HEADERS, new NettyRequestExtractAdapter(request)); - String url = request.uri(); - if (request.headers().contains(HOST)) { - url = "http://" + request.headers().get(HOST) + url; - } final Scope scope = GlobalTracer.get() .buildSpan("netty.request") .asChildOf(extractedContext) - .withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER) - .withTag(Tags.PEER_HOSTNAME.getKey(), remoteAddress.getHostName()) - .withTag(Tags.PEER_PORT.getKey(), remoteAddress.getPort()) - .withTag(Tags.HTTP_METHOD.getKey(), request.method().name()) - .withTag(Tags.HTTP_URL.getKey(), url) - .withTag(Tags.COMPONENT.getKey(), "netty") - .withTag(DDTags.SPAN_TYPE, DDSpanTypes.HTTP_SERVER) .startActive(false); + final Span span = scope.span(); + DECORATE.afterStart(span); + DECORATE.onRequest(span, request); + DECORATE.onPeerConnection(span, remoteAddress); if (scope instanceof TraceScope) { ((TraceScope) scope).setAsyncPropagation(true); } - final Span span = scope.span(); ctx.channel().attr(AttributeKeys.SERVER_ATTRIBUTE_KEY).set(span); try { ctx.fireChannelRead(msg); } catch (final Throwable throwable) { - Tags.ERROR.set(span, Boolean.TRUE); - span.log(Collections.singletonMap(ERROR_OBJECT, throwable)); + DECORATE.onError(span, throwable); + DECORATE.beforeFinish(span); span.finish(); // Finish the span manually since finishSpanOnClose was false throw throwable; } finally { diff --git a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerResponseTracingHandler.java b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerResponseTracingHandler.java index 6de0af59d7..de197533fe 100644 --- a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerResponseTracingHandler.java +++ b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/HttpServerResponseTracingHandler.java @@ -1,6 +1,6 @@ package datadog.trace.instrumentation.netty41.server; -import static io.opentracing.log.Fields.ERROR_OBJECT; +import static datadog.trace.instrumentation.netty41.server.NettyHttpServerDecorator.DECORATE; import datadog.trace.instrumentation.netty41.AttributeKeys; import io.netty.channel.ChannelHandlerContext; @@ -9,7 +9,6 @@ import io.netty.channel.ChannelPromise; import io.netty.handler.codec.http.HttpResponse; import io.opentracing.Span; import io.opentracing.tag.Tags; -import java.util.Collections; public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdapter { @@ -26,14 +25,13 @@ public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdap try { ctx.write(msg, prm); } catch (final Throwable throwable) { - Tags.ERROR.set(span, Boolean.TRUE); - span.log(Collections.singletonMap(ERROR_OBJECT, throwable)); + DECORATE.onError(span, throwable); Tags.HTTP_STATUS.set(span, 500); span.finish(); // Finish the span manually since finishSpanOnClose was false throw throwable; } - - Tags.HTTP_STATUS.set(span, response.status().code()); + DECORATE.onResponse(span, response); + DECORATE.beforeFinish(span); span.finish(); // Finish the span manually since finishSpanOnClose was false } } diff --git a/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/NettyHttpServerDecorator.java b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/NettyHttpServerDecorator.java new file mode 100644 index 0000000000..23fe66e24e --- /dev/null +++ b/dd-java-agent/instrumentation/netty-4.1/src/main/java/datadog/trace/instrumentation/netty41/server/NettyHttpServerDecorator.java @@ -0,0 +1,61 @@ +package datadog.trace.instrumentation.netty41.server; + +import static io.netty.handler.codec.http.HttpHeaders.Names.HOST; + +import datadog.trace.agent.decorator.HttpServerDecorator; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpResponse; +import java.net.URI; +import java.net.URISyntaxException; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class NettyHttpServerDecorator extends HttpServerDecorator { + public static final NettyHttpServerDecorator DECORATE = new NettyHttpServerDecorator(); + + @Override + protected String[] instrumentationNames() { + return new String[] {"netty", "netty-4.0"}; + } + + @Override + protected String component() { + return "netty"; + } + + @Override + protected String method(final HttpRequest httpRequest) { + return httpRequest.method().name(); + } + + @Override + protected String url(final HttpRequest request) { + // FIXME: This code is duplicated across netty integrations. + try { + URI uri = new URI(request.uri()); + if ((uri.getHost() == null || uri.getHost().equals("")) && request.headers().contains(HOST)) { + uri = new URI("http://" + request.headers().get(HOST) + request.uri()); + } + return new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null) + .toString(); + } catch (final URISyntaxException e) { + log.debug("Cannot parse netty uri: {}", request.uri()); + return request.uri(); + } + } + + @Override + protected String hostname(final HttpRequest httpRequest) { + return null; + } + + @Override + protected Integer port(final HttpRequest httpRequest) { + return null; + } + + @Override + protected Integer status(final HttpResponse httpResponse) { + return httpResponse.status().code(); + } +} diff --git a/dd-java-agent/instrumentation/netty-4.1/src/test/groovy/Netty41ClientTest.groovy b/dd-java-agent/instrumentation/netty-4.1/src/test/groovy/Netty41ClientTest.groovy index dac2f7c8e1..244ab7f60a 100644 --- a/dd-java-agent/instrumentation/netty-4.1/src/test/groovy/Netty41ClientTest.groovy +++ b/dd-java-agent/instrumentation/netty-4.1/src/test/groovy/Netty41ClientTest.groovy @@ -58,7 +58,8 @@ class Netty41ClientTest extends AgentTestRunner { "$Tags.HTTP_STATUS.key" 200 "$Tags.HTTP_URL.key" "$server.address/" "$Tags.PEER_HOSTNAME.key" "localhost" - "$Tags.PEER_PORT.key" Integer + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" + "$Tags.PEER_PORT.key" server.address.port "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT defaultTags() } diff --git a/dd-java-agent/instrumentation/netty-4.1/src/test/groovy/Netty41ServerTest.groovy b/dd-java-agent/instrumentation/netty-4.1/src/test/groovy/Netty41ServerTest.groovy index 90a695a1bd..69976e756d 100644 --- a/dd-java-agent/instrumentation/netty-4.1/src/test/groovy/Netty41ServerTest.groovy +++ b/dd-java-agent/instrumentation/netty-4.1/src/test/groovy/Netty41ServerTest.groovy @@ -13,7 +13,6 @@ import io.netty.channel.nio.NioEventLoopGroup import io.netty.channel.socket.nio.NioServerSocketChannel import io.netty.handler.codec.http.DefaultFullHttpResponse import io.netty.handler.codec.http.FullHttpResponse -import io.netty.handler.codec.http.HttpHeaderNames import io.netty.handler.codec.http.HttpRequestDecoder import io.netty.handler.codec.http.HttpResponseEncoder import io.netty.handler.codec.http.HttpResponseStatus @@ -28,6 +27,9 @@ import okhttp3.OkHttpClient import okhttp3.Request import spock.lang.Shared +import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH +import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE + class Netty41ServerTest extends AgentTestRunner { @Shared @@ -68,6 +70,7 @@ class Netty41ServerTest extends AgentTestRunner { "$Tags.HTTP_STATUS.key" 200 "$Tags.HTTP_URL.key" "http://localhost:$port/" "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER defaultTags(true) @@ -113,6 +116,7 @@ class Netty41ServerTest extends AgentTestRunner { "$Tags.HTTP_STATUS.key" responseCode.code() "$Tags.HTTP_URL.key" "http://localhost:$port/" "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER if (error) { @@ -147,8 +151,8 @@ class Netty41ServerTest extends AgentTestRunner { if (msg instanceof LastHttpContent) { ByteBuf content = Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8) FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, responseCode, content) - response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain") - response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes()) + response.headers().set(CONTENT_TYPE, "text/plain") + response.headers().set(CONTENT_LENGTH, content.readableBytes()) ctx.write(response) } }, diff --git a/dd-java-agent/instrumentation/spring-webflux/src/test/groovy/SpringWebfluxTest.groovy b/dd-java-agent/instrumentation/spring-webflux/src/test/groovy/SpringWebfluxTest.groovy index 8e5786f4a0..1d7f718e58 100644 --- a/dd-java-agent/instrumentation/spring-webflux/src/test/groovy/SpringWebfluxTest.groovy +++ b/dd-java-agent/instrumentation/spring-webflux/src/test/groovy/SpringWebfluxTest.groovy @@ -84,6 +84,7 @@ class SpringWebfluxTest extends AgentTestRunner { "$Tags.COMPONENT.key" "netty" "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.HTTP_METHOD.key" "GET" "$Tags.HTTP_STATUS.key" 200 @@ -156,6 +157,7 @@ class SpringWebfluxTest extends AgentTestRunner { "$Tags.COMPONENT.key" "netty" "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.HTTP_METHOD.key" "GET" "$Tags.HTTP_STATUS.key" 200 @@ -216,6 +218,7 @@ class SpringWebfluxTest extends AgentTestRunner { "$Tags.COMPONENT.key" "netty" "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.HTTP_METHOD.key" "GET" "$Tags.HTTP_STATUS.key" 404 @@ -278,6 +281,7 @@ class SpringWebfluxTest extends AgentTestRunner { "$Tags.COMPONENT.key" "netty" "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.HTTP_METHOD.key" "POST" "$Tags.HTTP_STATUS.key" 202 @@ -320,6 +324,7 @@ class SpringWebfluxTest extends AgentTestRunner { "$Tags.COMPONENT.key" "netty" "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.HTTP_METHOD.key" "GET" "$Tags.HTTP_STATUS.key" 500 @@ -392,6 +397,7 @@ class SpringWebfluxTest extends AgentTestRunner { "$Tags.COMPONENT.key" "netty" "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.HTTP_METHOD.key" "GET" "$Tags.HTTP_STATUS.key" 307 @@ -439,6 +445,7 @@ class SpringWebfluxTest extends AgentTestRunner { "$Tags.COMPONENT.key" "netty" "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.HTTP_METHOD.key" "GET" "$Tags.HTTP_STATUS.key" 200 @@ -500,6 +507,7 @@ class SpringWebfluxTest extends AgentTestRunner { "$Tags.COMPONENT.key" "netty" "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.HTTP_METHOD.key" "GET" "$Tags.HTTP_STATUS.key" 200 diff --git a/dd-java-agent/instrumentation/vertx/src/test/groovy/VertxHttpClientTest.groovy b/dd-java-agent/instrumentation/vertx/src/test/groovy/VertxHttpClientTest.groovy index 501b7f65e9..2875bb8269 100644 --- a/dd-java-agent/instrumentation/vertx/src/test/groovy/VertxHttpClientTest.groovy +++ b/dd-java-agent/instrumentation/vertx/src/test/groovy/VertxHttpClientTest.groovy @@ -80,6 +80,7 @@ class VertxHttpClientTest extends AgentTestRunner { "$Tags.HTTP_STATUS.key" expectedStatus "$Tags.HTTP_URL.key" "${server.address}/$route" "$Tags.PEER_HOSTNAME.key" server.address.host + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" server.address.port "$Tags.HTTP_METHOD.key" "GET" "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT diff --git a/dd-java-agent/instrumentation/vertx/src/test/groovy/VertxServerTest.groovy b/dd-java-agent/instrumentation/vertx/src/test/groovy/VertxServerTest.groovy index e0f06d3523..83a7cf6091 100644 --- a/dd-java-agent/instrumentation/vertx/src/test/groovy/VertxServerTest.groovy +++ b/dd-java-agent/instrumentation/vertx/src/test/groovy/VertxServerTest.groovy @@ -59,6 +59,7 @@ class VertxServerTest extends AgentTestRunner { "$Tags.HTTP_STATUS.key" 200 "$Tags.HTTP_URL.key" "http://localhost:$port/test" "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER defaultTags(true) @@ -95,6 +96,7 @@ class VertxServerTest extends AgentTestRunner { "$Tags.HTTP_STATUS.key" responseCode.code() "$Tags.HTTP_URL.key" "http://localhost:$port/$path" "$Tags.PEER_HOSTNAME.key" "localhost" + "$Tags.PEER_HOST_IPV4.key" "127.0.0.1" "$Tags.PEER_PORT.key" Integer "$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER if (error) {