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