Migrate Netty instrumentation to Decorator
This commit is contained in:
parent
246bdfe081
commit
084c2eb51f
|
@ -8,6 +8,10 @@ import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.tag.Tags;
|
import io.opentracing.tag.Tags;
|
||||||
import java.lang.reflect.Method;
|
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.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
@ -86,6 +90,22 @@ public abstract class BaseDecorator {
|
||||||
return span;
|
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
|
* 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.
|
* reference. Anonymous classes are named based on their parent.
|
||||||
|
|
|
@ -28,6 +28,28 @@ class BaseDecoratorTest extends Specification {
|
||||||
0 * _
|
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"() {
|
def "test onError"() {
|
||||||
when:
|
when:
|
||||||
decorator.onError(span, error)
|
decorator.onError(span, error)
|
||||||
|
@ -64,6 +86,12 @@ class BaseDecoratorTest extends Specification {
|
||||||
then:
|
then:
|
||||||
thrown(AssertionError)
|
thrown(AssertionError)
|
||||||
|
|
||||||
|
when:
|
||||||
|
decorator.onPeerConnection((Span) null, null)
|
||||||
|
|
||||||
|
then:
|
||||||
|
thrown(AssertionError)
|
||||||
|
|
||||||
when:
|
when:
|
||||||
decorator.beforeFinish((Span) null)
|
decorator.beforeFinish((Span) null)
|
||||||
|
|
||||||
|
|
|
@ -193,6 +193,7 @@ class AwsClientTest extends AgentTestRunner {
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
"$Tags.HTTP_STATUS.key" 200
|
||||||
"$Tags.HTTP_URL.key" expectedUrl
|
"$Tags.HTTP_URL.key" expectedUrl
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" server.address.port
|
"$Tags.PEER_PORT.key" server.address.port
|
||||||
"$Tags.HTTP_METHOD.key" "$method"
|
"$Tags.HTTP_METHOD.key" "$method"
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
|
||||||
|
|
|
@ -42,7 +42,11 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
packageName + ".AttributeKeys",
|
packageName + ".AttributeKeys",
|
||||||
|
"datadog.trace.agent.decorator.BaseDecorator",
|
||||||
// server helpers
|
// server helpers
|
||||||
|
"datadog.trace.agent.decorator.ServerDecorator",
|
||||||
|
"datadog.trace.agent.decorator.HttpServerDecorator",
|
||||||
|
packageName + ".server.NettyHttpServerDecorator",
|
||||||
packageName + ".server.NettyRequestExtractAdapter",
|
packageName + ".server.NettyRequestExtractAdapter",
|
||||||
packageName + ".server.HttpServerRequestTracingHandler",
|
packageName + ".server.HttpServerRequestTracingHandler",
|
||||||
packageName + ".server.HttpServerResponseTracingHandler",
|
packageName + ".server.HttpServerResponseTracingHandler",
|
||||||
|
|
|
@ -56,12 +56,19 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
packageName + ".AttributeKeys",
|
packageName + ".AttributeKeys",
|
||||||
|
"datadog.trace.agent.decorator.BaseDecorator",
|
||||||
// client helpers
|
// client helpers
|
||||||
|
"datadog.trace.agent.decorator.ClientDecorator",
|
||||||
|
"datadog.trace.agent.decorator.HttpClientDecorator",
|
||||||
|
packageName + ".client.NettyHttpClientDecorator",
|
||||||
packageName + ".client.NettyResponseInjectAdapter",
|
packageName + ".client.NettyResponseInjectAdapter",
|
||||||
packageName + ".client.HttpClientRequestTracingHandler",
|
packageName + ".client.HttpClientRequestTracingHandler",
|
||||||
packageName + ".client.HttpClientResponseTracingHandler",
|
packageName + ".client.HttpClientResponseTracingHandler",
|
||||||
packageName + ".client.HttpClientTracingHandler",
|
packageName + ".client.HttpClientTracingHandler",
|
||||||
// server helpers
|
// server helpers
|
||||||
|
"datadog.trace.agent.decorator.ServerDecorator",
|
||||||
|
"datadog.trace.agent.decorator.HttpServerDecorator",
|
||||||
|
packageName + ".server.NettyHttpServerDecorator",
|
||||||
packageName + ".server.NettyRequestExtractAdapter",
|
packageName + ".server.NettyRequestExtractAdapter",
|
||||||
packageName + ".server.HttpServerRequestTracingHandler",
|
packageName + ".server.HttpServerRequestTracingHandler",
|
||||||
packageName + ".server.HttpServerResponseTracingHandler",
|
packageName + ".server.HttpServerResponseTracingHandler",
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
package datadog.trace.instrumentation.netty40.client;
|
package datadog.trace.instrumentation.netty40.client;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http.HttpHeaders.Names.HOST;
|
import static datadog.trace.instrumentation.netty40.client.NettyHttpClientDecorator.DECORATE;
|
||||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
|
||||||
|
|
||||||
import datadog.trace.api.DDSpanTypes;
|
|
||||||
import datadog.trace.api.DDTags;
|
|
||||||
import datadog.trace.context.TraceScope;
|
import datadog.trace.context.TraceScope;
|
||||||
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
@ -13,12 +10,8 @@ import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.handler.codec.http.HttpRequest;
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.propagation.Format;
|
import io.opentracing.propagation.Format;
|
||||||
import io.opentracing.tag.Tags;
|
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -39,19 +32,11 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
}
|
}
|
||||||
|
|
||||||
final HttpRequest request = (HttpRequest) msg;
|
final HttpRequest request = (HttpRequest) msg;
|
||||||
final InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
|
|
||||||
|
|
||||||
final Span span =
|
final Span span = GlobalTracer.get().buildSpan("netty.client.request").start();
|
||||||
GlobalTracer.get()
|
DECORATE.afterStart(span);
|
||||||
.buildSpan("netty.client.request")
|
DECORATE.onRequest(span, request);
|
||||||
.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
|
DECORATE.onPeerConnection(span, (InetSocketAddress) ctx.channel().remoteAddress());
|
||||||
.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();
|
|
||||||
|
|
||||||
// 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")) {
|
||||||
|
@ -65,9 +50,9 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
try {
|
try {
|
||||||
ctx.write(msg, prm);
|
ctx.write(msg, prm);
|
||||||
} catch (final Throwable throwable) {
|
} catch (final Throwable throwable) {
|
||||||
Tags.ERROR.set(span, Boolean.TRUE);
|
DECORATE.onError(span, throwable);
|
||||||
span.log(Collections.singletonMap(ERROR_OBJECT, throwable));
|
DECORATE.beforeFinish(span);
|
||||||
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
span.finish();
|
||||||
throw throwable;
|
throw throwable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,18 +60,4 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
scope.close();
|
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package datadog.trace.instrumentation.netty40.client;
|
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.context.TraceScope;
|
||||||
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
||||||
|
@ -11,7 +11,6 @@ import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.tag.Tags;
|
import io.opentracing.tag.Tags;
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapter {
|
public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
||||||
|
@ -33,8 +32,8 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt
|
||||||
ctx.fireChannelRead(msg);
|
ctx.fireChannelRead(msg);
|
||||||
} catch (final Throwable throwable) {
|
} catch (final Throwable throwable) {
|
||||||
if (finishSpan) {
|
if (finishSpan) {
|
||||||
Tags.ERROR.set(span, Boolean.TRUE);
|
DECORATE.onError(span, throwable);
|
||||||
span.log(Collections.singletonMap(ERROR_OBJECT, throwable));
|
DECORATE.beforeFinish(span);
|
||||||
Tags.HTTP_STATUS.set(span, 500);
|
Tags.HTTP_STATUS.set(span, 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;
|
||||||
|
@ -42,7 +41,8 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finishSpan) {
|
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
|
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<HttpRequest, HttpResponse> {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,7 @@
|
||||||
package datadog.trace.instrumentation.netty40.server;
|
package datadog.trace.instrumentation.netty40.server;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http.HttpHeaders.Names.HOST;
|
import static datadog.trace.instrumentation.netty40.server.NettyHttpServerDecorator.DECORATE;
|
||||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
|
||||||
|
|
||||||
import datadog.trace.api.DDSpanTypes;
|
|
||||||
import datadog.trace.api.DDTags;
|
|
||||||
import datadog.trace.context.TraceScope;
|
import datadog.trace.context.TraceScope;
|
||||||
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
import datadog.trace.instrumentation.netty40.AttributeKeys;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
@ -14,10 +11,8 @@ import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.SpanContext;
|
import io.opentracing.SpanContext;
|
||||||
import io.opentracing.propagation.Format;
|
import io.opentracing.propagation.Format;
|
||||||
import io.opentracing.tag.Tags;
|
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapter {
|
public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
||||||
|
@ -34,35 +29,27 @@ public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapte
|
||||||
GlobalTracer.get()
|
GlobalTracer.get()
|
||||||
.extract(Format.Builtin.HTTP_HEADERS, new NettyRequestExtractAdapter(request));
|
.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 =
|
final Scope scope =
|
||||||
GlobalTracer.get()
|
GlobalTracer.get()
|
||||||
.buildSpan("netty.request")
|
.buildSpan("netty.request")
|
||||||
.asChildOf(extractedContext)
|
.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);
|
.startActive(false);
|
||||||
|
final Span span = scope.span();
|
||||||
|
DECORATE.afterStart(span);
|
||||||
|
DECORATE.onRequest(span, request);
|
||||||
|
DECORATE.onPeerConnection(span, remoteAddress);
|
||||||
|
|
||||||
if (scope instanceof TraceScope) {
|
if (scope instanceof TraceScope) {
|
||||||
((TraceScope) scope).setAsyncPropagation(true);
|
((TraceScope) scope).setAsyncPropagation(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Span span = scope.span();
|
|
||||||
ctx.channel().attr(AttributeKeys.SERVER_ATTRIBUTE_KEY).set(span);
|
ctx.channel().attr(AttributeKeys.SERVER_ATTRIBUTE_KEY).set(span);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ctx.fireChannelRead(msg);
|
ctx.fireChannelRead(msg);
|
||||||
} catch (final Throwable throwable) {
|
} catch (final Throwable throwable) {
|
||||||
Tags.ERROR.set(span, Boolean.TRUE);
|
DECORATE.onError(span, throwable);
|
||||||
span.log(Collections.singletonMap(ERROR_OBJECT, throwable));
|
DECORATE.beforeFinish(span);
|
||||||
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
||||||
throw throwable;
|
throw throwable;
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package datadog.trace.instrumentation.netty40.server;
|
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 datadog.trace.instrumentation.netty40.AttributeKeys;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
@ -9,7 +9,6 @@ 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.Span;
|
||||||
import io.opentracing.tag.Tags;
|
import io.opentracing.tag.Tags;
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdapter {
|
public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdapter {
|
||||||
|
|
||||||
|
@ -26,14 +25,13 @@ public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdap
|
||||||
try {
|
try {
|
||||||
ctx.write(msg, prm);
|
ctx.write(msg, prm);
|
||||||
} catch (final Throwable throwable) {
|
} catch (final Throwable throwable) {
|
||||||
Tags.ERROR.set(span, Boolean.TRUE);
|
DECORATE.onError(span, throwable);
|
||||||
span.log(Collections.singletonMap(ERROR_OBJECT, throwable));
|
|
||||||
Tags.HTTP_STATUS.set(span, 500);
|
Tags.HTTP_STATUS.set(span, 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;
|
||||||
}
|
}
|
||||||
|
DECORATE.onResponse(span, response);
|
||||||
Tags.HTTP_STATUS.set(span, response.getStatus().code());
|
DECORATE.beforeFinish(span);
|
||||||
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<HttpRequest, HttpResponse> {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -57,7 +57,8 @@ class Netty40ClientTest extends AgentTestRunner {
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
"$Tags.HTTP_STATUS.key" 200
|
||||||
"$Tags.HTTP_URL.key" "$server.address/"
|
"$Tags.HTTP_URL.key" "$server.address/"
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$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
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
|
||||||
defaultTags()
|
defaultTags()
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import io.netty.channel.nio.NioEventLoopGroup
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel
|
import io.netty.channel.socket.nio.NioServerSocketChannel
|
||||||
import io.netty.handler.codec.http.DefaultFullHttpResponse
|
import io.netty.handler.codec.http.DefaultFullHttpResponse
|
||||||
import io.netty.handler.codec.http.FullHttpResponse
|
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.HttpRequestDecoder
|
||||||
import io.netty.handler.codec.http.HttpResponseEncoder
|
import io.netty.handler.codec.http.HttpResponseEncoder
|
||||||
import io.netty.handler.codec.http.HttpResponseStatus
|
import io.netty.handler.codec.http.HttpResponseStatus
|
||||||
|
@ -26,9 +25,14 @@ import io.netty.util.CharsetUtil
|
||||||
import io.opentracing.tag.Tags
|
import io.opentracing.tag.Tags
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
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 {
|
class Netty40ServerTest extends AgentTestRunner {
|
||||||
|
|
||||||
|
@Shared
|
||||||
OkHttpClient client = OkHttpUtils.client()
|
OkHttpClient client = OkHttpUtils.client()
|
||||||
|
|
||||||
def "test server request/response"() {
|
def "test server request/response"() {
|
||||||
|
@ -66,6 +70,7 @@ class Netty40ServerTest extends AgentTestRunner {
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
"$Tags.HTTP_STATUS.key" 200
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/"
|
"$Tags.HTTP_URL.key" "http://localhost:$port/"
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
defaultTags(true)
|
defaultTags(true)
|
||||||
|
@ -111,6 +116,7 @@ class Netty40ServerTest extends AgentTestRunner {
|
||||||
"$Tags.HTTP_STATUS.key" responseCode.code()
|
"$Tags.HTTP_STATUS.key" responseCode.code()
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/"
|
"$Tags.HTTP_URL.key" "http://localhost:$port/"
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -145,8 +151,8 @@ class Netty40ServerTest extends AgentTestRunner {
|
||||||
if (msg instanceof LastHttpContent) {
|
if (msg instanceof LastHttpContent) {
|
||||||
ByteBuf content = Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8)
|
ByteBuf content = Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8)
|
||||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, responseCode, content)
|
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, responseCode, content)
|
||||||
response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "text/plain")
|
response.headers().set(CONTENT_TYPE, "text/plain")
|
||||||
response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, content.readableBytes())
|
response.headers().set(CONTENT_LENGTH, content.readableBytes())
|
||||||
ctx.write(response)
|
ctx.write(response)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -42,7 +42,11 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
packageName + ".AttributeKeys",
|
packageName + ".AttributeKeys",
|
||||||
|
"datadog.trace.agent.decorator.BaseDecorator",
|
||||||
// server helpers
|
// server helpers
|
||||||
|
"datadog.trace.agent.decorator.ServerDecorator",
|
||||||
|
"datadog.trace.agent.decorator.HttpServerDecorator",
|
||||||
|
packageName + ".server.NettyHttpServerDecorator",
|
||||||
packageName + ".server.NettyRequestExtractAdapter",
|
packageName + ".server.NettyRequestExtractAdapter",
|
||||||
packageName + ".server.HttpServerRequestTracingHandler",
|
packageName + ".server.HttpServerRequestTracingHandler",
|
||||||
packageName + ".server.HttpServerResponseTracingHandler",
|
packageName + ".server.HttpServerResponseTracingHandler",
|
||||||
|
|
|
@ -56,12 +56,19 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
|
||||||
public String[] helperClassNames() {
|
public String[] helperClassNames() {
|
||||||
return new String[] {
|
return new String[] {
|
||||||
packageName + ".AttributeKeys",
|
packageName + ".AttributeKeys",
|
||||||
|
"datadog.trace.agent.decorator.BaseDecorator",
|
||||||
// client helpers
|
// client helpers
|
||||||
|
"datadog.trace.agent.decorator.ClientDecorator",
|
||||||
|
"datadog.trace.agent.decorator.HttpClientDecorator",
|
||||||
|
packageName + ".client.NettyHttpClientDecorator",
|
||||||
packageName + ".client.NettyResponseInjectAdapter",
|
packageName + ".client.NettyResponseInjectAdapter",
|
||||||
packageName + ".client.HttpClientRequestTracingHandler",
|
packageName + ".client.HttpClientRequestTracingHandler",
|
||||||
packageName + ".client.HttpClientResponseTracingHandler",
|
packageName + ".client.HttpClientResponseTracingHandler",
|
||||||
packageName + ".client.HttpClientTracingHandler",
|
packageName + ".client.HttpClientTracingHandler",
|
||||||
// server helpers
|
// server helpers
|
||||||
|
"datadog.trace.agent.decorator.ServerDecorator",
|
||||||
|
"datadog.trace.agent.decorator.HttpServerDecorator",
|
||||||
|
packageName + ".server.NettyHttpServerDecorator",
|
||||||
packageName + ".server.NettyRequestExtractAdapter",
|
packageName + ".server.NettyRequestExtractAdapter",
|
||||||
packageName + ".server.HttpServerRequestTracingHandler",
|
packageName + ".server.HttpServerRequestTracingHandler",
|
||||||
packageName + ".server.HttpServerResponseTracingHandler",
|
packageName + ".server.HttpServerResponseTracingHandler",
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
package datadog.trace.instrumentation.netty41.client;
|
package datadog.trace.instrumentation.netty41.client;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http.HttpHeaderNames.HOST;
|
import static datadog.trace.instrumentation.netty41.client.NettyHttpClientDecorator.DECORATE;
|
||||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
|
||||||
|
|
||||||
import datadog.trace.api.DDSpanTypes;
|
|
||||||
import datadog.trace.api.DDTags;
|
|
||||||
import datadog.trace.context.TraceScope;
|
import datadog.trace.context.TraceScope;
|
||||||
import datadog.trace.instrumentation.netty41.AttributeKeys;
|
import datadog.trace.instrumentation.netty41.AttributeKeys;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
@ -13,12 +10,8 @@ import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.handler.codec.http.HttpRequest;
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.propagation.Format;
|
import io.opentracing.propagation.Format;
|
||||||
import io.opentracing.tag.Tags;
|
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.util.Collections;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@ -39,19 +32,11 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
}
|
}
|
||||||
|
|
||||||
final HttpRequest request = (HttpRequest) msg;
|
final HttpRequest request = (HttpRequest) msg;
|
||||||
final InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
|
|
||||||
|
|
||||||
final Span span =
|
final Span span = GlobalTracer.get().buildSpan("netty.client.request").start();
|
||||||
GlobalTracer.get()
|
DECORATE.afterStart(span);
|
||||||
.buildSpan("netty.client.request")
|
DECORATE.onRequest(span, request);
|
||||||
.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
|
DECORATE.onPeerConnection(span, (InetSocketAddress) ctx.channel().remoteAddress());
|
||||||
.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();
|
|
||||||
|
|
||||||
// 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")) {
|
||||||
|
@ -65,9 +50,9 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
try {
|
try {
|
||||||
ctx.write(msg, prm);
|
ctx.write(msg, prm);
|
||||||
} catch (final Throwable throwable) {
|
} catch (final Throwable throwable) {
|
||||||
Tags.ERROR.set(span, Boolean.TRUE);
|
DECORATE.onError(span, throwable);
|
||||||
span.log(Collections.singletonMap(ERROR_OBJECT, throwable));
|
DECORATE.beforeFinish(span);
|
||||||
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
span.finish();
|
||||||
throw throwable;
|
throw throwable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,18 +60,4 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
scope.close();
|
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package datadog.trace.instrumentation.netty41.client;
|
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.context.TraceScope;
|
||||||
import datadog.trace.instrumentation.netty41.AttributeKeys;
|
import datadog.trace.instrumentation.netty41.AttributeKeys;
|
||||||
|
@ -11,7 +11,6 @@ import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.tag.Tags;
|
import io.opentracing.tag.Tags;
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapter {
|
public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
||||||
|
@ -33,8 +32,8 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt
|
||||||
ctx.fireChannelRead(msg);
|
ctx.fireChannelRead(msg);
|
||||||
} catch (final Throwable throwable) {
|
} catch (final Throwable throwable) {
|
||||||
if (finishSpan) {
|
if (finishSpan) {
|
||||||
Tags.ERROR.set(span, Boolean.TRUE);
|
DECORATE.onError(span, throwable);
|
||||||
span.log(Collections.singletonMap(ERROR_OBJECT, throwable));
|
DECORATE.beforeFinish(span);
|
||||||
Tags.HTTP_STATUS.set(span, 500);
|
Tags.HTTP_STATUS.set(span, 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;
|
||||||
|
@ -42,7 +41,8 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt
|
||||||
}
|
}
|
||||||
|
|
||||||
if (finishSpan) {
|
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
|
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<HttpRequest, HttpResponse> {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,7 @@
|
||||||
package datadog.trace.instrumentation.netty41.server;
|
package datadog.trace.instrumentation.netty41.server;
|
||||||
|
|
||||||
import static io.netty.handler.codec.http.HttpHeaderNames.HOST;
|
import static datadog.trace.instrumentation.netty41.server.NettyHttpServerDecorator.DECORATE;
|
||||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
|
||||||
|
|
||||||
import datadog.trace.api.DDSpanTypes;
|
|
||||||
import datadog.trace.api.DDTags;
|
|
||||||
import datadog.trace.context.TraceScope;
|
import datadog.trace.context.TraceScope;
|
||||||
import datadog.trace.instrumentation.netty41.AttributeKeys;
|
import datadog.trace.instrumentation.netty41.AttributeKeys;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
@ -14,10 +11,8 @@ import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.SpanContext;
|
import io.opentracing.SpanContext;
|
||||||
import io.opentracing.propagation.Format;
|
import io.opentracing.propagation.Format;
|
||||||
import io.opentracing.tag.Tags;
|
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapter {
|
public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
|
||||||
|
@ -34,35 +29,27 @@ public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapte
|
||||||
GlobalTracer.get()
|
GlobalTracer.get()
|
||||||
.extract(Format.Builtin.HTTP_HEADERS, new NettyRequestExtractAdapter(request));
|
.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 =
|
final Scope scope =
|
||||||
GlobalTracer.get()
|
GlobalTracer.get()
|
||||||
.buildSpan("netty.request")
|
.buildSpan("netty.request")
|
||||||
.asChildOf(extractedContext)
|
.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);
|
.startActive(false);
|
||||||
|
final Span span = scope.span();
|
||||||
|
DECORATE.afterStart(span);
|
||||||
|
DECORATE.onRequest(span, request);
|
||||||
|
DECORATE.onPeerConnection(span, remoteAddress);
|
||||||
|
|
||||||
if (scope instanceof TraceScope) {
|
if (scope instanceof TraceScope) {
|
||||||
((TraceScope) scope).setAsyncPropagation(true);
|
((TraceScope) scope).setAsyncPropagation(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Span span = scope.span();
|
|
||||||
ctx.channel().attr(AttributeKeys.SERVER_ATTRIBUTE_KEY).set(span);
|
ctx.channel().attr(AttributeKeys.SERVER_ATTRIBUTE_KEY).set(span);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ctx.fireChannelRead(msg);
|
ctx.fireChannelRead(msg);
|
||||||
} catch (final Throwable throwable) {
|
} catch (final Throwable throwable) {
|
||||||
Tags.ERROR.set(span, Boolean.TRUE);
|
DECORATE.onError(span, throwable);
|
||||||
span.log(Collections.singletonMap(ERROR_OBJECT, throwable));
|
DECORATE.beforeFinish(span);
|
||||||
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
||||||
throw throwable;
|
throw throwable;
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package datadog.trace.instrumentation.netty41.server;
|
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 datadog.trace.instrumentation.netty41.AttributeKeys;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
@ -9,7 +9,6 @@ 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.Span;
|
||||||
import io.opentracing.tag.Tags;
|
import io.opentracing.tag.Tags;
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdapter {
|
public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdapter {
|
||||||
|
|
||||||
|
@ -26,14 +25,13 @@ public class HttpServerResponseTracingHandler extends ChannelOutboundHandlerAdap
|
||||||
try {
|
try {
|
||||||
ctx.write(msg, prm);
|
ctx.write(msg, prm);
|
||||||
} catch (final Throwable throwable) {
|
} catch (final Throwable throwable) {
|
||||||
Tags.ERROR.set(span, Boolean.TRUE);
|
DECORATE.onError(span, throwable);
|
||||||
span.log(Collections.singletonMap(ERROR_OBJECT, throwable));
|
|
||||||
Tags.HTTP_STATUS.set(span, 500);
|
Tags.HTTP_STATUS.set(span, 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;
|
||||||
}
|
}
|
||||||
|
DECORATE.onResponse(span, response);
|
||||||
Tags.HTTP_STATUS.set(span, response.status().code());
|
DECORATE.beforeFinish(span);
|
||||||
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
span.finish(); // Finish the span manually since finishSpanOnClose was false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<HttpRequest, HttpResponse> {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -58,7 +58,8 @@ class Netty41ClientTest extends AgentTestRunner {
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
"$Tags.HTTP_STATUS.key" 200
|
||||||
"$Tags.HTTP_URL.key" "$server.address/"
|
"$Tags.HTTP_URL.key" "$server.address/"
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$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
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
|
||||||
defaultTags()
|
defaultTags()
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,6 @@ import io.netty.channel.nio.NioEventLoopGroup
|
||||||
import io.netty.channel.socket.nio.NioServerSocketChannel
|
import io.netty.channel.socket.nio.NioServerSocketChannel
|
||||||
import io.netty.handler.codec.http.DefaultFullHttpResponse
|
import io.netty.handler.codec.http.DefaultFullHttpResponse
|
||||||
import io.netty.handler.codec.http.FullHttpResponse
|
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.HttpRequestDecoder
|
||||||
import io.netty.handler.codec.http.HttpResponseEncoder
|
import io.netty.handler.codec.http.HttpResponseEncoder
|
||||||
import io.netty.handler.codec.http.HttpResponseStatus
|
import io.netty.handler.codec.http.HttpResponseStatus
|
||||||
|
@ -28,6 +27,9 @@ import okhttp3.OkHttpClient
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import spock.lang.Shared
|
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 {
|
class Netty41ServerTest extends AgentTestRunner {
|
||||||
|
|
||||||
@Shared
|
@Shared
|
||||||
|
@ -68,6 +70,7 @@ class Netty41ServerTest extends AgentTestRunner {
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
"$Tags.HTTP_STATUS.key" 200
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/"
|
"$Tags.HTTP_URL.key" "http://localhost:$port/"
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
defaultTags(true)
|
defaultTags(true)
|
||||||
|
@ -113,6 +116,7 @@ class Netty41ServerTest extends AgentTestRunner {
|
||||||
"$Tags.HTTP_STATUS.key" responseCode.code()
|
"$Tags.HTTP_STATUS.key" responseCode.code()
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/"
|
"$Tags.HTTP_URL.key" "http://localhost:$port/"
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -147,8 +151,8 @@ class Netty41ServerTest extends AgentTestRunner {
|
||||||
if (msg instanceof LastHttpContent) {
|
if (msg instanceof LastHttpContent) {
|
||||||
ByteBuf content = Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8)
|
ByteBuf content = Unpooled.copiedBuffer("Hello World", CharsetUtil.UTF_8)
|
||||||
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, responseCode, content)
|
FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, responseCode, content)
|
||||||
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain")
|
response.headers().set(CONTENT_TYPE, "text/plain")
|
||||||
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes())
|
response.headers().set(CONTENT_LENGTH, content.readableBytes())
|
||||||
ctx.write(response)
|
ctx.write(response)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -84,6 +84,7 @@ class SpringWebfluxTest extends AgentTestRunner {
|
||||||
"$Tags.COMPONENT.key" "netty"
|
"$Tags.COMPONENT.key" "netty"
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
"$Tags.HTTP_METHOD.key" "GET"
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
"$Tags.HTTP_STATUS.key" 200
|
||||||
|
@ -156,6 +157,7 @@ class SpringWebfluxTest extends AgentTestRunner {
|
||||||
"$Tags.COMPONENT.key" "netty"
|
"$Tags.COMPONENT.key" "netty"
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
"$Tags.HTTP_METHOD.key" "GET"
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
"$Tags.HTTP_STATUS.key" 200
|
||||||
|
@ -216,6 +218,7 @@ class SpringWebfluxTest extends AgentTestRunner {
|
||||||
"$Tags.COMPONENT.key" "netty"
|
"$Tags.COMPONENT.key" "netty"
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
"$Tags.HTTP_METHOD.key" "GET"
|
||||||
"$Tags.HTTP_STATUS.key" 404
|
"$Tags.HTTP_STATUS.key" 404
|
||||||
|
@ -278,6 +281,7 @@ class SpringWebfluxTest extends AgentTestRunner {
|
||||||
"$Tags.COMPONENT.key" "netty"
|
"$Tags.COMPONENT.key" "netty"
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.HTTP_METHOD.key" "POST"
|
"$Tags.HTTP_METHOD.key" "POST"
|
||||||
"$Tags.HTTP_STATUS.key" 202
|
"$Tags.HTTP_STATUS.key" 202
|
||||||
|
@ -320,6 +324,7 @@ class SpringWebfluxTest extends AgentTestRunner {
|
||||||
"$Tags.COMPONENT.key" "netty"
|
"$Tags.COMPONENT.key" "netty"
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
"$Tags.HTTP_METHOD.key" "GET"
|
||||||
"$Tags.HTTP_STATUS.key" 500
|
"$Tags.HTTP_STATUS.key" 500
|
||||||
|
@ -392,6 +397,7 @@ class SpringWebfluxTest extends AgentTestRunner {
|
||||||
"$Tags.COMPONENT.key" "netty"
|
"$Tags.COMPONENT.key" "netty"
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
"$Tags.HTTP_METHOD.key" "GET"
|
||||||
"$Tags.HTTP_STATUS.key" 307
|
"$Tags.HTTP_STATUS.key" 307
|
||||||
|
@ -439,6 +445,7 @@ class SpringWebfluxTest extends AgentTestRunner {
|
||||||
"$Tags.COMPONENT.key" "netty"
|
"$Tags.COMPONENT.key" "netty"
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
"$Tags.HTTP_METHOD.key" "GET"
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
"$Tags.HTTP_STATUS.key" 200
|
||||||
|
@ -500,6 +507,7 @@ class SpringWebfluxTest extends AgentTestRunner {
|
||||||
"$Tags.COMPONENT.key" "netty"
|
"$Tags.COMPONENT.key" "netty"
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
"$Tags.HTTP_METHOD.key" "GET"
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
"$Tags.HTTP_STATUS.key" 200
|
||||||
|
|
|
@ -80,6 +80,7 @@ class VertxHttpClientTest extends AgentTestRunner {
|
||||||
"$Tags.HTTP_STATUS.key" expectedStatus
|
"$Tags.HTTP_STATUS.key" expectedStatus
|
||||||
"$Tags.HTTP_URL.key" "${server.address}/$route"
|
"$Tags.HTTP_URL.key" "${server.address}/$route"
|
||||||
"$Tags.PEER_HOSTNAME.key" server.address.host
|
"$Tags.PEER_HOSTNAME.key" server.address.host
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" server.address.port
|
"$Tags.PEER_PORT.key" server.address.port
|
||||||
"$Tags.HTTP_METHOD.key" "GET"
|
"$Tags.HTTP_METHOD.key" "GET"
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_CLIENT
|
||||||
|
|
|
@ -59,6 +59,7 @@ class VertxServerTest extends AgentTestRunner {
|
||||||
"$Tags.HTTP_STATUS.key" 200
|
"$Tags.HTTP_STATUS.key" 200
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/test"
|
"$Tags.HTTP_URL.key" "http://localhost:$port/test"
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
defaultTags(true)
|
defaultTags(true)
|
||||||
|
@ -95,6 +96,7 @@ class VertxServerTest extends AgentTestRunner {
|
||||||
"$Tags.HTTP_STATUS.key" responseCode.code()
|
"$Tags.HTTP_STATUS.key" responseCode.code()
|
||||||
"$Tags.HTTP_URL.key" "http://localhost:$port/$path"
|
"$Tags.HTTP_URL.key" "http://localhost:$port/$path"
|
||||||
"$Tags.PEER_HOSTNAME.key" "localhost"
|
"$Tags.PEER_HOSTNAME.key" "localhost"
|
||||||
|
"$Tags.PEER_HOST_IPV4.key" "127.0.0.1"
|
||||||
"$Tags.PEER_PORT.key" Integer
|
"$Tags.PEER_PORT.key" Integer
|
||||||
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
"$Tags.SPAN_KIND.key" Tags.SPAN_KIND_SERVER
|
||||||
if (error) {
|
if (error) {
|
||||||
|
|
Loading…
Reference in New Issue