Propagate full context (#1350)

* Propagate full context

* spotless
This commit is contained in:
Trask Stalnaker 2020-10-09 02:58:42 -07:00 committed by GitHub
parent 020d445dd3
commit 9605789726
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 216 additions and 221 deletions

View File

@ -5,11 +5,11 @@
package io.opentelemetry.instrumentation.auto.apachehttpasyncclient;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.instrumentation.api.tracer.HttpClientTracer.DEFAULT_SPAN_NAME;
import static io.opentelemetry.instrumentation.auto.apachehttpasyncclient.ApacheHttpAsyncClientTracer.TRACER;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
@ -17,6 +17,7 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
import com.google.auto.service.AutoService;
import io.grpc.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import io.opentelemetry.trace.Span;
@ -87,12 +88,12 @@ public class ApacheHttpAsyncClientInstrumentation extends Instrumenter.Default {
@Advice.Argument(2) HttpContext context,
@Advice.Argument(value = 3, readOnly = false) FutureCallback<?> futureCallback) {
Span parentSpan = TRACER.getCurrentSpan();
Context parentContext = Context.current();
Span clientSpan = TRACER.startSpan(DEFAULT_SPAN_NAME, Kind.CLIENT);
requestProducer = new DelegatingRequestProducer(clientSpan, requestProducer);
futureCallback =
new TraceContinuedFutureCallback(parentSpan, clientSpan, context, futureCallback);
new TraceContinuedFutureCallback(parentContext, clientSpan, context, futureCallback);
return clientSpan;
}
@ -165,14 +166,14 @@ public class ApacheHttpAsyncClientInstrumentation extends Instrumenter.Default {
}
public static class TraceContinuedFutureCallback<T> implements FutureCallback<T> {
private final Span parentSpan;
private final Context parentContext;
private final Span clientSpan;
private final HttpContext context;
private final FutureCallback<T> delegate;
public TraceContinuedFutureCallback(
Span parentSpan, Span clientSpan, HttpContext context, FutureCallback<T> delegate) {
this.parentSpan = parentSpan;
Context parentContext, Span clientSpan, HttpContext context, FutureCallback<T> delegate) {
this.parentContext = parentContext;
this.clientSpan = clientSpan;
this.context = context;
// Note: this can be null in real life, so we have to handle this carefully
@ -183,10 +184,10 @@ public class ApacheHttpAsyncClientInstrumentation extends Instrumenter.Default {
public void completed(T result) {
TRACER.end(clientSpan, getResponse(context));
if (parentSpan == null) {
if (parentContext == null) {
completeDelegate(result);
} else {
try (Scope scope = currentContextWith(parentSpan)) {
try (Scope scope = withScopedContext(parentContext)) {
completeDelegate(result);
}
}
@ -197,10 +198,10 @@ public class ApacheHttpAsyncClientInstrumentation extends Instrumenter.Default {
// end span before calling delegate
TRACER.endExceptionally(clientSpan, getResponse(context), ex);
if (parentSpan == null) {
if (parentContext == null) {
failDelegate(ex);
} else {
try (Scope scope = currentContextWith(parentSpan)) {
try (Scope scope = withScopedContext(parentContext)) {
failDelegate(ex);
}
}
@ -211,10 +212,10 @@ public class ApacheHttpAsyncClientInstrumentation extends Instrumenter.Default {
// end span before calling delegate
TRACER.end(clientSpan, getResponse(context));
if (parentSpan == null) {
if (parentContext == null) {
cancelDelegate();
} else {
try (Scope scope = currentContextWith(parentSpan)) {
try (Scope scope = withScopedContext(parentContext)) {
cancelDelegate();
}
}

View File

@ -5,11 +5,10 @@
package io.opentelemetry.instrumentation.auto.awssdk.v2_2;
import io.grpc.Context;
import io.opentelemetry.context.ContextUtils;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.decorator.ClientDecorator;
import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdk;
import io.opentelemetry.trace.Span;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.Optional;
@ -100,12 +99,11 @@ public class TracingExecutionInterceptor implements ExecutionInterceptor {
public void beforeTransmission(
BeforeTransmission context, ExecutionAttributes executionAttributes) {
delegate.beforeTransmission(context, executionAttributes);
Span span = AwsSdk.getSpanFromAttributes(executionAttributes);
if (span != null) {
Context parentContext = AwsSdk.getContextFromAttributes(executionAttributes);
if (parentContext != null) {
// This scope will be closed by AwsHttpClientInstrumentation since ExecutionInterceptor API
// doesn't provide a way to run code in the same thread after transmission has been scheduled.
ScopeHolder.CURRENT.set(
ContextUtils.withScopedContext(ClientDecorator.currentContextWith(span)));
ScopeHolder.CURRENT.set(ContextUtils.withScopedContext(parentContext));
}
}

View File

@ -5,9 +5,12 @@
package io.opentelemetry.instrumentation.awssdk.v2_2;
import static io.opentelemetry.instrumentation.awssdk.v2_2.TracingExecutionInterceptor.SPAN_ATTRIBUTE;
import static io.opentelemetry.instrumentation.awssdk.v2_2.TracingExecutionInterceptor.CONTEXT_ATTRIBUTE;
import static io.opentelemetry.trace.TracingContextUtils.getSpan;
import io.grpc.Context;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.trace.DefaultSpan;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Span.Kind;
import io.opentelemetry.trace.Tracer;
@ -62,6 +65,15 @@ public class AwsSdk {
* no span set.
*/
public static Span getSpanFromAttributes(ExecutionAttributes attributes) {
return attributes.getAttribute(SPAN_ATTRIBUTE);
Context context = getContextFromAttributes(attributes);
return context == null ? DefaultSpan.getInvalid() : getSpan(context);
}
/**
* Returns the {@link Span} stored in the {@link ExecutionAttributes}, or {@code null} if there is
* no span set.
*/
public static Context getContextFromAttributes(ExecutionAttributes attributes) {
return attributes.getAttribute(CONTEXT_ATTRIBUTE);
}
}

View File

@ -8,6 +8,7 @@ package io.opentelemetry.instrumentation.awssdk.v2_2;
import static io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdk.getSpanFromAttributes;
import static io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkHttpClientTracer.TRACER;
import static io.opentelemetry.instrumentation.awssdk.v2_2.RequestType.ofSdkRequest;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Span.Kind;
@ -27,8 +28,8 @@ import software.amazon.awssdk.core.interceptor.SdkExecutionAttribute;
/** AWS request execution interceptor */
final class TracingExecutionInterceptor implements ExecutionInterceptor {
static final ExecutionAttribute<Span> SPAN_ATTRIBUTE =
new ExecutionAttribute<>("io.opentelemetry.auto.Span");
static final ExecutionAttribute<io.grpc.Context> CONTEXT_ATTRIBUTE =
new ExecutionAttribute<>("io.opentelemetry.auto.Context");
static final ExecutionAttribute<RequestType> REQUEST_TYPE_ATTRIBUTE =
new ExecutionAttribute<>("io.opentelemetry.auto.aws.RequestType");
@ -74,7 +75,7 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
public void beforeExecution(
Context.BeforeExecution context, ExecutionAttributes executionAttributes) {
Span span = TRACER.getOrCreateSpan(spanName(executionAttributes), AwsSdk.tracer(), kind);
executionAttributes.putAttribute(SPAN_ATTRIBUTE, span);
executionAttributes.putAttribute(CONTEXT_ATTRIBUTE, withSpan(span, io.grpc.Context.current()));
RequestType type = ofSdkRequest(context.request());
if (type != null) {
executionAttributes.putAttribute(REQUEST_TYPE_ATTRIBUTE, type);
@ -85,7 +86,7 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
public void afterMarshalling(
Context.AfterMarshalling context, ExecutionAttributes executionAttributes) {
Span span = getSpanFromAttributes(executionAttributes);
if (span != null) {
if (span.getContext().isValid()) {
TRACER.onRequest(span, context.httpRequest());
SdkRequestDecorator decorator = decorator(executionAttributes);
if (decorator != null) {
@ -122,7 +123,7 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
public void afterExecution(
Context.AfterExecution context, ExecutionAttributes executionAttributes) {
Span span = getSpanFromAttributes(executionAttributes);
if (span != null) {
if (span.getContext().isValid()) {
clearAttributes(executionAttributes);
TRACER.afterExecution(span, context.httpRequest());
onSdkResponse(span, context.response());
@ -140,14 +141,14 @@ final class TracingExecutionInterceptor implements ExecutionInterceptor {
public void onExecutionFailure(
Context.FailedExecution context, ExecutionAttributes executionAttributes) {
Span span = getSpanFromAttributes(executionAttributes);
if (span != null) {
if (span.getContext().isValid()) {
clearAttributes(executionAttributes);
TRACER.endExceptionally(span, context.exception());
}
}
private void clearAttributes(ExecutionAttributes executionAttributes) {
executionAttributes.putAttribute(SPAN_ATTRIBUTE, null);
executionAttributes.putAttribute(CONTEXT_ATTRIBUTE, null);
executionAttributes.putAttribute(REQUEST_TYPE_ATTRIBUTE, null);
}

View File

@ -5,13 +5,13 @@
package io.opentelemetry.instrumentation.auto.jms;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.instrumentation.auto.jms.JMSDecorator.DECORATE;
import static io.opentelemetry.instrumentation.auto.jms.JMSDecorator.TRACER;
import static io.opentelemetry.instrumentation.auto.jms.MessageInjectAdapter.SETTER;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.trace.Span.Kind.PRODUCER;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static io.opentelemetry.trace.TracingContextUtils.withSpan;
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
import static net.bytebuddy.matcher.ElementMatchers.named;
@ -101,7 +101,7 @@ public final class JMSMessageProducerInstrumentation extends Instrumenter.Defaul
Context context = withSpan(span, Context.current());
OpenTelemetry.getPropagators().getTextMapPropagator().inject(context, message, SETTER);
return new SpanWithScope(span, currentContextWith(span));
return new SpanWithScope(span, withScopedContext(context));
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
@ -139,7 +139,7 @@ public final class JMSMessageProducerInstrumentation extends Instrumenter.Defaul
Context context = withSpan(span, Context.current());
OpenTelemetry.getPropagators().getTextMapPropagator().inject(context, message, SETTER);
return new SpanWithScope(span, currentContextWith(span));
return new SpanWithScope(span, withScopedContext(context));
}
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)

View File

@ -5,15 +5,16 @@
package io.opentelemetry.instrumentation.auto.netty.v3_8;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.grpc.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.auto.api.ContextStore;
import io.opentelemetry.instrumentation.auto.api.InstrumentationContext;
@ -94,15 +95,16 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
ContextStore<Channel, ChannelTraceContext> contextStore =
InstrumentationContext.get(Channel.class, ChannelTraceContext.class);
Span continuation =
Context parentContext =
contextStore
.putIfAbsent(future.getChannel(), ChannelTraceContext.Factory.INSTANCE)
.getConnectionContinuation();
contextStore.get(future.getChannel()).setConnectionContinuation(null);
if (continuation == null) {
.getConnectionContext();
contextStore.get(future.getChannel()).setConnectionContext(null);
if (parentContext == null) {
return null;
}
Scope parentScope = currentContextWith(continuation);
// TODO pass Context into Tracer.startSpan() and then don't need this scoping
Scope parentScope = withScopedContext(parentContext);
Span errorSpan = NettyHttpClientTracer.TRACER.startSpan("CONNECT", Kind.CLIENT);
NettyHttpClientTracer.TRACER.endExceptionally(errorSpan, cause);
return parentScope;

View File

@ -20,26 +20,17 @@ public class ChannelTraceContext {
}
}
private Span connectionContinuation;
private Span serverSpan;
private Context connectionContext;
private Span clientSpan;
private Span clientParentSpan;
private Context clientParentContext;
private Context context;
public Span getConnectionContinuation() {
return connectionContinuation;
public Context getConnectionContext() {
return connectionContext;
}
public void setConnectionContinuation(Span connectionContinuation) {
this.connectionContinuation = connectionContinuation;
}
public Span getServerSpan() {
return serverSpan;
}
public void setServerSpan(Span serverSpan) {
this.serverSpan = serverSpan;
public void setConnectionContext(Context connectionContinuation) {
this.connectionContext = connectionContinuation;
}
public Span getClientSpan() {
@ -50,12 +41,12 @@ public class ChannelTraceContext {
this.clientSpan = clientSpan;
}
public Span getClientParentSpan() {
return clientParentSpan;
public Context getClientParentContext() {
return clientParentContext;
}
public void setClientParentSpan(Span clientParentSpan) {
this.clientParentSpan = clientParentSpan;
public void setClientParentContext(Context clientParentContext) {
this.clientParentContext = clientParentContext;
}
public Context getContext() {
@ -75,15 +66,14 @@ public class ChannelTraceContext {
return false;
}
ChannelTraceContext that = (ChannelTraceContext) o;
return Objects.equals(connectionContinuation, that.connectionContinuation)
&& Objects.equals(serverSpan, that.serverSpan)
return Objects.equals(connectionContext, that.connectionContext)
&& Objects.equals(clientSpan, that.clientSpan)
&& Objects.equals(clientParentSpan, that.clientParentSpan)
&& Objects.equals(clientParentContext, that.clientParentContext)
&& Objects.equals(context, that.context);
}
@Override
public int hashCode() {
return Objects.hash(connectionContinuation, serverSpan, clientSpan, clientParentSpan, context);
return Objects.hash(connectionContext, clientSpan, clientParentContext, context);
}
}

View File

@ -7,14 +7,15 @@ package io.opentelemetry.instrumentation.auto.netty.v3_8;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.trace.TracingContextUtils.getSpan;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.returns;
import com.google.auto.service.AutoService;
import io.grpc.Context;
import io.opentelemetry.instrumentation.auto.api.ContextStore;
import io.opentelemetry.instrumentation.auto.api.InstrumentationContext;
import io.opentelemetry.instrumentation.auto.netty.v3_8.server.NettyHttpServerTracer;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import io.opentelemetry.trace.Span;
import java.util.Collections;
@ -76,16 +77,17 @@ public class NettyChannelInstrumentation extends Instrumenter.Default {
public static class ChannelConnectAdvice extends AbstractNettyAdvice {
@Advice.OnMethodEnter
public static void addConnectContinuation(@Advice.This Channel channel) {
Span span = NettyHttpServerTracer.TRACER.getCurrentSpan();
Context context = Context.current();
Span span = getSpan(context);
if (span.getContext().isValid()) {
ContextStore<Channel, ChannelTraceContext> contextStore =
InstrumentationContext.get(Channel.class, ChannelTraceContext.class);
if (contextStore
.putIfAbsent(channel, ChannelTraceContext.Factory.INSTANCE)
.getConnectionContinuation()
.getConnectionContext()
== null) {
contextStore.get(channel).setConnectionContinuation(span);
contextStore.get(channel).setConnectionContext(context);
}
}
}

View File

@ -5,9 +5,10 @@
package io.opentelemetry.instrumentation.auto.netty.v3_8.client;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.instrumentation.auto.netty.v3_8.client.NettyHttpClientTracer.TRACER;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import io.grpc.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.tracer.utils.NetPeerUtils;
import io.opentelemetry.instrumentation.auto.api.ContextStore;
@ -38,13 +39,14 @@ public class HttpClientRequestTracingHandler extends SimpleChannelDownstreamHand
ChannelTraceContext channelTraceContext =
contextStore.putIfAbsent(ctx.getChannel(), ChannelTraceContext.Factory.INSTANCE);
// TODO pass Context into Tracer.startSpan() and then don't need this scoping
Scope parentScope = null;
Span continuation = channelTraceContext.getConnectionContinuation();
if (continuation != null) {
parentScope = currentContextWith(continuation);
channelTraceContext.setConnectionContinuation(null);
Context parentContext = channelTraceContext.getConnectionContext();
if (parentContext != null) {
parentScope = withScopedContext(parentContext);
channelTraceContext.setConnectionContext(null);
}
channelTraceContext.setClientParentSpan(TRACER.getCurrentSpan());
channelTraceContext.setClientParentContext(Context.current());
HttpRequest request = (HttpRequest) msg.getMessage();

View File

@ -5,14 +5,14 @@
package io.opentelemetry.instrumentation.auto.netty.v3_8.client;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.instrumentation.auto.netty.v3_8.client.NettyHttpClientTracer.TRACER;
import io.grpc.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.auto.api.ContextStore;
import io.opentelemetry.instrumentation.auto.netty.v3_8.ChannelTraceContext;
import io.opentelemetry.trace.DefaultSpan;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.TracingContextUtils;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.MessageEvent;
@ -32,11 +32,7 @@ public class HttpClientResponseTracingHandler extends SimpleChannelUpstreamHandl
ChannelTraceContext channelTraceContext =
contextStore.putIfAbsent(ctx.getChannel(), ChannelTraceContext.Factory.INSTANCE);
Span parent = channelTraceContext.getClientParentSpan();
if (parent == null) {
parent = DefaultSpan.getInvalid();
channelTraceContext.setClientParentSpan(DefaultSpan.getInvalid());
}
Context parentContext = channelTraceContext.getClientParentContext();
Span span = channelTraceContext.getClientSpan();
boolean finishSpan = msg.getMessage() instanceof HttpResponse;
@ -46,7 +42,11 @@ public class HttpClientResponseTracingHandler extends SimpleChannelUpstreamHandl
}
// We want the callback in the scope of the parent, not the client span
try (Scope scope = TracingContextUtils.currentContextWith(parent)) {
if (parentContext != null) {
try (Scope ignored = withScopedContext(parentContext)) {
ctx.sendUpstream(msg);
}
} else {
ctx.sendUpstream(msg);
}
}

View File

@ -33,11 +33,11 @@ public class HttpServerRequestTracingHandler extends SimpleChannelUpstreamHandle
contextStore.putIfAbsent(ctx.getChannel(), ChannelTraceContext.Factory.INSTANCE);
if (!(msg.getMessage() instanceof HttpRequest)) {
Context serverSpanContext = TRACER.getServerContext(channelTraceContext);
if (serverSpanContext == null) {
Context serverContext = TRACER.getServerContext(channelTraceContext);
if (serverContext == null) {
ctx.sendUpstream(msg);
} else {
try (Scope ignored = ContextUtils.withScopedContext(serverSpanContext)) {
try (Scope ignored = ContextUtils.withScopedContext(serverContext)) {
ctx.sendUpstream(msg);
}
}

View File

@ -26,8 +26,8 @@ public class AttributeKeys {
}
};
public static final AttributeKey<Span> PARENT_CONNECT_SPAN_ATTRIBUTE_KEY =
attributeKey("io.opentelemetry.instrumentation.auto.netty.v4_0.parent.connect.span");
public static final AttributeKey<Context> PARENT_CONNECT_CONTEXT_ATTRIBUTE_KEY =
attributeKey("io.opentelemetry.instrumentation.auto.netty.v4_0.parent.connect.context");
public static final AttributeKey<Context> SERVER_ATTRIBUTE_KEY =
attributeKey(HttpServerTracingHandler.class.getName() + ".context");
@ -35,7 +35,7 @@ public class AttributeKeys {
public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY =
attributeKey(HttpClientTracingHandler.class.getName() + ".span");
public static final AttributeKey<Span> CLIENT_PARENT_ATTRIBUTE_KEY =
public static final AttributeKey<Context> CLIENT_PARENT_ATTRIBUTE_KEY =
attributeKey(HttpClientTracingHandler.class.getName() + ".parent");
/**

View File

@ -5,15 +5,16 @@
package io.opentelemetry.instrumentation.auto.netty.v4_0;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.javaagent.tooling.ClassLoaderMatcher.hasClassesNamed;
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.implementsInterface;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static java.util.Collections.singletonMap;
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.grpc.Context;
import io.netty.channel.ChannelFuture;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.auto.netty.v4_0.client.NettyHttpClientTracer;
@ -87,12 +88,12 @@ public class ChannelFutureListenerInstrumentation extends Instrumenter.Default {
if (cause == null) {
return null;
}
Span parentSpan =
future.channel().attr(AttributeKeys.PARENT_CONNECT_SPAN_ATTRIBUTE_KEY).getAndRemove();
if (parentSpan == null) {
Context parentContext =
future.channel().attr(AttributeKeys.PARENT_CONNECT_CONTEXT_ATTRIBUTE_KEY).getAndRemove();
if (parentContext == null) {
return null;
}
Scope parentScope = currentContextWith(parentSpan);
Scope parentScope = withScopedContext(parentContext);
Span span = NettyHttpClientTracer.TRACER.startSpan("CONNECT", Kind.CLIENT);
NettyHttpClientTracer.TRACER.endExceptionally(span, cause);
return parentScope;

View File

@ -14,6 +14,7 @@ import static net.bytebuddy.matcher.ElementMatchers.returns;
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
import com.google.auto.service.AutoService;
import io.grpc.Context;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.HttpClientCodec;
@ -30,9 +31,7 @@ import io.opentelemetry.instrumentation.auto.netty.v4_0.client.HttpClientTracing
import io.opentelemetry.instrumentation.auto.netty.v4_0.server.HttpServerRequestTracingHandler;
import io.opentelemetry.instrumentation.auto.netty.v4_0.server.HttpServerResponseTracingHandler;
import io.opentelemetry.instrumentation.auto.netty.v4_0.server.HttpServerTracingHandler;
import io.opentelemetry.instrumentation.auto.netty.v4_0.server.NettyHttpServerTracer;
import io.opentelemetry.javaagent.tooling.Instrumenter;
import io.opentelemetry.trace.Span;
import java.util.HashMap;
import java.util.Map;
import net.bytebuddy.asm.Advice;
@ -152,12 +151,10 @@ public class NettyChannelPipelineInstrumentation extends Instrumenter.Default {
public static class ChannelPipelineConnectAdvice {
@Advice.OnMethodEnter
public static void addParentSpan(@Advice.This ChannelPipeline pipeline) {
Span span = NettyHttpServerTracer.TRACER.getCurrentSpan();
if (span.getContext().isValid()) {
Attribute<Span> attribute =
pipeline.channel().attr(AttributeKeys.PARENT_CONNECT_SPAN_ATTRIBUTE_KEY);
attribute.compareAndSet(null, span);
}
Context context = Context.current();
Attribute<Context> attribute =
pipeline.channel().attr(AttributeKeys.PARENT_CONNECT_CONTEXT_ATTRIBUTE_KEY);
attribute.compareAndSet(null, context);
}
}
}

View File

@ -5,9 +5,10 @@
package io.opentelemetry.instrumentation.auto.netty.v4_0.client;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.instrumentation.auto.netty.v4_0.client.NettyHttpClientTracer.TRACER;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import io.grpc.Context;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOutboundHandlerAdapter;
import io.netty.channel.ChannelPromise;
@ -27,21 +28,17 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
return;
}
// TODO pass Context into Tracer.startSpan() and then don't need this scoping
Scope parentScope = null;
Span parentSpan =
ctx.channel().attr(AttributeKeys.PARENT_CONNECT_SPAN_ATTRIBUTE_KEY).getAndRemove();
if (parentSpan != null) {
parentScope = currentContextWith(parentSpan);
Context parentContext =
ctx.channel().attr(AttributeKeys.PARENT_CONNECT_CONTEXT_ATTRIBUTE_KEY).getAndRemove();
if (parentContext != null) {
parentScope = withScopedContext(parentContext);
}
HttpRequest request = (HttpRequest) msg;
Span currentSpan = TRACER.getCurrentSpan();
if (currentSpan.getContext().isValid()) {
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY).set(currentSpan);
} else {
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY).set(null);
}
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY).set(Context.current());
Span span = TRACER.startSpan(request);
NetPeerUtils.setNetPeer(span, (InetSocketAddress) ctx.channel().remoteAddress());

View File

@ -5,25 +5,25 @@
package io.opentelemetry.instrumentation.auto.netty.v4_0.client;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.instrumentation.auto.netty.v4_0.client.NettyHttpClientTracer.TRACER;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import io.grpc.Context;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.util.Attribute;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.auto.netty.v4_0.AttributeKeys;
import io.opentelemetry.trace.DefaultSpan;
import io.opentelemetry.trace.Span;
public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
Attribute<Span> parentAttr = ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY);
parentAttr.setIfAbsent(DefaultSpan.getInvalid());
Span parent = parentAttr.get();
Attribute<Context> parentAttr = ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY);
Context parentContext = parentAttr.get();
Span span = ctx.channel().attr(AttributeKeys.CLIENT_ATTRIBUTE_KEY).get();
boolean finishSpan = msg instanceof HttpResponse;
@ -35,7 +35,11 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt
}
// We want the callback in the scope of the parent, not the client span
try (Scope scope = currentContextWith(parent)) {
if (parentContext != null) {
try (Scope ignored = withScopedContext(parentContext)) {
ctx.fireChannelRead(msg);
}
} else {
ctx.fireChannelRead(msg);
}
}

View File

@ -5,9 +5,10 @@
package io.opentelemetry.instrumentation.auto.netty.v4_0.server;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.instrumentation.auto.netty.v4_0.server.NettyHttpServerTracer.TRACER;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import io.grpc.Context;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
@ -22,11 +23,11 @@ public class HttpServerRequestTracingHandler extends ChannelInboundHandlerAdapte
Channel channel = ctx.channel();
if (!(msg instanceof HttpRequest)) {
Span serverSpan = TRACER.getServerSpan(channel);
if (serverSpan == null) {
Context serverContext = TRACER.getServerContext(channel);
if (serverContext == null) {
ctx.fireChannelRead(msg);
} else {
try (Scope ignored = currentContextWith(serverSpan)) {
try (Scope ignored = withScopedContext(serverContext)) {
ctx.fireChannelRead(msg);
}
}

View File

@ -41,7 +41,7 @@ public class AttributeKeys {
public static final AttributeKey<Span> CLIENT_ATTRIBUTE_KEY =
attributeKey(HttpClientTracingHandler.class.getName() + ".span");
public static final AttributeKey<Span> CLIENT_PARENT_ATTRIBUTE_KEY =
public static final AttributeKey<Context> CLIENT_PARENT_ATTRIBUTE_KEY =
attributeKey(HttpClientTracingHandler.class.getName() + ".parent");
/**

View File

@ -28,22 +28,17 @@ public class HttpClientRequestTracingHandler extends ChannelOutboundHandlerAdapt
return;
}
// TODO pass Context into Tracer.startSpan() and then don't need this scoping
Scope parentScope = null;
Context parentContext =
ctx.channel().attr(AttributeKeys.PARENT_CONNECT_CONTEXT_ATTRIBUTE_KEY).getAndRemove();
if (parentContext != null) {
// TODO (trask) if null then do with ROOT scope?
parentScope = withScopedContext(parentContext);
}
HttpRequest request = (HttpRequest) msg;
Span currentSpan = TRACER.getCurrentSpan();
if (currentSpan.getContext().isValid()) {
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY).set(currentSpan);
} else {
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY).set(null);
}
ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY).set(Context.current());
Span span = TRACER.startSpan(request);
NetPeerUtils.setNetPeer(span, (InetSocketAddress) ctx.channel().remoteAddress());

View File

@ -5,25 +5,25 @@
package io.opentelemetry.instrumentation.auto.netty.v4_1.client;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.instrumentation.auto.netty.v4_1.client.NettyHttpClientTracer.TRACER;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import io.grpc.Context;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.util.Attribute;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.auto.netty.v4_1.AttributeKeys;
import io.opentelemetry.trace.DefaultSpan;
import io.opentelemetry.trace.Span;
public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
Attribute<Span> parentAttr = ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY);
parentAttr.setIfAbsent(DefaultSpan.getInvalid());
Span parent = parentAttr.get();
Attribute<Context> parentAttr = ctx.channel().attr(AttributeKeys.CLIENT_PARENT_ATTRIBUTE_KEY);
Context parentContext = parentAttr.get();
Span span = ctx.channel().attr(AttributeKeys.CLIENT_ATTRIBUTE_KEY).get();
boolean finishSpan = msg instanceof HttpResponse;
@ -35,7 +35,11 @@ public class HttpClientResponseTracingHandler extends ChannelInboundHandlerAdapt
}
// We want the callback in the scope of the parent, not the client span
try (Scope scope = currentContextWith(parent)) {
if (parentContext != null) {
try (Scope ignored = withScopedContext(parentContext)) {
ctx.fireChannelRead(msg);
}
} else {
ctx.fireChannelRead(msg);
}
}

View File

@ -5,9 +5,10 @@
package io.opentelemetry.instrumentation.auto.playws.v2_0;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.instrumentation.auto.playws.PlayWSClientTracer.TRACER;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import io.grpc.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
import java.net.InetSocketAddress;
@ -23,14 +24,14 @@ import play.shaded.ahc.org.asynchttpclient.netty.request.NettyRequest;
public class AsyncHandlerWrapper implements AsyncHandler {
private final AsyncHandler delegate;
private final Span span;
private final Span parentSpan;
private final Context parentContext;
private final Response.ResponseBuilder builder = new Response.ResponseBuilder();
public AsyncHandlerWrapper(AsyncHandler delegate, Span span) {
this.delegate = delegate;
this.span = span;
parentSpan = TRACER.getCurrentSpan();
parentContext = Context.current();
}
@Override
@ -57,11 +58,7 @@ public class AsyncHandlerWrapper implements AsyncHandler {
Response response = builder.build();
TRACER.end(span, response);
if (parentSpan.getContext().isValid()) {
try (Scope scope = currentContextWith(parentSpan)) {
return delegate.onCompleted();
}
} else {
try (Scope ignored = withScopedContext(parentContext)) {
return delegate.onCompleted();
}
}
@ -70,11 +67,7 @@ public class AsyncHandlerWrapper implements AsyncHandler {
public void onThrowable(Throwable throwable) {
TRACER.endExceptionally(span, throwable);
if (parentSpan.getContext().isValid()) {
try (Scope scope = currentContextWith(parentSpan)) {
delegate.onThrowable(throwable);
}
} else {
try (Scope ignored = withScopedContext(parentContext)) {
delegate.onThrowable(throwable);
}
}

View File

@ -5,9 +5,10 @@
package io.opentelemetry.instrumentation.auto.playws.v2_1;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.instrumentation.auto.playws.PlayWSClientTracer.TRACER;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import io.grpc.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
import java.net.InetSocketAddress;
@ -24,14 +25,14 @@ import play.shaded.ahc.org.asynchttpclient.netty.request.NettyRequest;
public class AsyncHandlerWrapper implements AsyncHandler {
private final AsyncHandler delegate;
private final Span span;
private final Span parentSpan;
private final Context parentContext;
private final Response.ResponseBuilder builder = new Response.ResponseBuilder();
public AsyncHandlerWrapper(AsyncHandler delegate, Span span) {
this.delegate = delegate;
this.span = span;
parentSpan = TRACER.getCurrentSpan();
parentContext = Context.current();
}
@Override
@ -58,11 +59,7 @@ public class AsyncHandlerWrapper implements AsyncHandler {
Response response = builder.build();
TRACER.end(span, response);
if (parentSpan.getContext().isValid()) {
try (Scope scope = currentContextWith(parentSpan)) {
return delegate.onCompleted();
}
} else {
try (Scope ignored = withScopedContext(parentContext)) {
return delegate.onCompleted();
}
}
@ -71,11 +68,7 @@ public class AsyncHandlerWrapper implements AsyncHandler {
public void onThrowable(Throwable throwable) {
TRACER.endExceptionally(span, throwable);
if (parentSpan.getContext().isValid()) {
try (Scope scope = currentContextWith(parentSpan)) {
delegate.onThrowable(throwable);
}
} else {
try (Scope ignored = withScopedContext(parentContext)) {
delegate.onThrowable(throwable);
}
}

View File

@ -5,12 +5,10 @@
package io.opentelemetry.instrumentation.auto.ratpack;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import io.opentelemetry.OpenTelemetry;
import io.grpc.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Tracer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ratpack.func.Action;
@ -19,30 +17,27 @@ public class ActionWrapper<T> implements Action<T> {
private static final Logger log = LoggerFactory.getLogger(ActionWrapper.class);
private static final Tracer TRACER = OpenTelemetry.getTracer("io.opentelemetry.auto.ratpack-1.4");
private final Action<T> delegate;
private final Span span;
private final Context parentContext;
private ActionWrapper(Action<T> delegate, Span span) {
assert span != null;
private ActionWrapper(Action<T> delegate, Context parentContext) {
assert parentContext != null;
this.delegate = delegate;
this.span = span;
this.parentContext = parentContext;
}
@Override
public void execute(T t) throws Exception {
try (Scope scope = currentContextWith(span)) {
try (Scope ignored = withScopedContext(parentContext)) {
delegate.execute(t);
}
}
public static <T> Action<T> wrapIfNeeded(Action<T> delegate) {
Span span = TRACER.getCurrentSpan();
if (delegate instanceof ActionWrapper || !span.getContext().isValid()) {
if (delegate instanceof ActionWrapper) {
return delegate;
}
log.debug("Wrapping action task {}", delegate);
return new ActionWrapper(delegate, span);
return new ActionWrapper(delegate, Context.current());
}
}

View File

@ -5,11 +5,11 @@
package io.opentelemetry.instrumentation.auto.ratpack;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import io.grpc.Context;
import io.opentelemetry.OpenTelemetry;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
import io.opentelemetry.trace.Tracer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -22,27 +22,26 @@ public class BlockWrapper implements Block {
private static final Tracer TRACER = OpenTelemetry.getTracer("io.opentelemetry.auto.ratpack-1.4");
private final Block delegate;
private final Span span;
private final Context parentContext;
private BlockWrapper(Block delegate, Span span) {
assert span != null;
private BlockWrapper(Block delegate, Context parentContext) {
assert parentContext != null;
this.delegate = delegate;
this.span = span;
this.parentContext = parentContext;
}
@Override
public void execute() throws Exception {
try (Scope scope = currentContextWith(span)) {
try (Scope ignored = withScopedContext(parentContext)) {
delegate.execute();
}
}
public static Block wrapIfNeeded(Block delegate) {
Span span = TRACER.getCurrentSpan();
if (delegate instanceof BlockWrapper || !span.getContext().isValid()) {
if (delegate instanceof BlockWrapper) {
return delegate;
}
log.debug("Wrapping block {}", delegate);
return new BlockWrapper(delegate, span);
return new BlockWrapper(delegate, Context.current());
}
}

View File

@ -5,6 +5,9 @@
package io.opentelemetry.instrumentation.auto.rxjava;
import static io.opentelemetry.trace.TracingContextUtils.getSpan;
import io.grpc.Context;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import io.opentelemetry.trace.Span;
import java.util.concurrent.atomic.AtomicReference;
@ -12,23 +15,26 @@ import rx.Subscription;
public class SpanFinishingSubscription implements Subscription {
private final BaseTracer tracer;
private final AtomicReference<Span> spanRef;
private final AtomicReference<Context> contextRef;
public SpanFinishingSubscription(BaseTracer tracer, AtomicReference<Span> spanRef) {
public SpanFinishingSubscription(BaseTracer tracer, AtomicReference<Context> contextRef) {
this.tracer = tracer;
this.spanRef = spanRef;
this.contextRef = contextRef;
}
@Override
public void unsubscribe() {
Span span = spanRef.getAndSet(null);
if (span != null) {
tracer.end(span);
Context context = contextRef.getAndSet(null);
if (context != null) {
Span span = getSpan(context);
if (span.getContext().isValid()) {
tracer.end(span);
}
}
}
@Override
public boolean isUnsubscribed() {
return spanRef.get() == null;
return contextRef.get() == null;
}
}

View File

@ -33,13 +33,12 @@ public class TracedOnSubscribe<T> implements Observable.OnSubscribe<T> {
@Override
public void call(Subscriber<? super T> subscriber) {
// TODO too many contexts here
// Review if we can pass parentContext to startSpan
// TODO pass Context into Tracer.startSpan() and then don't need this outer scoping
try (Scope ignored = ContextUtils.withScopedContext(parentContext)) {
Span span = tracer.startSpan(operationName, spanKind);
decorateSpan(span);
try (Scope ignored1 = tracer.startScope(span)) {
delegate.call(new TracedSubscriber(span, subscriber, tracer));
delegate.call(new TracedSubscriber(Context.current(), subscriber, tracer));
}
}
}

View File

@ -5,8 +5,10 @@
package io.opentelemetry.instrumentation.auto.rxjava;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.trace.TracingContextUtils.getSpan;
import io.grpc.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
import io.opentelemetry.trace.Span;
@ -15,24 +17,23 @@ import rx.Subscriber;
public class TracedSubscriber<T> extends Subscriber<T> {
private final AtomicReference<Span> spanRef;
private final AtomicReference<Context> contextRef;
private final Subscriber<T> delegate;
private final BaseTracer tracer;
// TODO pass the whole context here, not just span
public TracedSubscriber(Span span, Subscriber<T> delegate, BaseTracer tracer) {
spanRef = new AtomicReference<>(span);
public TracedSubscriber(Context context, Subscriber<T> delegate, BaseTracer tracer) {
contextRef = new AtomicReference<>(context);
this.delegate = delegate;
this.tracer = tracer;
SpanFinishingSubscription subscription = new SpanFinishingSubscription(tracer, spanRef);
SpanFinishingSubscription subscription = new SpanFinishingSubscription(tracer, contextRef);
delegate.add(subscription);
}
@Override
public void onStart() {
Span span = spanRef.get();
if (span != null) {
try (Scope ignored = currentContextWith(span)) {
Context context = contextRef.get();
if (context != null) {
try (Scope ignored = withScopedContext(context)) {
delegate.onStart();
}
} else {
@ -42,12 +43,10 @@ public class TracedSubscriber<T> extends Subscriber<T> {
@Override
public void onNext(T value) {
Span span = spanRef.get();
if (span != null) {
try (Scope ignored = currentContextWith(span)) {
Context context = contextRef.get();
if (context != null) {
try (Scope ignored = withScopedContext(context)) {
delegate.onNext(value);
} catch (Throwable e) {
onError(e);
}
} else {
delegate.onNext(value);
@ -56,19 +55,19 @@ public class TracedSubscriber<T> extends Subscriber<T> {
@Override
public void onCompleted() {
Span span = spanRef.getAndSet(null);
if (span != null) {
boolean errored = false;
try (Scope ignored = currentContextWith(span)) {
Context context = contextRef.getAndSet(null);
if (context != null) {
Throwable error = null;
try (Scope ignored = withScopedContext(context)) {
delegate.onCompleted();
} catch (Throwable e) {
// Repopulate the spanRef for onError
spanRef.compareAndSet(null, span);
onError(e);
errored = true;
} catch (Throwable t) {
error = t;
throw t;
} finally {
// finish called by onError, so don't finish again.
if (!errored) {
Span span = getSpan(context);
if (error != null) {
tracer.endExceptionally(span, error);
} else {
tracer.end(span);
}
}
@ -79,10 +78,11 @@ public class TracedSubscriber<T> extends Subscriber<T> {
@Override
public void onError(Throwable e) {
Span span = spanRef.getAndSet(null);
if (span != null) {
tracer.endExceptionally(span, e);
Context context = contextRef.getAndSet(null);
if (context != null) {
tracer.endExceptionally(getSpan(context), e);
}
// TODO (trask) should this be wrapped in parent of context(?)
delegate.onError(e);
}
}

View File

@ -5,8 +5,8 @@
package io.opentelemetry.instrumentation.auto.spring.webflux.server;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.instrumentation.auto.spring.webflux.server.SpringWebfluxHttpServerTracer.TRACER;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import io.grpc.Context;
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
@ -45,7 +45,7 @@ public class HandlerAdapterAdvice {
span.updateName(operationName);
span.setAttribute("handler.type", handlerType);
spanWithScope = new SpanWithScope(span, currentContextWith(span));
spanWithScope = new SpanWithScope(span, withScopedContext(context));
}
if (context != null) {

View File

@ -5,9 +5,10 @@
package io.opentelemetry.instrumentation.auto.spymemcached;
import static io.opentelemetry.context.ContextUtils.withScopedContext;
import static io.opentelemetry.instrumentation.auto.spymemcached.MemcacheClientTracer.TRACER;
import static io.opentelemetry.trace.TracingContextUtils.currentContextWith;
import io.grpc.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.trace.Span;
import java.util.concurrent.CancellationException;
@ -21,14 +22,16 @@ public abstract class CompletionListener<T> {
static final String HIT = "hit";
static final String MISS = "miss";
private final Context context;
private final Span span;
public CompletionListener(MemcachedConnection connection, String methodName) {
context = Context.current();
span = TRACER.startSpan(connection, methodName);
}
protected void closeAsyncSpan(T future) {
try (Scope ignored = currentContextWith(span)) {
try (Scope ignored = withScopedContext(context)) {
try {
processResult(span, future);
} catch (CancellationException e) {