Merge pull request #791 from DataDog/mar-kolya/handle-scopes
Mar kolya/handle scopes
This commit is contained in:
commit
6ee172baaa
|
@ -34,9 +34,11 @@ public class TracingExecutionInterceptor implements ExecutionInterceptor {
|
||||||
public void beforeExecution(
|
public void beforeExecution(
|
||||||
final Context.BeforeExecution context, final ExecutionAttributes executionAttributes) {
|
final Context.BeforeExecution context, final ExecutionAttributes executionAttributes) {
|
||||||
final Span span = GlobalTracer.get().buildSpan("aws.command").start();
|
final Span span = GlobalTracer.get().buildSpan("aws.command").start();
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.afterStart(span);
|
DECORATE.afterStart(span);
|
||||||
executionAttributes.putAttribute(SPAN_ATTRIBUTE, span);
|
executionAttributes.putAttribute(SPAN_ATTRIBUTE, span);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterMarshalling(
|
public void afterMarshalling(
|
||||||
|
|
|
@ -14,6 +14,7 @@ import com.google.auto.service.AutoService;
|
||||||
import datadog.trace.agent.tooling.Instrumenter;
|
import datadog.trace.agent.tooling.Instrumenter;
|
||||||
import datadog.trace.api.DDTags;
|
import datadog.trace.api.DDTags;
|
||||||
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
||||||
|
import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.noop.NoopSpan;
|
import io.opentracing.noop.NoopSpan;
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
|
@ -113,14 +114,16 @@ public class CouchbaseBucketInstrumentation extends Instrumenter.Default {
|
||||||
declaringClass.getSimpleName().replace("CouchbaseAsync", "").replace("DefaultAsync", "");
|
declaringClass.getSimpleName().replace("CouchbaseAsync", "").replace("DefaultAsync", "");
|
||||||
final String resourceName = className + "." + method.getName();
|
final String resourceName = className + "." + method.getName();
|
||||||
|
|
||||||
// just replace the no-op span.
|
final Span span =
|
||||||
spanRef.set(
|
|
||||||
DECORATE.afterStart(
|
|
||||||
GlobalTracer.get()
|
GlobalTracer.get()
|
||||||
.buildSpan("couchbase.call")
|
.buildSpan("couchbase.call")
|
||||||
.withTag(DDTags.RESOURCE_NAME, resourceName)
|
.withTag(DDTags.RESOURCE_NAME, resourceName)
|
||||||
.withTag("bucket", bucket)
|
.withTag("bucket", bucket)
|
||||||
.start()));
|
.start();
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
|
// just replace the no-op span.
|
||||||
|
spanRef.set(DECORATE.afterStart(span));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,11 +139,13 @@ public class CouchbaseBucketInstrumentation extends Instrumenter.Default {
|
||||||
final Span span = spanRef.getAndSet(null);
|
final Span span = spanRef.getAndSet(null);
|
||||||
|
|
||||||
if (span != null) {
|
if (span != null) {
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.beforeFinish(span);
|
DECORATE.beforeFinish(span);
|
||||||
span.finish();
|
span.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class TraceSpanError implements Action1<Throwable> {
|
public static class TraceSpanError implements Action1<Throwable> {
|
||||||
private final AtomicReference<Span> spanRef;
|
private final AtomicReference<Span> spanRef;
|
||||||
|
@ -153,10 +158,12 @@ public class CouchbaseBucketInstrumentation extends Instrumenter.Default {
|
||||||
public void call(final Throwable throwable) {
|
public void call(final Throwable throwable) {
|
||||||
final Span span = spanRef.getAndSet(null);
|
final Span span = spanRef.getAndSet(null);
|
||||||
if (span != null) {
|
if (span != null) {
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.onError(span, throwable);
|
DECORATE.onError(span, throwable);
|
||||||
DECORATE.beforeFinish(span);
|
DECORATE.beforeFinish(span);
|
||||||
span.finish();
|
span.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import com.google.auto.service.AutoService;
|
||||||
import datadog.trace.agent.tooling.Instrumenter;
|
import datadog.trace.agent.tooling.Instrumenter;
|
||||||
import datadog.trace.api.DDTags;
|
import datadog.trace.api.DDTags;
|
||||||
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
||||||
|
import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.noop.NoopSpan;
|
import io.opentracing.noop.NoopSpan;
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
|
@ -108,13 +109,15 @@ public class CouchbaseClusterInstrumentation extends Instrumenter.Default {
|
||||||
declaringClass.getSimpleName().replace("CouchbaseAsync", "").replace("DefaultAsync", "");
|
declaringClass.getSimpleName().replace("CouchbaseAsync", "").replace("DefaultAsync", "");
|
||||||
final String resourceName = className + "." + method.getName();
|
final String resourceName = className + "." + method.getName();
|
||||||
|
|
||||||
// just replace the no-op span.
|
final Span span =
|
||||||
spanRef.set(
|
|
||||||
DECORATE.afterStart(
|
|
||||||
GlobalTracer.get()
|
GlobalTracer.get()
|
||||||
.buildSpan("couchbase.call")
|
.buildSpan("couchbase.call")
|
||||||
.withTag(DDTags.RESOURCE_NAME, resourceName)
|
.withTag(DDTags.RESOURCE_NAME, resourceName)
|
||||||
.start()));
|
.start();
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
|
// just replace the no-op span.
|
||||||
|
spanRef.set(DECORATE.afterStart(scope.span()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,11 +133,13 @@ public class CouchbaseClusterInstrumentation extends Instrumenter.Default {
|
||||||
final Span span = spanRef.getAndSet(null);
|
final Span span = spanRef.getAndSet(null);
|
||||||
|
|
||||||
if (span != null) {
|
if (span != null) {
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.beforeFinish(span);
|
DECORATE.beforeFinish(span);
|
||||||
span.finish();
|
span.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class TraceSpanError implements Action1<Throwable> {
|
public static class TraceSpanError implements Action1<Throwable> {
|
||||||
private final AtomicReference<Span> spanRef;
|
private final AtomicReference<Span> spanRef;
|
||||||
|
@ -147,10 +152,12 @@ public class CouchbaseClusterInstrumentation extends Instrumenter.Default {
|
||||||
public void call(final Throwable throwable) {
|
public void call(final Throwable throwable) {
|
||||||
final Span span = spanRef.getAndSet(null);
|
final Span span = spanRef.getAndSet(null);
|
||||||
if (span != null) {
|
if (span != null) {
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.onError(span, throwable);
|
DECORATE.onError(span, throwable);
|
||||||
DECORATE.beforeFinish(span);
|
DECORATE.beforeFinish(span);
|
||||||
span.finish();
|
span.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,10 @@ import com.datastax.driver.core.Statement;
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.Tracer;
|
import io.opentracing.Tracer;
|
||||||
|
import io.opentracing.util.GlobalTracer;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
@ -58,89 +60,109 @@ public class TracingSession implements Session {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet execute(final String query) {
|
public ResultSet execute(final String query) {
|
||||||
final Span span = buildSpan(query);
|
try (final Scope scope = startSpanWithScope(query)) {
|
||||||
ResultSet resultSet = null;
|
|
||||||
try {
|
try {
|
||||||
resultSet = session.execute(query);
|
final ResultSet resultSet = session.execute(query);
|
||||||
|
beforeSpanFinish(scope.span(), resultSet);
|
||||||
return resultSet;
|
return resultSet;
|
||||||
|
} catch (final RuntimeException e) {
|
||||||
|
beforeSpanFinish(scope.span(), e);
|
||||||
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
finishSpan(span, resultSet);
|
scope.span().finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet execute(final String query, final Object... values) {
|
public ResultSet execute(final String query, final Object... values) {
|
||||||
final Span span = buildSpan(query);
|
try (final Scope scope = startSpanWithScope(query)) {
|
||||||
ResultSet resultSet = null;
|
|
||||||
try {
|
try {
|
||||||
resultSet = session.execute(query, values);
|
final ResultSet resultSet = session.execute(query, values);
|
||||||
|
beforeSpanFinish(scope.span(), resultSet);
|
||||||
return resultSet;
|
return resultSet;
|
||||||
|
} catch (final RuntimeException e) {
|
||||||
|
beforeSpanFinish(scope.span(), e);
|
||||||
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
finishSpan(span, resultSet);
|
scope.span().finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet execute(final String query, final Map<String, Object> values) {
|
public ResultSet execute(final String query, final Map<String, Object> values) {
|
||||||
final Span span = buildSpan(query);
|
try (final Scope scope = startSpanWithScope(query)) {
|
||||||
ResultSet resultSet = null;
|
|
||||||
try {
|
try {
|
||||||
resultSet = session.execute(query, values);
|
final ResultSet resultSet = session.execute(query, values);
|
||||||
|
beforeSpanFinish(scope.span(), resultSet);
|
||||||
return resultSet;
|
return resultSet;
|
||||||
|
} catch (final RuntimeException e) {
|
||||||
|
beforeSpanFinish(scope.span(), e);
|
||||||
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
finishSpan(span, resultSet);
|
scope.span().finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSet execute(final Statement statement) {
|
public ResultSet execute(final Statement statement) {
|
||||||
final String query = getQuery(statement);
|
final String query = getQuery(statement);
|
||||||
final Span span = buildSpan(query);
|
try (final Scope scope = startSpanWithScope(query)) {
|
||||||
ResultSet resultSet = null;
|
|
||||||
try {
|
try {
|
||||||
resultSet = session.execute(statement);
|
final ResultSet resultSet = session.execute(statement);
|
||||||
|
beforeSpanFinish(scope.span(), resultSet);
|
||||||
return resultSet;
|
return resultSet;
|
||||||
|
} catch (final RuntimeException e) {
|
||||||
|
beforeSpanFinish(scope.span(), e);
|
||||||
|
throw e;
|
||||||
} finally {
|
} finally {
|
||||||
finishSpan(span, resultSet);
|
scope.span().finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSetFuture executeAsync(final String query) {
|
public ResultSetFuture executeAsync(final String query) {
|
||||||
final Span span = buildSpan(query);
|
try (final Scope scope = startSpanWithScope(query)) {
|
||||||
final ResultSetFuture future = session.executeAsync(query);
|
final ResultSetFuture future = session.executeAsync(query);
|
||||||
future.addListener(createListener(span, future), executorService);
|
future.addListener(createListener(scope.span(), future), executorService);
|
||||||
|
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSetFuture executeAsync(final String query, final Object... values) {
|
public ResultSetFuture executeAsync(final String query, final Object... values) {
|
||||||
final Span span = buildSpan(query);
|
try (final Scope scope = startSpanWithScope(query)) {
|
||||||
final ResultSetFuture future = session.executeAsync(query, values);
|
final ResultSetFuture future = session.executeAsync(query, values);
|
||||||
future.addListener(createListener(span, future), executorService);
|
future.addListener(createListener(scope.span(), future), executorService);
|
||||||
|
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSetFuture executeAsync(final String query, final Map<String, Object> values) {
|
public ResultSetFuture executeAsync(final String query, final Map<String, Object> values) {
|
||||||
final Span span = buildSpan(query);
|
try (final Scope scope = startSpanWithScope(query)) {
|
||||||
final ResultSetFuture future = session.executeAsync(query, values);
|
final ResultSetFuture future = session.executeAsync(query, values);
|
||||||
future.addListener(createListener(span, future), executorService);
|
future.addListener(createListener(scope.span(), future), executorService);
|
||||||
|
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ResultSetFuture executeAsync(final Statement statement) {
|
public ResultSetFuture executeAsync(final Statement statement) {
|
||||||
final String query = getQuery(statement);
|
final String query = getQuery(statement);
|
||||||
final Span span = buildSpan(query);
|
try (final Scope scope = startSpanWithScope(query)) {
|
||||||
final ResultSetFuture future = session.executeAsync(statement);
|
final ResultSetFuture future = session.executeAsync(statement);
|
||||||
future.addListener(createListener(span, future), executorService);
|
future.addListener(createListener(scope.span(), future), executorService);
|
||||||
|
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PreparedStatement prepare(final String query) {
|
public PreparedStatement prepare(final String query) {
|
||||||
|
@ -202,32 +224,33 @@ public class TracingSession implements Session {
|
||||||
return new Runnable() {
|
return new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
finishSpan(span, future.get());
|
beforeSpanFinish(span, future.get());
|
||||||
} catch (final InterruptedException | ExecutionException e) {
|
} catch (final InterruptedException | ExecutionException e) {
|
||||||
finishSpan(span, e);
|
beforeSpanFinish(span, e);
|
||||||
|
} finally {
|
||||||
|
span.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private Span buildSpan(final String query) {
|
private Scope startSpanWithScope(final String query) {
|
||||||
final Span span = tracer.buildSpan("cassandra.execute").start();
|
final Span span = tracer.buildSpan("cassandra.execute").start();
|
||||||
|
final Scope scope = tracer.scopeManager().activate(span, false);
|
||||||
DECORATE.afterStart(span);
|
DECORATE.afterStart(span);
|
||||||
DECORATE.onConnection(span, session);
|
DECORATE.onConnection(span, session);
|
||||||
DECORATE.onStatement(span, query);
|
DECORATE.onStatement(span, query);
|
||||||
return span;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void finishSpan(final Span span, final ResultSet resultSet) {
|
private static void beforeSpanFinish(final Span span, final ResultSet resultSet) {
|
||||||
DECORATE.onResponse(span, resultSet);
|
DECORATE.onResponse(span, resultSet);
|
||||||
DECORATE.beforeFinish(span);
|
DECORATE.beforeFinish(span);
|
||||||
span.finish();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void finishSpan(final Span span, final Exception e) {
|
private static void beforeSpanFinish(final Span span, final Exception e) {
|
||||||
DECORATE.onError(span, e);
|
DECORATE.onError(span, e);
|
||||||
DECORATE.beforeFinish(span);
|
DECORATE.beforeFinish(span);
|
||||||
span.finish();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.Tracer;
|
import io.opentracing.Tracer;
|
||||||
import io.opentracing.propagation.Format;
|
import io.opentracing.propagation.Format;
|
||||||
|
import io.opentracing.util.GlobalTracer;
|
||||||
|
|
||||||
public class TracingClientInterceptor implements ClientInterceptor {
|
public class TracingClientInterceptor implements ClientInterceptor {
|
||||||
|
|
||||||
|
@ -36,10 +37,11 @@ public class TracingClientInterceptor implements ClientInterceptor {
|
||||||
.buildSpan("grpc.client")
|
.buildSpan("grpc.client")
|
||||||
.withTag(DDTags.RESOURCE_NAME, method.getFullMethodName())
|
.withTag(DDTags.RESOURCE_NAME, method.getFullMethodName())
|
||||||
.start();
|
.start();
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.afterStart(span);
|
DECORATE.afterStart(span);
|
||||||
|
|
||||||
final ClientCall<ReqT, RespT> result;
|
final ClientCall<ReqT, RespT> result;
|
||||||
try (final Scope ignore = tracer.scopeManager().activate(span, false)) {
|
try {
|
||||||
// call other interceptors
|
// call other interceptors
|
||||||
result = next.newCall(method, callOptions);
|
result = next.newCall(method, callOptions);
|
||||||
} catch (final Throwable e) {
|
} catch (final Throwable e) {
|
||||||
|
@ -51,6 +53,7 @@ public class TracingClientInterceptor implements ClientInterceptor {
|
||||||
|
|
||||||
return new TracingClientCall<>(tracer, span, result);
|
return new TracingClientCall<>(tracer, span, result);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static final class TracingClientCall<ReqT, RespT>
|
static final class TracingClientCall<ReqT, RespT>
|
||||||
extends ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT> {
|
extends ForwardingClientCall.SimpleForwardingClientCall<ReqT, RespT> {
|
||||||
|
@ -128,14 +131,14 @@ public class TracingClientInterceptor implements ClientInterceptor {
|
||||||
public void onClose(final Status status, final Metadata trailers) {
|
public void onClose(final Status status, final Metadata trailers) {
|
||||||
DECORATE.onClose(span, status);
|
DECORATE.onClose(span, status);
|
||||||
// Finishes span.
|
// Finishes span.
|
||||||
try (final Scope ignored = tracer.scopeManager().activate(span, true)) {
|
try (final Scope ignored = tracer.scopeManager().activate(span, false)) {
|
||||||
delegate().onClose(status, trailers);
|
delegate().onClose(status, trailers);
|
||||||
DECORATE.beforeFinish(span);
|
|
||||||
} catch (final Throwable e) {
|
} catch (final Throwable e) {
|
||||||
DECORATE.onError(span, e);
|
DECORATE.onError(span, e);
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
DECORATE.beforeFinish(span);
|
DECORATE.beforeFinish(span);
|
||||||
span.finish();
|
span.finish();
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,7 @@ public class TracingServerInterceptor implements ServerInterceptor {
|
||||||
@Override
|
@Override
|
||||||
public void onCancel() {
|
public void onCancel() {
|
||||||
// Finishes span.
|
// Finishes span.
|
||||||
try (final Scope scope = tracer.scopeManager().activate(span, true)) {
|
try (final Scope scope = tracer.scopeManager().activate(span, false)) {
|
||||||
if (scope instanceof TraceScope) {
|
if (scope instanceof TraceScope) {
|
||||||
((TraceScope) scope).setAsyncPropagation(true);
|
((TraceScope) scope).setAsyncPropagation(true);
|
||||||
}
|
}
|
||||||
|
@ -149,19 +149,19 @@ public class TracingServerInterceptor implements ServerInterceptor {
|
||||||
if (scope instanceof TraceScope) {
|
if (scope instanceof TraceScope) {
|
||||||
((TraceScope) scope).setAsyncPropagation(false);
|
((TraceScope) scope).setAsyncPropagation(false);
|
||||||
}
|
}
|
||||||
DECORATE.beforeFinish(span);
|
|
||||||
} catch (final Throwable e) {
|
} catch (final Throwable e) {
|
||||||
DECORATE.onError(span, e);
|
DECORATE.onError(span, e);
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
DECORATE.beforeFinish(span);
|
DECORATE.beforeFinish(span);
|
||||||
span.finish();
|
span.finish();
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onComplete() {
|
public void onComplete() {
|
||||||
// Finishes span.
|
// Finishes span.
|
||||||
try (final Scope scope = tracer.scopeManager().activate(span, true)) {
|
try (final Scope scope = tracer.scopeManager().activate(span, false)) {
|
||||||
if (scope instanceof TraceScope) {
|
if (scope instanceof TraceScope) {
|
||||||
((TraceScope) scope).setAsyncPropagation(true);
|
((TraceScope) scope).setAsyncPropagation(true);
|
||||||
}
|
}
|
||||||
|
@ -169,12 +169,12 @@ public class TracingServerInterceptor implements ServerInterceptor {
|
||||||
if (scope instanceof TraceScope) {
|
if (scope instanceof TraceScope) {
|
||||||
((TraceScope) scope).setAsyncPropagation(false);
|
((TraceScope) scope).setAsyncPropagation(false);
|
||||||
}
|
}
|
||||||
DECORATE.beforeFinish(span);
|
|
||||||
} catch (final Throwable e) {
|
} catch (final Throwable e) {
|
||||||
DECORATE.onError(span, e);
|
DECORATE.onError(span, e);
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
DECORATE.beforeFinish(span);
|
DECORATE.beforeFinish(span);
|
||||||
span.finish();
|
span.finish();
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ import datadog.trace.agent.tooling.Instrumenter;
|
||||||
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
import datadog.trace.bootstrap.CallDepthThreadLocalMap;
|
||||||
import datadog.trace.bootstrap.ContextStore;
|
import datadog.trace.bootstrap.ContextStore;
|
||||||
import datadog.trace.bootstrap.InstrumentationContext;
|
import datadog.trace.bootstrap.InstrumentationContext;
|
||||||
|
import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.Tracer;
|
import io.opentracing.Tracer;
|
||||||
import io.opentracing.propagation.Format;
|
import io.opentracing.propagation.Format;
|
||||||
|
@ -178,10 +179,12 @@ public class HttpUrlConnectionInstrumentation extends Instrumenter.Default {
|
||||||
public Span startSpan(final HttpURLConnection connection) {
|
public Span startSpan(final HttpURLConnection connection) {
|
||||||
final Tracer.SpanBuilder builder = GlobalTracer.get().buildSpan(OPERATION_NAME);
|
final Tracer.SpanBuilder builder = GlobalTracer.get().buildSpan(OPERATION_NAME);
|
||||||
span = builder.start();
|
span = builder.start();
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.afterStart(span);
|
DECORATE.afterStart(span);
|
||||||
DECORATE.onRequest(span, connection);
|
DECORATE.onRequest(span, connection);
|
||||||
return span;
|
return span;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasSpan() {
|
public boolean hasSpan() {
|
||||||
return span != null;
|
return span != null;
|
||||||
|
@ -196,12 +199,14 @@ public class HttpUrlConnectionInstrumentation extends Instrumenter.Default {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finishSpan(final Throwable throwable) {
|
public void finishSpan(final Throwable throwable) {
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.onError(span, throwable);
|
DECORATE.onError(span, throwable);
|
||||||
DECORATE.beforeFinish(span);
|
DECORATE.beforeFinish(span);
|
||||||
span.finish();
|
span.finish();
|
||||||
span = null;
|
span = null;
|
||||||
finished = true;
|
finished = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void finishSpan(final int responseCode) {
|
public void finishSpan(final int responseCode) {
|
||||||
/*
|
/*
|
||||||
|
@ -210,6 +215,7 @@ public class HttpUrlConnectionInstrumentation extends Instrumenter.Default {
|
||||||
* (e.g. breaks getOutputStream).
|
* (e.g. breaks getOutputStream).
|
||||||
*/
|
*/
|
||||||
if (responseCode > 0) {
|
if (responseCode > 0) {
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.onResponse(span, responseCode);
|
DECORATE.onResponse(span, responseCode);
|
||||||
DECORATE.beforeFinish(span);
|
DECORATE.beforeFinish(span);
|
||||||
span.finish();
|
span.finish();
|
||||||
|
@ -218,4 +224,5 @@ public class HttpUrlConnectionInstrumentation extends Instrumenter.Default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import datadog.trace.agent.tooling.Instrumenter;
|
||||||
import datadog.trace.api.Config;
|
import datadog.trace.api.Config;
|
||||||
import datadog.trace.api.DDSpanTypes;
|
import datadog.trace.api.DDSpanTypes;
|
||||||
import datadog.trace.api.DDTags;
|
import datadog.trace.api.DDTags;
|
||||||
|
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;
|
||||||
|
@ -65,7 +66,7 @@ public class UrlInstrumentation extends Instrumenter.Default {
|
||||||
.withTag(DDTags.SPAN_TYPE, DDSpanTypes.HTTP_CLIENT)
|
.withTag(DDTags.SPAN_TYPE, DDSpanTypes.HTTP_CLIENT)
|
||||||
.withTag(Tags.COMPONENT.getKey(), COMPONENT)
|
.withTag(Tags.COMPONENT.getKey(), COMPONENT)
|
||||||
.start();
|
.start();
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
Tags.HTTP_URL.set(span, url.toString());
|
Tags.HTTP_URL.set(span, url.toString());
|
||||||
Tags.PEER_PORT.set(span, url.getPort() == -1 ? 80 : url.getPort());
|
Tags.PEER_PORT.set(span, url.getPort() == -1 ? 80 : url.getPort());
|
||||||
Tags.PEER_HOSTNAME.set(span, url.getHost());
|
Tags.PEER_HOSTNAME.set(span, url.getHost());
|
||||||
|
@ -79,4 +80,5 @@ public class UrlInstrumentation extends Instrumenter.Default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,9 +81,9 @@ public final class JerseyClientConnectionErrorInstrumentation extends Instrument
|
||||||
@Advice.OnMethodExit(suppress = Throwable.class)
|
@Advice.OnMethodExit(suppress = Throwable.class)
|
||||||
public static void handleError(
|
public static void handleError(
|
||||||
@Advice.FieldValue("requestContext") final ClientRequest context,
|
@Advice.FieldValue("requestContext") final ClientRequest context,
|
||||||
@Advice.Return(readOnly = false) Future future) {
|
@Advice.Return(readOnly = false) Future<?> future) {
|
||||||
if (!(future instanceof WrappedFuture)) {
|
if (!(future instanceof WrappedFuture)) {
|
||||||
future = new WrappedFuture(future, context);
|
future = new WrappedFuture<>(future, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,9 +81,9 @@ public final class ResteasyClientConnectionErrorInstrumentation extends Instrume
|
||||||
@Advice.OnMethodExit(suppress = Throwable.class)
|
@Advice.OnMethodExit(suppress = Throwable.class)
|
||||||
public static void handleError(
|
public static void handleError(
|
||||||
@Advice.FieldValue("configuration") final ClientConfiguration context,
|
@Advice.FieldValue("configuration") final ClientConfiguration context,
|
||||||
@Advice.Return(readOnly = false) Future future) {
|
@Advice.Return(readOnly = false) Future<?> future) {
|
||||||
if (!(future instanceof WrappedFuture)) {
|
if (!(future instanceof WrappedFuture)) {
|
||||||
future = new WrappedFuture(future, context);
|
future = new WrappedFuture<>(future, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package datadog.trace.instrumentation.jaxrs;
|
||||||
import static datadog.trace.instrumentation.jaxrs.JaxRsClientDecorator.DECORATE;
|
import static datadog.trace.instrumentation.jaxrs.JaxRsClientDecorator.DECORATE;
|
||||||
|
|
||||||
import datadog.trace.api.DDTags;
|
import datadog.trace.api.DDTags;
|
||||||
|
import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.propagation.Format;
|
import io.opentracing.propagation.Format;
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
|
@ -21,12 +22,12 @@ public class ClientTracingFilter implements ClientRequestFilter, ClientResponseF
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void filter(final ClientRequestContext requestContext) {
|
public void filter(final ClientRequestContext requestContext) {
|
||||||
|
|
||||||
final Span span =
|
final Span span =
|
||||||
GlobalTracer.get()
|
GlobalTracer.get()
|
||||||
.buildSpan("jax-rs.client.call")
|
.buildSpan("jax-rs.client.call")
|
||||||
.withTag(DDTags.RESOURCE_NAME, requestContext.getMethod() + " jax-rs.client.call")
|
.withTag(DDTags.RESOURCE_NAME, requestContext.getMethod() + " jax-rs.client.call")
|
||||||
.start();
|
.start();
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.afterStart(span);
|
DECORATE.afterStart(span);
|
||||||
DECORATE.onRequest(span, requestContext);
|
DECORATE.onRequest(span, requestContext);
|
||||||
|
|
||||||
|
@ -40,6 +41,7 @@ public class ClientTracingFilter implements ClientRequestFilter, ClientResponseF
|
||||||
|
|
||||||
requestContext.setProperty(SPAN_PROPERTY_NAME, span);
|
requestContext.setProperty(SPAN_PROPERTY_NAME, span);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void filter(
|
public void filter(
|
||||||
|
|
|
@ -10,6 +10,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||||
|
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import datadog.trace.agent.tooling.Instrumenter;
|
import datadog.trace.agent.tooling.Instrumenter;
|
||||||
|
import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.SpanContext;
|
import io.opentracing.SpanContext;
|
||||||
import io.opentracing.Tracer;
|
import io.opentracing.Tracer;
|
||||||
|
@ -92,6 +93,7 @@ public final class JMSMessageConsumerInstrumentation extends Instrumenter.Defaul
|
||||||
}
|
}
|
||||||
|
|
||||||
final Span span = spanBuilder.start();
|
final Span span = spanBuilder.start();
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
CONSUMER_DECORATE.afterStart(span);
|
CONSUMER_DECORATE.afterStart(span);
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
CONSUMER_DECORATE.onReceive(span, method);
|
CONSUMER_DECORATE.onReceive(span, method);
|
||||||
|
@ -103,4 +105,5 @@ public final class JMSMessageConsumerInstrumentation extends Instrumenter.Defaul
|
||||||
span.finish();
|
span.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ public final class MongoClientInstrumentation extends Instrumenter.Default {
|
||||||
"datadog.trace.agent.decorator.ClientDecorator",
|
"datadog.trace.agent.decorator.ClientDecorator",
|
||||||
"datadog.trace.agent.decorator.DatabaseClientDecorator",
|
"datadog.trace.agent.decorator.DatabaseClientDecorator",
|
||||||
packageName + ".MongoClientDecorator",
|
packageName + ".MongoClientDecorator",
|
||||||
packageName + ".DDTracingCommandListener"
|
packageName + ".TracingCommandListener"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ public final class MongoClientInstrumentation extends Instrumenter.Default {
|
||||||
// referencing "this" in the method args causes the class to load under a transformer.
|
// referencing "this" in the method args causes the class to load under a transformer.
|
||||||
// This bypasses the Builder instrumentation. Casting as a workaround.
|
// This bypasses the Builder instrumentation. Casting as a workaround.
|
||||||
final MongoClientOptions.Builder builder = (MongoClientOptions.Builder) dis;
|
final MongoClientOptions.Builder builder = (MongoClientOptions.Builder) dis;
|
||||||
final DDTracingCommandListener listener = new DDTracingCommandListener();
|
final TracingCommandListener listener = new TracingCommandListener();
|
||||||
builder.addCommandListener(listener);
|
builder.addCommandListener(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import com.mongodb.event.CommandFailedEvent;
|
||||||
import com.mongodb.event.CommandListener;
|
import com.mongodb.event.CommandListener;
|
||||||
import com.mongodb.event.CommandStartedEvent;
|
import com.mongodb.event.CommandStartedEvent;
|
||||||
import com.mongodb.event.CommandSucceededEvent;
|
import com.mongodb.event.CommandSucceededEvent;
|
||||||
|
import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -13,13 +14,14 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class DDTracingCommandListener implements CommandListener {
|
public class TracingCommandListener implements CommandListener {
|
||||||
|
|
||||||
private final Map<Integer, Span> spanMap = new ConcurrentHashMap<>();
|
private final Map<Integer, Span> spanMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commandStarted(final CommandStartedEvent event) {
|
public void commandStarted(final CommandStartedEvent event) {
|
||||||
final Span span = GlobalTracer.get().buildSpan("mongo.query").start();
|
final Span span = GlobalTracer.get().buildSpan("mongo.query").start();
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.afterStart(span);
|
DECORATE.afterStart(span);
|
||||||
DECORATE.onConnection(span, event);
|
DECORATE.onConnection(span, event);
|
||||||
if (event.getConnectionDescription() != null
|
if (event.getConnectionDescription() != null
|
||||||
|
@ -31,6 +33,7 @@ public class DDTracingCommandListener implements CommandListener {
|
||||||
DECORATE.onStatement(span, event.getCommand());
|
DECORATE.onStatement(span, event.getCommand());
|
||||||
spanMap.put(event.getRequestId(), span);
|
spanMap.put(event.getRequestId(), span);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void commandSucceeded(final CommandSucceededEvent event) {
|
public void commandSucceeded(final CommandSucceededEvent event) {
|
|
@ -48,7 +48,7 @@ public final class MongoAsyncClientInstrumentation extends Instrumenter.Default
|
||||||
"datadog.trace.agent.decorator.ClientDecorator",
|
"datadog.trace.agent.decorator.ClientDecorator",
|
||||||
"datadog.trace.agent.decorator.DatabaseClientDecorator",
|
"datadog.trace.agent.decorator.DatabaseClientDecorator",
|
||||||
packageName + ".MongoClientDecorator",
|
packageName + ".MongoClientDecorator",
|
||||||
packageName + ".DDTracingCommandListener"
|
packageName + ".TracingCommandListener"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ public final class MongoAsyncClientInstrumentation extends Instrumenter.Default
|
||||||
// referencing "this" in the method args causes the class to load under a transformer.
|
// referencing "this" in the method args causes the class to load under a transformer.
|
||||||
// This bypasses the Builder instrumentation. Casting as a workaround.
|
// This bypasses the Builder instrumentation. Casting as a workaround.
|
||||||
final MongoClientSettings.Builder builder = (MongoClientSettings.Builder) dis;
|
final MongoClientSettings.Builder builder = (MongoClientSettings.Builder) dis;
|
||||||
final DDTracingCommandListener listener = new DDTracingCommandListener();
|
final TracingCommandListener listener = new TracingCommandListener();
|
||||||
builder.addCommandListener(listener);
|
builder.addCommandListener(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package datadog.trace.instrumentation.netty40;
|
package datadog.trace.instrumentation.netty40;
|
||||||
|
|
||||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
|
||||||
import static java.util.Collections.singletonMap;
|
import static java.util.Collections.singletonMap;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
|
@ -12,6 +11,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import datadog.trace.agent.tooling.Instrumenter;
|
import datadog.trace.agent.tooling.Instrumenter;
|
||||||
import datadog.trace.context.TraceScope;
|
import datadog.trace.context.TraceScope;
|
||||||
|
import datadog.trace.instrumentation.netty40.server.NettyHttpServerDecorator;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.opentracing.Scope;
|
import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
|
@ -83,18 +83,20 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
|
||||||
if (continuation == null) {
|
if (continuation == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final TraceScope scope = continuation.activate();
|
final TraceScope parentScope = continuation.activate();
|
||||||
|
|
||||||
final Span errorSpan =
|
final Span errorSpan =
|
||||||
GlobalTracer.get()
|
GlobalTracer.get()
|
||||||
.buildSpan("netty.connect")
|
.buildSpan("netty.connect")
|
||||||
.withTag(Tags.COMPONENT.getKey(), "netty")
|
.withTag(Tags.COMPONENT.getKey(), "netty")
|
||||||
.start();
|
.start();
|
||||||
Tags.ERROR.set(errorSpan, true);
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(errorSpan, false)) {
|
||||||
errorSpan.log(singletonMap(ERROR_OBJECT, cause));
|
NettyHttpServerDecorator.DECORATE.onError(errorSpan, cause);
|
||||||
|
NettyHttpServerDecorator.DECORATE.beforeFinish(errorSpan);
|
||||||
errorSpan.finish();
|
errorSpan.finish();
|
||||||
|
}
|
||||||
|
|
||||||
return scope;
|
return parentScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
|
|
|
@ -8,6 +8,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.handler.codec.http.HttpRequest;
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
|
import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.propagation.Format;
|
import io.opentracing.propagation.Format;
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
|
@ -24,16 +25,17 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceScope scope = null;
|
TraceScope parentScope = null;
|
||||||
final TraceScope.Continuation continuation =
|
final TraceScope.Continuation continuation =
|
||||||
ctx.channel().attr(AttributeKeys.PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY).getAndRemove();
|
ctx.channel().attr(AttributeKeys.PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY).getAndRemove();
|
||||||
if (continuation != null) {
|
if (continuation != null) {
|
||||||
scope = continuation.activate();
|
parentScope = continuation.activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
final HttpRequest request = (HttpRequest) msg;
|
final HttpRequest request = (HttpRequest) msg;
|
||||||
|
|
||||||
final Span span = GlobalTracer.get().buildSpan("netty.client.request").start();
|
final Span span = GlobalTracer.get().buildSpan("netty.client.request").start();
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.afterStart(span);
|
DECORATE.afterStart(span);
|
||||||
DECORATE.onRequest(span, request);
|
DECORATE.onRequest(span, request);
|
||||||
DECORATE.onPeerConnection(span, (InetSocketAddress) ctx.channel().remoteAddress());
|
DECORATE.onPeerConnection(span, (InetSocketAddress) ctx.channel().remoteAddress());
|
||||||
|
@ -42,7 +44,9 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
if (!request.headers().contains("amz-sdk-invocation-id")) {
|
if (!request.headers().contains("amz-sdk-invocation-id")) {
|
||||||
GlobalTracer.get()
|
GlobalTracer.get()
|
||||||
.inject(
|
.inject(
|
||||||
span.context(), Format.Builtin.HTTP_HEADERS, new NettyResponseInjectAdapter(request));
|
span.context(),
|
||||||
|
Format.Builtin.HTTP_HEADERS,
|
||||||
|
new NettyResponseInjectAdapter(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.channel().attr(AttributeKeys.CLIENT_ATTRIBUTE_KEY).set(span);
|
ctx.channel().attr(AttributeKeys.CLIENT_ATTRIBUTE_KEY).set(span);
|
||||||
|
@ -55,9 +59,10 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
span.finish();
|
span.finish();
|
||||||
throw throwable;
|
throw throwable;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (null != scope) {
|
if (null != parentScope) {
|
||||||
scope.close();
|
parentScope.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,9 @@ 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));
|
||||||
|
|
||||||
final Scope scope =
|
final Span span =
|
||||||
GlobalTracer.get()
|
GlobalTracer.get().buildSpan("netty.request").asChildOf(extractedContext).start();
|
||||||
.buildSpan("netty.request")
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
.asChildOf(extractedContext)
|
|
||||||
.startActive(false);
|
|
||||||
final Span span = scope.span();
|
|
||||||
DECORATE.afterStart(span);
|
DECORATE.afterStart(span);
|
||||||
DECORATE.onRequest(span, request);
|
DECORATE.onRequest(span, request);
|
||||||
DECORATE.onPeerConnection(span, remoteAddress);
|
DECORATE.onPeerConnection(span, remoteAddress);
|
||||||
|
@ -52,8 +49,7 @@ public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapte
|
||||||
DECORATE.beforeFinish(span);
|
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 {
|
}
|
||||||
scope.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package datadog.trace.instrumentation.netty41;
|
package datadog.trace.instrumentation.netty41;
|
||||||
|
|
||||||
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
import static datadog.trace.agent.tooling.ByteBuddyElementMatchers.safeHasSuperType;
|
||||||
import static io.opentracing.log.Fields.ERROR_OBJECT;
|
|
||||||
import static java.util.Collections.singletonMap;
|
import static java.util.Collections.singletonMap;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
import static net.bytebuddy.matcher.ElementMatchers.isInterface;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
|
@ -12,6 +11,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import datadog.trace.agent.tooling.Instrumenter;
|
import datadog.trace.agent.tooling.Instrumenter;
|
||||||
import datadog.trace.context.TraceScope;
|
import datadog.trace.context.TraceScope;
|
||||||
|
import datadog.trace.instrumentation.netty41.server.NettyHttpServerDecorator;
|
||||||
import io.netty.channel.ChannelFuture;
|
import io.netty.channel.ChannelFuture;
|
||||||
import io.opentracing.Scope;
|
import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
|
@ -83,18 +83,20 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
|
||||||
if (continuation == null) {
|
if (continuation == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final TraceScope scope = continuation.activate();
|
final TraceScope parentScope = continuation.activate();
|
||||||
|
|
||||||
final Span errorSpan =
|
final Span errorSpan =
|
||||||
GlobalTracer.get()
|
GlobalTracer.get()
|
||||||
.buildSpan("netty.connect")
|
.buildSpan("netty.connect")
|
||||||
.withTag(Tags.COMPONENT.getKey(), "netty")
|
.withTag(Tags.COMPONENT.getKey(), "netty")
|
||||||
.start();
|
.start();
|
||||||
Tags.ERROR.set(errorSpan, true);
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(errorSpan, false)) {
|
||||||
errorSpan.log(singletonMap(ERROR_OBJECT, cause));
|
NettyHttpServerDecorator.DECORATE.onError(errorSpan, cause);
|
||||||
|
NettyHttpServerDecorator.DECORATE.beforeFinish(errorSpan);
|
||||||
errorSpan.finish();
|
errorSpan.finish();
|
||||||
|
}
|
||||||
|
|
||||||
return scope;
|
return parentScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
|
|
|
@ -8,6 +8,7 @@ import io.netty.channel.ChannelHandlerContext;
|
||||||
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
import io.netty.channel.ChannelOutboundHandlerAdapter;
|
||||||
import io.netty.channel.ChannelPromise;
|
import io.netty.channel.ChannelPromise;
|
||||||
import io.netty.handler.codec.http.HttpRequest;
|
import io.netty.handler.codec.http.HttpRequest;
|
||||||
|
import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.propagation.Format;
|
import io.opentracing.propagation.Format;
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
|
@ -24,16 +25,17 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TraceScope scope = null;
|
TraceScope parentScope = null;
|
||||||
final TraceScope.Continuation continuation =
|
final TraceScope.Continuation continuation =
|
||||||
ctx.channel().attr(AttributeKeys.PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY).getAndRemove();
|
ctx.channel().attr(AttributeKeys.PARENT_CONNECT_CONTINUATION_ATTRIBUTE_KEY).getAndRemove();
|
||||||
if (continuation != null) {
|
if (continuation != null) {
|
||||||
scope = continuation.activate();
|
parentScope = continuation.activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
final HttpRequest request = (HttpRequest) msg;
|
final HttpRequest request = (HttpRequest) msg;
|
||||||
|
|
||||||
final Span span = GlobalTracer.get().buildSpan("netty.client.request").start();
|
final Span span = GlobalTracer.get().buildSpan("netty.client.request").start();
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.afterStart(span);
|
DECORATE.afterStart(span);
|
||||||
DECORATE.onRequest(span, request);
|
DECORATE.onRequest(span, request);
|
||||||
DECORATE.onPeerConnection(span, (InetSocketAddress) ctx.channel().remoteAddress());
|
DECORATE.onPeerConnection(span, (InetSocketAddress) ctx.channel().remoteAddress());
|
||||||
|
@ -42,7 +44,9 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
if (!request.headers().contains("amz-sdk-invocation-id")) {
|
if (!request.headers().contains("amz-sdk-invocation-id")) {
|
||||||
GlobalTracer.get()
|
GlobalTracer.get()
|
||||||
.inject(
|
.inject(
|
||||||
span.context(), Format.Builtin.HTTP_HEADERS, new NettyResponseInjectAdapter(request));
|
span.context(),
|
||||||
|
Format.Builtin.HTTP_HEADERS,
|
||||||
|
new NettyResponseInjectAdapter(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.channel().attr(AttributeKeys.CLIENT_ATTRIBUTE_KEY).set(span);
|
ctx.channel().attr(AttributeKeys.CLIENT_ATTRIBUTE_KEY).set(span);
|
||||||
|
@ -55,9 +59,10 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
|
||||||
span.finish();
|
span.finish();
|
||||||
throw throwable;
|
throw throwable;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (null != scope) {
|
if (null != parentScope) {
|
||||||
scope.close();
|
parentScope.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,12 +29,9 @@ 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));
|
||||||
|
|
||||||
final Scope scope =
|
final Span span =
|
||||||
GlobalTracer.get()
|
GlobalTracer.get().buildSpan("netty.request").asChildOf(extractedContext).start();
|
||||||
.buildSpan("netty.request")
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
.asChildOf(extractedContext)
|
|
||||||
.startActive(false);
|
|
||||||
final Span span = scope.span();
|
|
||||||
DECORATE.afterStart(span);
|
DECORATE.afterStart(span);
|
||||||
DECORATE.onRequest(span, request);
|
DECORATE.onRequest(span, request);
|
||||||
DECORATE.onPeerConnection(span, remoteAddress);
|
DECORATE.onPeerConnection(span, remoteAddress);
|
||||||
|
@ -52,8 +49,7 @@ public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapte
|
||||||
DECORATE.beforeFinish(span);
|
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 {
|
}
|
||||||
scope.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class TracingCallFactory implements Call.Factory {
|
||||||
final Span span = GlobalTracer.get().buildSpan("okhttp.http").start();
|
final Span span = GlobalTracer.get().buildSpan("okhttp.http").start();
|
||||||
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.afterStart(scope);
|
DECORATE.afterStart(scope);
|
||||||
DECORATE.onRequest(scope.span(), request);
|
DECORATE.onRequest(span, request);
|
||||||
|
|
||||||
/** In case of exception network interceptor is not called */
|
/** In case of exception network interceptor is not called */
|
||||||
final OkHttpClient.Builder okBuilder = okHttpClient.newBuilder();
|
final OkHttpClient.Builder okBuilder = okHttpClient.newBuilder();
|
||||||
|
|
|
@ -189,10 +189,11 @@ public class RabbitChannelInstrumentation extends Instrumenter.Default {
|
||||||
public static class ChannelGetAdvice {
|
public static class ChannelGetAdvice {
|
||||||
@Advice.OnMethodEnter
|
@Advice.OnMethodEnter
|
||||||
public static long takeTimestamp(
|
public static long takeTimestamp(
|
||||||
@Advice.Local("placeholderScope") Scope scope, @Advice.Local("callDepth") int callDepth) {
|
@Advice.Local("placeholderScope") Scope placeholderScope,
|
||||||
|
@Advice.Local("callDepth") int callDepth) {
|
||||||
callDepth = CallDepthThreadLocalMap.incrementCallDepth(Channel.class);
|
callDepth = CallDepthThreadLocalMap.incrementCallDepth(Channel.class);
|
||||||
// Don't want RabbitCommandInstrumentation to mess up our actual parent span.
|
// Don't want RabbitCommandInstrumentation to mess up our actual parent span.
|
||||||
scope = GlobalTracer.get().scopeManager().activate(NoopSpan.INSTANCE, true);
|
placeholderScope = GlobalTracer.get().scopeManager().activate(NoopSpan.INSTANCE, false);
|
||||||
return System.currentTimeMillis();
|
return System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,13 +202,13 @@ public class RabbitChannelInstrumentation extends Instrumenter.Default {
|
||||||
@Advice.This final Channel channel,
|
@Advice.This final Channel channel,
|
||||||
@Advice.Argument(0) final String queue,
|
@Advice.Argument(0) final String queue,
|
||||||
@Advice.Enter final long startTime,
|
@Advice.Enter final long startTime,
|
||||||
@Advice.Local("placeholderScope") final Scope scope,
|
@Advice.Local("placeholderScope") final Scope placeholderScope,
|
||||||
@Advice.Local("callDepth") final int callDepth,
|
@Advice.Local("callDepth") final int callDepth,
|
||||||
@Advice.Return final GetResponse response,
|
@Advice.Return final GetResponse response,
|
||||||
@Advice.Thrown final Throwable throwable) {
|
@Advice.Thrown final Throwable throwable) {
|
||||||
|
|
||||||
if (scope.span() instanceof NoopSpan) {
|
if (placeholderScope.span() instanceof NoopSpan) {
|
||||||
scope.close();
|
placeholderScope.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (callDepth > 0) {
|
if (callDepth > 0) {
|
||||||
|
@ -236,6 +237,8 @@ public class RabbitChannelInstrumentation extends Instrumenter.Default {
|
||||||
|
|
||||||
final Integer length = response == null ? null : response.getBody().length;
|
final Integer length = response == null ? null : response.getBody().length;
|
||||||
|
|
||||||
|
// TODO: it would be better if we could actually have span wrapped into the scope started in
|
||||||
|
// OnMethodEnter
|
||||||
final Span span =
|
final Span span =
|
||||||
GlobalTracer.get()
|
GlobalTracer.get()
|
||||||
.buildSpan("amqp.command")
|
.buildSpan("amqp.command")
|
||||||
|
@ -244,15 +247,18 @@ public class RabbitChannelInstrumentation extends Instrumenter.Default {
|
||||||
.withTag("message.size", length)
|
.withTag("message.size", length)
|
||||||
.withTag(Tags.PEER_PORT.getKey(), connection.getPort())
|
.withTag(Tags.PEER_PORT.getKey(), connection.getPort())
|
||||||
.start();
|
.start();
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
CONSUMER_DECORATE.afterStart(span);
|
CONSUMER_DECORATE.afterStart(span);
|
||||||
CONSUMER_DECORATE.onGet(span, queue);
|
CONSUMER_DECORATE.onGet(span, queue);
|
||||||
CONSUMER_DECORATE.onPeerConnection(span, connection.getAddress());
|
CONSUMER_DECORATE.onPeerConnection(span, connection.getAddress());
|
||||||
CONSUMER_DECORATE.onError(span, throwable);
|
CONSUMER_DECORATE.onError(span, throwable);
|
||||||
CONSUMER_DECORATE.beforeFinish(span);
|
CONSUMER_DECORATE.beforeFinish(span);
|
||||||
|
} finally {
|
||||||
span.finish();
|
span.finish();
|
||||||
CallDepthThreadLocalMap.reset(Channel.class);
|
CallDepthThreadLocalMap.reset(Channel.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class ChannelConsumeAdvice {
|
public static class ChannelConsumeAdvice {
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package datadog.trace.instrumentation.spymemcached;
|
||||||
|
|
||||||
import static datadog.trace.instrumentation.spymemcached.MemcacheClientDecorator.DECORATE;
|
import static datadog.trace.instrumentation.spymemcached.MemcacheClientDecorator.DECORATE;
|
||||||
|
|
||||||
|
import io.opentracing.Scope;
|
||||||
import io.opentracing.Span;
|
import io.opentracing.Span;
|
||||||
import io.opentracing.util.GlobalTracer;
|
import io.opentracing.util.GlobalTracer;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
|
@ -29,19 +30,23 @@ public abstract class CompletionListener<T> {
|
||||||
public CompletionListener(final MemcachedConnection connection, final String methodName) {
|
public CompletionListener(final MemcachedConnection connection, final String methodName) {
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
span = GlobalTracer.get().buildSpan(OPERATION_NAME).start();
|
span = GlobalTracer.get().buildSpan(OPERATION_NAME).start();
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.afterStart(span);
|
DECORATE.afterStart(span);
|
||||||
DECORATE.onConnection(span, connection);
|
DECORATE.onConnection(span, connection);
|
||||||
DECORATE.onOperation(span, methodName);
|
DECORATE.onOperation(span, methodName);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void closeAsyncSpan(final T future) {
|
protected void closeAsyncSpan(final T future) {
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
try {
|
try {
|
||||||
processResult(span, future);
|
processResult(span, future);
|
||||||
} catch (final CancellationException e) {
|
} catch (final CancellationException e) {
|
||||||
span.setTag(DB_COMMAND_CANCELLED, true);
|
span.setTag(DB_COMMAND_CANCELLED, true);
|
||||||
} catch (final ExecutionException e) {
|
} catch (final ExecutionException e) {
|
||||||
if (e.getCause() instanceof CancellationException) {
|
if (e.getCause() instanceof CancellationException) {
|
||||||
// Looks like underlying OperationFuture wraps CancellationException into ExecutionException
|
// Looks like underlying OperationFuture wraps CancellationException into
|
||||||
|
// ExecutionException
|
||||||
span.setTag(DB_COMMAND_CANCELLED, true);
|
span.setTag(DB_COMMAND_CANCELLED, true);
|
||||||
} else {
|
} else {
|
||||||
DECORATE.onError(span, e.getCause());
|
DECORATE.onError(span, e.getCause());
|
||||||
|
@ -58,12 +63,15 @@ public abstract class CompletionListener<T> {
|
||||||
span.finish();
|
span.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void closeSyncSpan(final Throwable thrown) {
|
protected void closeSyncSpan(final Throwable thrown) {
|
||||||
|
try (final Scope scope = GlobalTracer.get().scopeManager().activate(span, false)) {
|
||||||
DECORATE.onError(span, thrown);
|
DECORATE.onError(span, thrown);
|
||||||
DECORATE.beforeFinish(span);
|
DECORATE.beforeFinish(span);
|
||||||
span.finish();
|
span.finish();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract void processResult(Span span, T future)
|
protected abstract void processResult(Span span, T future)
|
||||||
throws ExecutionException, InterruptedException;
|
throws ExecutionException, InterruptedException;
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class MongoAsyncClientInstrumentationTest {
|
||||||
public void asyncClientHasListener() {
|
public void asyncClientHasListener() {
|
||||||
Assert.assertEquals(1, client.getSettings().getCommandListeners().size());
|
Assert.assertEquals(1, client.getSettings().getCommandListeners().size());
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
"DDTracingCommandListener",
|
"TracingCommandListener",
|
||||||
client.getSettings().getCommandListeners().get(0).getClass().getSimpleName());
|
client.getSettings().getCommandListeners().get(0).getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ public class MongoClientInstrumentationTest {
|
||||||
public void syncClientHasListener() {
|
public void syncClientHasListener() {
|
||||||
Assert.assertEquals(1, client.getMongoClientOptions().getCommandListeners().size());
|
Assert.assertEquals(1, client.getMongoClientOptions().getCommandListeners().size());
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
"DDTracingCommandListener",
|
"TracingCommandListener",
|
||||||
client.getMongoClientOptions().getCommandListeners().get(0).getClass().getSimpleName());
|
client.getMongoClientOptions().getCommandListeners().get(0).getClass().getSimpleName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue