diff --git a/instrumentation/dropwizard-views-0.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/dropwizardviews/DropwizardViewsInstrumentationModule.java b/instrumentation/dropwizard-views-0.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/dropwizardviews/DropwizardViewsInstrumentationModule.java index dc1fe69501..24f0adbca0 100644 --- a/instrumentation/dropwizard-views-0.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/dropwizardviews/DropwizardViewsInstrumentationModule.java +++ b/instrumentation/dropwizard-views-0.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/dropwizardviews/DropwizardViewsInstrumentationModule.java @@ -18,8 +18,8 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import com.google.auto.service.AutoService; import io.dropwizard.views.View; import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.List; @@ -65,27 +65,30 @@ public class DropwizardViewsInstrumentationModule extends InstrumentationModule public static class RenderAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope onEnter(@Advice.Argument(0) View view) { - if (!Java8BytecodeBridge.currentSpan().getSpanContext().isValid()) { - return null; + public static void onEnter( + @Advice.Argument(0) View view, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + if (Java8BytecodeBridge.currentSpan().getSpanContext().isValid()) { + span = tracer().startSpan("Render " + view.getTemplateName()); + scope = span.makeCurrent(); } - Span span = tracer().startSpan("Render " + view.getTemplateName()); - return new SpanWithScope(span, span.makeCurrent()); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void stopSpan( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) { - if (spanWithScope == null) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + if (scope == null) { return; } - Span span = spanWithScope.getSpan(); + scope.close(); if (throwable == null) { tracer().end(span); } else { tracer().endExceptionally(span, throwable); } - spanWithScope.closeScope(); } } } diff --git a/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraInstrumentationModule.java b/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraInstrumentationModule.java index 4fe6eecb67..bfd06007a0 100644 --- a/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraInstrumentationModule.java +++ b/instrumentation/finatra-2.9/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finatra/FinatraInstrumentationModule.java @@ -22,8 +22,8 @@ import com.twitter.finatra.http.contexts.RouteInfo; import com.twitter.util.Future; import com.twitter.util.FutureEventListener; import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.tracer.BaseTracer; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.tooling.InstrumentationModule; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.List; @@ -71,60 +71,61 @@ public class FinatraInstrumentationModule extends InstrumentationModule { public static class RouteAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope nameSpan( + public static void nameSpan( @Advice.FieldValue("routeInfo") RouteInfo routeInfo, - @Advice.FieldValue("clazz") Class clazz) { + @Advice.FieldValue("clazz") Class clazz, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { Span serverSpan = BaseTracer.getCurrentServerSpan(); if (serverSpan != null) { serverSpan.updateName(routeInfo.path()); } - Span span = tracer().startSpan(clazz); - - return new SpanWithScope(span, span.makeCurrent()); + span = tracer().startSpan(clazz); + scope = span.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void setupCallback( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable, - @Advice.Return Some> responseOption) { + @Advice.Return Some> responseOption, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { - if (spanWithScope == null) { + if (scope == null) { return; } - Span span = spanWithScope.getSpan(); if (throwable != null) { + scope.close(); tracer().endExceptionally(span, throwable); - spanWithScope.closeScope(); return; } - responseOption.get().addEventListener(new Listener(spanWithScope)); + responseOption.get().addEventListener(new Listener(span, scope)); } } public static class Listener implements FutureEventListener { - private final SpanWithScope spanWithScope; + private final Span span; + private final Scope scope; - public Listener(SpanWithScope spanWithScope) { - this.spanWithScope = spanWithScope; + public Listener(Span span, Scope scope) { + this.span = span; + this.scope = scope; } @Override public void onSuccess(Response response) { - Span span = spanWithScope.getSpan(); + scope.close(); tracer().end(span); - spanWithScope.closeScope(); } @Override public void onFailure(Throwable cause) { - Span span = spanWithScope.getSpan(); + scope.close(); tracer().endExceptionally(span, cause); - spanWithScope.closeScope(); } } } diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java index 6bf98e4a63..4ede395e00 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/CriteriaInstrumentation.java @@ -13,9 +13,9 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Map; @@ -48,24 +48,33 @@ public class CriteriaInstrumentation implements TypeInstrumentation { public static class CriteriaMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope startMethod( - @Advice.This Criteria criteria, @Advice.Origin("#m") String name) { + public static void startMethod( + @Advice.This Criteria criteria, + @Advice.Origin("#m") String name, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { ContextStore contextStore = InstrumentationContext.get(Criteria.class, Context.class); - return SessionMethodUtils.startScopeFrom( - contextStore, criteria, "Criteria." + name, null, true); + context = SessionMethodUtils.startSpanFrom(contextStore, criteria, "Criteria." + name, null); + if (context != null) { + scope = context.makeCurrent(); + } } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable, @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object entity, - @Advice.Origin("#m") String name) { + @Advice.Origin("#m") String name, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - SessionMethodUtils.closeScope(spanWithScope, throwable, "Criteria." + name, entity); + if (scope != null) { + SessionMethodUtils.end(context, throwable, "Criteria." + name, entity); + scope.close(); + } } } } diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java index 5c7edd4e05..5d0759bbc5 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/QueryInstrumentation.java @@ -13,9 +13,9 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Map; @@ -47,20 +47,30 @@ public class QueryInstrumentation implements TypeInstrumentation { public static class QueryMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope startMethod(@Advice.This Query query) { + public static void startMethod( + @Advice.This Query query, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { ContextStore contextStore = InstrumentationContext.get(Query.class, Context.class); - return SessionMethodUtils.startScopeFrom( - contextStore, query, query.getQueryString(), null, true); + context = SessionMethodUtils.startSpanFrom(contextStore, query, query.getQueryString(), null); + if (context != null) { + scope = context.makeCurrent(); + } } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - SessionMethodUtils.closeScope(spanWithScope, throwable, null, null); + if (scope != null) { + SessionMethodUtils.end(context, throwable, null, null); + scope.close(); + } } } } diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionInstrumentation.java index 7389904d7b..c93cc54406 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/SessionInstrumentation.java @@ -19,10 +19,11 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.HashMap; @@ -137,34 +138,53 @@ public class SessionInstrumentation implements TypeInstrumentation { public static class SessionMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope startMethod( + public static void startMethod( @Advice.This Object session, @Advice.Origin("#m") String name, - @Advice.Argument(0) Object entity) { + @Advice.Argument(0) Object entity, + @Advice.Local("otelContext") Context spanContext, + @Advice.Local("otelScope") Scope scope) { - boolean startSpan = !SCOPE_ONLY_METHODS.contains(name); + Context sessionContext = null; if (session instanceof Session) { ContextStore contextStore = InstrumentationContext.get(Session.class, Context.class); - return SessionMethodUtils.startScopeFrom( - contextStore, (Session) session, "Session." + name, entity, startSpan); + sessionContext = contextStore.get((Session) session); } else if (session instanceof StatelessSession) { ContextStore contextStore = InstrumentationContext.get(StatelessSession.class, Context.class); - return SessionMethodUtils.startScopeFrom( - contextStore, (StatelessSession) session, "Session." + name, entity, startSpan); + sessionContext = contextStore.get((StatelessSession) session); + } + + if (sessionContext == null) { + return; // No state found. We aren't in a Session. + } + + if (CallDepthThreadLocalMap.incrementCallDepth(SessionMethodUtils.class) > 0) { + return; // This method call is being traced already. + } + + if (!SCOPE_ONLY_METHODS.contains(name)) { + Span span = tracer().startSpan(sessionContext, "Session." + name, entity); + spanContext = sessionContext.with(span); + scope = spanContext.makeCurrent(); + } else { + scope = sessionContext.makeCurrent(); } - return null; } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable, @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returned, - @Advice.Origin("#m") String name) { + @Advice.Origin("#m") String name, + @Advice.Local("otelContext") Context spanContext, + @Advice.Local("otelScope") Scope scope) { - SessionMethodUtils.closeScope(spanWithScope, throwable, "Session." + name, returned); + if (scope != null) { + scope.close(); + SessionMethodUtils.end(spanContext, throwable, "Session." + name, returned); + } } } diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java index d30cabe915..d70868118f 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/TransactionInstrumentation.java @@ -13,9 +13,9 @@ import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Map; @@ -47,20 +47,31 @@ public class TransactionInstrumentation implements TypeInstrumentation { public static class TransactionCommitAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope startCommit(@Advice.This Transaction transaction) { + public static void startCommit( + @Advice.This Transaction transaction, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { ContextStore contextStore = InstrumentationContext.get(Transaction.class, Context.class); - return SessionMethodUtils.startScopeFrom( - contextStore, transaction, "Transaction.commit", null, true); + context = + SessionMethodUtils.startSpanFrom(contextStore, transaction, "Transaction.commit", null); + if (context != null) { + scope = context.makeCurrent(); + } } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endCommit( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - SessionMethodUtils.closeScope(spanWithScope, throwable, null, null); + if (scope != null) { + SessionMethodUtils.end(context, throwable, null, null); + scope.close(); + } } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java index fe11341078..198bf86f0d 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/CriteriaInstrumentation.java @@ -13,9 +13,9 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Map; @@ -48,24 +48,33 @@ public class CriteriaInstrumentation implements TypeInstrumentation { public static class CriteriaMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope startMethod( - @Advice.This Criteria criteria, @Advice.Origin("#m") String name) { + public static void startMethod( + @Advice.This Criteria criteria, + @Advice.Origin("#m") String name, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { ContextStore contextStore = InstrumentationContext.get(Criteria.class, Context.class); - return SessionMethodUtils.startScopeFrom( - contextStore, criteria, "Criteria." + name, null, true); + context = SessionMethodUtils.startSpanFrom(contextStore, criteria, "Criteria." + name, null); + if (context != null) { + scope = context.makeCurrent(); + } } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable, @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object entity, - @Advice.Origin("#m") String name) { + @Advice.Origin("#m") String name, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - SessionMethodUtils.closeScope(spanWithScope, throwable, "Criteria." + name, entity); + if (scope != null) { + scope.close(); + SessionMethodUtils.end(context, throwable, "Criteria." + name, entity); + } } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java index 4250c05ea1..c9d6d73b0e 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/QueryInstrumentation.java @@ -13,9 +13,9 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Map; @@ -47,20 +47,30 @@ public class QueryInstrumentation implements TypeInstrumentation { public static class QueryMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope startMethod(@Advice.This Query query) { + public static void startMethod( + @Advice.This Query query, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { ContextStore contextStore = InstrumentationContext.get(Query.class, Context.class); - return SessionMethodUtils.startScopeFrom( - contextStore, query, query.getQueryString(), null, true); + context = SessionMethodUtils.startSpanFrom(contextStore, query, query.getQueryString(), null); + if (context != null) { + scope = context.makeCurrent(); + } } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - SessionMethodUtils.closeScope(spanWithScope, throwable, null, null); + if (scope != null) { + scope.close(); + SessionMethodUtils.end(context, throwable, null, null); + } } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java index bc35a87095..638cd0f5bd 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/SessionInstrumentation.java @@ -19,10 +19,11 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.HashMap; @@ -126,26 +127,46 @@ public class SessionInstrumentation implements TypeInstrumentation { public static class SessionMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope startMethod( + public static void startMethod( @Advice.This SharedSessionContract session, @Advice.Origin("#m") String name, - @Advice.Argument(0) Object entity) { + @Advice.Argument(0) Object entity, + @Advice.Local("otelContext") Context spanContext, + @Advice.Local("otelScope") Scope scope) { - boolean startSpan = !SCOPE_ONLY_METHODS.contains(name); ContextStore contextStore = InstrumentationContext.get(SharedSessionContract.class, Context.class); - return SessionMethodUtils.startScopeFrom( - contextStore, session, "Session." + name, entity, startSpan); + Context sessionContext = contextStore.get(session); + + if (sessionContext == null) { + return; // No state found. We aren't in a Session. + } + + if (CallDepthThreadLocalMap.incrementCallDepth(SessionMethodUtils.class) > 0) { + return; // This method call is being traced already. + } + + if (!SCOPE_ONLY_METHODS.contains(name)) { + Span span = tracer().startSpan(sessionContext, "Session." + name, entity); + spanContext = sessionContext.with(span); + scope = spanContext.makeCurrent(); + } else { + scope = sessionContext.makeCurrent(); + } } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable, @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returned, - @Advice.Origin("#m") String name) { + @Advice.Origin("#m") String name, + @Advice.Local("otelContext") Context spanContext, + @Advice.Local("otelScope") Scope scope) { - SessionMethodUtils.closeScope(spanWithScope, throwable, "Session." + name, returned); + if (scope != null) { + scope.close(); + SessionMethodUtils.end(spanContext, throwable, "Session." + name, returned); + } } } diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java index f126d782a9..2113d5abd2 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/TransactionInstrumentation.java @@ -13,9 +13,9 @@ import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Map; @@ -47,20 +47,31 @@ public class TransactionInstrumentation implements TypeInstrumentation { public static class TransactionCommitAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope startCommit(@Advice.This Transaction transaction) { + public static void startCommit( + @Advice.This Transaction transaction, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { ContextStore contextStore = InstrumentationContext.get(Transaction.class, Context.class); - return SessionMethodUtils.startScopeFrom( - contextStore, transaction, "Transaction.commit", null, true); + context = + SessionMethodUtils.startSpanFrom(contextStore, transaction, "Transaction.commit", null); + if (context != null) { + scope = context.makeCurrent(); + } } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endCommit( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { - SessionMethodUtils.closeScope(spanWithScope, throwable, null, null); + if (scope != null) { + scope.close(); + SessionMethodUtils.end(context, throwable, null, null); + } } } } diff --git a/instrumentation/hibernate/hibernate-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java b/instrumentation/hibernate/hibernate-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java index 5c105f8cf5..49f175e5c6 100644 --- a/instrumentation/hibernate/hibernate-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java +++ b/instrumentation/hibernate/hibernate-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_3/ProcedureCallInstrumentation.java @@ -12,9 +12,9 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.instrumentation.api.ContextStore; import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.instrumentation.hibernate.SessionMethodUtils; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Map; @@ -46,20 +46,33 @@ public class ProcedureCallInstrumentation implements TypeInstrumentation { public static class ProcedureCallMethodAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope startMethod( - @Advice.This ProcedureCall call, @Advice.Origin("#m") String name) { + public static void startMethod( + @Advice.This ProcedureCall call, + @Advice.Origin("#m") String name, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { ContextStore contextStore = InstrumentationContext.get(ProcedureCall.class, Context.class); - return SessionMethodUtils.startScopeFrom( - contextStore, call, "ProcedureCall." + name, call.getProcedureName(), true); + context = + SessionMethodUtils.startSpanFrom( + contextStore, call, "ProcedureCall." + name, call.getProcedureName()); + if (context != null) { + scope = context.makeCurrent(); + } } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void endMethod( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) { - SessionMethodUtils.closeScope(spanWithScope, throwable, null, null); + @Advice.Thrown Throwable throwable, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + if (scope != null) { + scope.close(); + SessionMethodUtils.end(context, throwable, null, null); + } } } } diff --git a/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java b/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java index 9dfb137fbf..e99bd144be 100644 --- a/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java +++ b/instrumentation/hibernate/hibernate-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/SessionMethodUtils.java @@ -11,24 +11,21 @@ import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; import io.opentelemetry.javaagent.instrumentation.api.ContextStore; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import org.checkerframework.checker.nullness.qual.Nullable; public class SessionMethodUtils { public static final Set SCOPE_ONLY_METHODS = new HashSet<>(Arrays.asList("immediateLoad", "internalLoad")); - // Starts a scope as a child from a Span, where the Span is attached to the given spanKey using - // the given contextStore. - public static SpanWithScope startScopeFrom( + public static Context startSpanFrom( ContextStore contextStore, TARGET spanKey, String operationName, - ENTITY entity, - boolean createSpan) { + ENTITY entity) { Context sessionContext = contextStore.get(spanKey); if (sessionContext == null) { @@ -40,40 +37,31 @@ public class SessionMethodUtils { return null; // This method call is being traced already. } - if (createSpan) { - Span span = tracer().startSpan(sessionContext, operationName, entity); - return new SpanWithScope(span, sessionContext.with(span).makeCurrent()); - } else { - return new SpanWithScope(null, sessionContext.makeCurrent()); - } + Span span = tracer().startSpan(sessionContext, operationName, entity); + return sessionContext.with(span); } - // Closes a Scope/Span, adding an error tag if the given Throwable is not null. - public static void closeScope( - SpanWithScope spanWithScope, Throwable throwable, String operationName, Object entity) { + public static void end( + @Nullable Context context, Throwable throwable, String operationName, Object entity) { - if (spanWithScope == null) { - // This method call was re-entrant. Do nothing, since it is being traced by the parent/first - // call. - return; - } CallDepthThreadLocalMap.reset(SessionMethodUtils.class); - Span span = spanWithScope.getSpan(); - if (span != null) { - if (operationName != null && entity != null) { - String entityName = tracer().entityName(entity); - if (entityName != null) { - span.updateName(operationName + " " + entityName); - } - } - if (throwable != null) { - tracer().endExceptionally(span, throwable); - } else { - tracer().end(span); + if (context == null) { + return; + } + + Span span = Span.fromContext(context); + if (operationName != null && entity != null) { + String entityName = tracer().entityName(entity); + if (entityName != null) { + span.updateName(operationName + " " + entityName); } } - spanWithScope.closeScope(); + if (throwable != null) { + tracer().endExceptionally(span, throwable); + } else { + tracer().end(span); + } } // Copies a span from the given Session ContextStore into the targetContextStore. Used to diff --git a/instrumentation/jaxrs/jaxrs-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrs/v1_0/JaxRsAnnotationsInstrumentation.java b/instrumentation/jaxrs/jaxrs-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrs/v1_0/JaxRsAnnotationsInstrumentation.java index 611d1bd92a..7d658d0f84 100644 --- a/instrumentation/jaxrs/jaxrs-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrs/v1_0/JaxRsAnnotationsInstrumentation.java +++ b/instrumentation/jaxrs/jaxrs-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxrs/v1_0/JaxRsAnnotationsInstrumentation.java @@ -17,8 +17,8 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod; import static net.bytebuddy.matcher.ElementMatchers.named; import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.lang.reflect.Method; import java.util.Map; @@ -63,31 +63,34 @@ public class JaxRsAnnotationsInstrumentation implements TypeInstrumentation { public static class JaxRsAnnotationsAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope nameSpan(@Advice.This Object target, @Advice.Origin Method method) { + public static void nameSpan( + @Advice.This Object target, + @Advice.Origin Method method, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { if (CallDepthThreadLocalMap.incrementCallDepth(Path.class) > 0) { - return null; + return; } - - Span span = tracer().startSpan(target.getClass(), method); - - return new SpanWithScope(span, span.makeCurrent()); + span = tracer().startSpan(target.getClass(), method); + scope = span.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void stopSpan( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) { - if (spanWithScope == null) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + if (scope == null) { return; } CallDepthThreadLocalMap.reset(Path.class); - Span span = spanWithScope.getSpan(); + scope.close(); if (throwable == null) { tracer().end(span); } else { tracer().endExceptionally(span, throwable); } - spanWithScope.closeScope(); } } } diff --git a/instrumentation/kafka-clients-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkaclients/TracingIterator.java b/instrumentation/kafka-clients-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkaclients/TracingIterator.java index 4300ea093f..84da446061 100644 --- a/instrumentation/kafka-clients-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkaclients/TracingIterator.java +++ b/instrumentation/kafka-clients-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkaclients/TracingIterator.java @@ -6,7 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.kafkaclients; import io.opentelemetry.api.trace.Span; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; +import io.opentelemetry.context.Scope; import java.util.Iterator; import org.apache.kafka.clients.consumer.ConsumerRecord; import org.slf4j.Logger; @@ -24,7 +24,9 @@ public class TracingIterator implements Iterator> { * Note: this may potentially create problems if this iterator is used from different threads. But * at the moment we cannot do much about this. */ - private SpanWithScope currentSpanWithScope; + private Span currentSpan; + + private Scope currentScope; public TracingIterator( Iterator> delegateIterator, KafkaConsumerTracer tracer) { @@ -35,30 +37,21 @@ public class TracingIterator implements Iterator> { @Override public boolean hasNext() { - if (currentSpanWithScope != null) { - tracer.end(currentSpanWithScope.getSpan()); - currentSpanWithScope.closeScope(); - currentSpanWithScope = null; - } + closeScopeAndEndSpan(); return delegateIterator.hasNext(); } @Override public ConsumerRecord next() { - if (currentSpanWithScope != null) { - // in case they didn't call hasNext()... - tracer.end(currentSpanWithScope.getSpan()); - currentSpanWithScope.closeScope(); - currentSpanWithScope = null; - } + // in case they didn't call hasNext()... + closeScopeAndEndSpan(); ConsumerRecord next = delegateIterator.next(); try { if (next != null) { - Span span = tracer.startSpan(next); - - currentSpanWithScope = new SpanWithScope(span, span.makeCurrent()); + currentSpan = tracer.startSpan(next); + currentScope = currentSpan.makeCurrent(); } } catch (Exception e) { log.debug("Error during decoration", e); @@ -66,6 +59,15 @@ public class TracingIterator implements Iterator> { return next; } + private void closeScopeAndEndSpan() { + if (currentScope != null) { + currentScope.close(); + currentScope = null; + tracer.end(currentSpan); + currentSpan = null; + } + } + @Override public void remove() { delegateIterator.remove(); diff --git a/instrumentation/kafka-streams-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkastreams/SpanScopeHolder.java b/instrumentation/kafka-streams-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkastreams/SpanScopeHolder.java index 9aaa53976a..ca92aa00ff 100644 --- a/instrumentation/kafka-streams-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkastreams/SpanScopeHolder.java +++ b/instrumentation/kafka-streams-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkastreams/SpanScopeHolder.java @@ -5,18 +5,25 @@ package io.opentelemetry.javaagent.instrumentation.kafkastreams; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; public class SpanScopeHolder { public static final ThreadLocal HOLDER = new ThreadLocal<>(); - private SpanWithScope spanWithScope; + private Span span; + private Scope scope; - public SpanWithScope getSpanWithScope() { - return spanWithScope; + public void closeScope() { + scope.close(); } - public void setSpanWithScope(SpanWithScope spanWithScope) { - this.spanWithScope = spanWithScope; + public Span getSpan() { + return span; + } + + public void set(Span span, Scope scope) { + this.span = span; + this.scope = scope; } } diff --git a/instrumentation/kafka-streams-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkastreams/StreamTaskStartInstrumentation.java b/instrumentation/kafka-streams-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkastreams/StreamTaskStartInstrumentation.java index aa5036c380..c9e52befb4 100644 --- a/instrumentation/kafka-streams-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkastreams/StreamTaskStartInstrumentation.java +++ b/instrumentation/kafka-streams-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkastreams/StreamTaskStartInstrumentation.java @@ -14,7 +14,6 @@ import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.returns; import io.opentelemetry.api.trace.Span; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -56,7 +55,7 @@ public class StreamTaskStartInstrumentation implements TypeInstrumentation { Span span = tracer().startSpan(record); - holder.setSpanWithScope(new SpanWithScope(span, span.makeCurrent())); + holder.set(span, span.makeCurrent()); } } } diff --git a/instrumentation/kafka-streams-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkastreams/StreamTaskStopInstrumentation.java b/instrumentation/kafka-streams-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkastreams/StreamTaskStopInstrumentation.java index 110079c8dd..8bea619741 100644 --- a/instrumentation/kafka-streams-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkastreams/StreamTaskStopInstrumentation.java +++ b/instrumentation/kafka-streams-0.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kafkastreams/StreamTaskStopInstrumentation.java @@ -14,7 +14,6 @@ import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import io.opentelemetry.api.trace.Span; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -49,11 +48,9 @@ public class StreamTaskStopInstrumentation implements TypeInstrumentation { public static void stopSpan( @Advice.Enter SpanScopeHolder holder, @Advice.Thrown Throwable throwable) { HOLDER.remove(); - SpanWithScope spanWithScope = holder.getSpanWithScope(); - if (spanWithScope != null) { - spanWithScope.closeScope(); - - Span span = spanWithScope.getSpan(); + Span span = holder.getSpan(); + if (span != null) { + holder.closeScope(); if (throwable != null) { tracer().endExceptionally(span, throwable); diff --git a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/InstrumentationPoints.java b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/InstrumentationPoints.java index 38a0818362..781cfa7dae 100644 --- a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/InstrumentationPoints.java +++ b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/InstrumentationPoints.java @@ -8,14 +8,13 @@ package io.opentelemetry.javaagent.instrumentation.lettuce.v4_0; import static com.lambdaworks.redis.protocol.CommandKeyword.SEGFAULT; import static com.lambdaworks.redis.protocol.CommandType.DEBUG; import static com.lambdaworks.redis.protocol.CommandType.SHUTDOWN; +import static io.opentelemetry.javaagent.instrumentation.lettuce.v4_0.LettuceDatabaseClientTracer.tracer; -import com.lambdaworks.redis.RedisURI; import com.lambdaworks.redis.protocol.AsyncCommand; import com.lambdaworks.redis.protocol.CommandType; import com.lambdaworks.redis.protocol.ProtocolKeyword; import com.lambdaworks.redis.protocol.RedisCommand; import io.opentelemetry.api.trace.Span; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import java.util.EnumSet; import java.util.Set; import java.util.concurrent.CancellationException; @@ -24,52 +23,30 @@ public final class InstrumentationPoints { private static final Set NON_INSTRUMENTING_COMMANDS = EnumSet.of(SHUTDOWN, DEBUG); - public static SpanWithScope beforeCommand(RedisCommand command) { - Span span = LettuceDatabaseClientTracer.tracer().startSpan(null, command); - return new SpanWithScope(span, LettuceDatabaseClientTracer.tracer().startScope(span)); - } - public static void afterCommand( RedisCommand command, - SpanWithScope spanWithScope, + Span span, Throwable throwable, AsyncCommand asyncCommand) { - Span span = spanWithScope.getSpan(); if (throwable != null) { - LettuceDatabaseClientTracer.tracer().endExceptionally(span, throwable); + tracer().endExceptionally(span, throwable); } else if (expectsResponse(command)) { asyncCommand.handleAsync( (value, ex) -> { if (ex == null) { - LettuceDatabaseClientTracer.tracer().end(span); + tracer().end(span); } else if (ex instanceof CancellationException) { span.setAttribute("lettuce.command.cancelled", true); - LettuceDatabaseClientTracer.tracer().end(span); + tracer().end(span); } else { - LettuceDatabaseClientTracer.tracer().endExceptionally(span, ex); + tracer().endExceptionally(span, ex); } return null; }); } else { // No response is expected, so we must finish the span now. - LettuceDatabaseClientTracer.tracer().end(span); + tracer().end(span); } - spanWithScope.closeScope(); - } - - public static SpanWithScope beforeConnect(RedisURI redisUri) { - Span span = LettuceConnectionDatabaseClientTracer.tracer().startSpan(redisUri, "CONNECT"); - return new SpanWithScope(span, LettuceConnectionDatabaseClientTracer.tracer().startScope(span)); - } - - public static void afterConnect(SpanWithScope spanWithScope, Throwable throwable) { - Span span = spanWithScope.getSpan(); - if (throwable != null) { - LettuceConnectionDatabaseClientTracer.tracer().endExceptionally(span, throwable); - } else { - LettuceConnectionDatabaseClientTracer.tracer().end(span); - } - spanWithScope.closeScope(); } /** diff --git a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncCommandsAdvice.java b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncCommandsAdvice.java index a40aea3798..82bf66f070 100644 --- a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncCommandsAdvice.java +++ b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/LettuceAsyncCommandsAdvice.java @@ -5,24 +5,33 @@ package io.opentelemetry.javaagent.instrumentation.lettuce.v4_0; +import static io.opentelemetry.javaagent.instrumentation.lettuce.v4_0.LettuceDatabaseClientTracer.tracer; + import com.lambdaworks.redis.protocol.AsyncCommand; import com.lambdaworks.redis.protocol.RedisCommand; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; import net.bytebuddy.asm.Advice; public class LettuceAsyncCommandsAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope onEnter(@Advice.Argument(0) RedisCommand command) { - return InstrumentationPoints.beforeCommand(command); + public static void onEnter( + @Advice.Argument(0) RedisCommand command, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + span = tracer().startSpan(null, command); + scope = tracer().startScope(span); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void onExit( @Advice.Argument(0) RedisCommand command, - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable, - @Advice.Return AsyncCommand asyncCommand) { - InstrumentationPoints.afterCommand(command, spanWithScope, throwable, asyncCommand); + @Advice.Return AsyncCommand asyncCommand, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + scope.close(); + InstrumentationPoints.afterCommand(command, span, throwable, asyncCommand); } } diff --git a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/RedisConnectionAdvice.java b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/RedisConnectionAdvice.java index 3abc55e7c1..1c2c3136ee 100644 --- a/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/RedisConnectionAdvice.java +++ b/instrumentation/lettuce/lettuce-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/lettuce/v4_0/RedisConnectionAdvice.java @@ -5,19 +5,34 @@ package io.opentelemetry.javaagent.instrumentation.lettuce.v4_0; +import static io.opentelemetry.javaagent.instrumentation.lettuce.v4_0.LettuceConnectionDatabaseClientTracer.tracer; + import com.lambdaworks.redis.RedisURI; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; import net.bytebuddy.asm.Advice; public class RedisConnectionAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope onEnter(@Advice.Argument(1) RedisURI redisUri) { - return InstrumentationPoints.beforeConnect(redisUri); + public static void onEnter( + @Advice.Argument(1) RedisURI redisUri, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + span = tracer().startSpan(redisUri, "CONNECT"); + scope = tracer().startScope(span); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void onExit(@Advice.Enter SpanWithScope scope, @Advice.Thrown Throwable throwable) { - InstrumentationPoints.afterConnect(scope, throwable); + public static void onExit( + @Advice.Thrown Throwable throwable, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + scope.close(); + if (throwable != null) { + tracer().endExceptionally(span, throwable); + } else { + tracer().end(span); + } } } diff --git a/instrumentation/play/play-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_3/PlayAdvice.java b/instrumentation/play/play-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_3/PlayAdvice.java index 527bc6e2a4..7c06fef7b5 100644 --- a/instrumentation/play/play-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_3/PlayAdvice.java +++ b/instrumentation/play/play-2.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_3/PlayAdvice.java @@ -9,8 +9,8 @@ import static io.opentelemetry.javaagent.instrumentation.play.v2_3.PlayTracer.tr import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span.Kind; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.tracer.BaseTracer; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import net.bytebuddy.asm.Advice; import play.api.mvc.Action; import play.api.mvc.Headers; @@ -20,30 +20,31 @@ import scala.concurrent.Future; public class PlayAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope onEnter(@Advice.Argument(0) final Request req) { - Span span = tracer().startSpan("play.request", Kind.INTERNAL); - - return new SpanWithScope(span, span.makeCurrent()); + public static void onEnter( + @Advice.Argument(0) final Request req, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + span = tracer().startSpan("play.request", Kind.INTERNAL); + scope = span.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void stopTraceOnResponse( - @Advice.Enter SpanWithScope playControllerScope, @Advice.This Object thisAction, @Advice.Thrown Throwable throwable, @Advice.Argument(0) Request req, - @Advice.Return(readOnly = false) Future responseFuture) { - Span playControllerSpan = playControllerScope.getSpan(); + @Advice.Return(readOnly = false) Future responseFuture, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + scope.close(); + // span finished in RequestCompleteCallback if (throwable == null) { responseFuture.onComplete( - new RequestCompleteCallback(playControllerSpan), - ((Action) thisAction).executionContext()); + new RequestCompleteCallback(span), ((Action) thisAction).executionContext()); } else { - tracer().endExceptionally(playControllerSpan, throwable); + tracer().endExceptionally(span, throwable); } - playControllerScope.closeScope(); - // span finished in RequestCompleteCallback // set the span name on the upstream akka/netty span tracer().updateSpanName(BaseTracer.getCurrentServerSpan(), req); diff --git a/instrumentation/play/play-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_4/PlayAdvice.java b/instrumentation/play/play-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_4/PlayAdvice.java index 4cdc682b50..0b715cc203 100644 --- a/instrumentation/play/play-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_4/PlayAdvice.java +++ b/instrumentation/play/play-2.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_4/PlayAdvice.java @@ -9,8 +9,8 @@ import static io.opentelemetry.javaagent.instrumentation.play.v2_4.PlayTracer.tr import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span.Kind; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.tracer.BaseTracer; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import net.bytebuddy.asm.Advice; import play.api.mvc.Action; import play.api.mvc.Headers; @@ -20,36 +20,36 @@ import scala.concurrent.Future; public class PlayAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope onEnter(@Advice.Argument(0) Request req) { - Span span = tracer().startSpan("play.request", Kind.INTERNAL); - return new SpanWithScope(span, span.makeCurrent()); + public static void onEnter( + @Advice.Argument(0) Request req, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + span = tracer().startSpan("play.request", Kind.INTERNAL); + scope = span.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void stopTraceOnResponse( - @Advice.Enter SpanWithScope playControllerScope, @Advice.This Object thisAction, @Advice.Thrown Throwable throwable, @Advice.Argument(0) Request req, - @Advice.Return(readOnly = false) Future responseFuture) { - Span playControllerSpan = playControllerScope.getSpan(); - + @Advice.Return(readOnly = false) Future responseFuture, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { // Call onRequest on return after tags are populated. - tracer().updateSpanName(playControllerSpan, req); + tracer().updateSpanName(span, req); + scope.close(); + // span finished in RequestCompleteCallback if (throwable == null) { responseFuture.onComplete( - new RequestCompleteCallback(playControllerSpan), - ((Action) thisAction).executionContext()); + new RequestCompleteCallback(span), ((Action) thisAction).executionContext()); } else { - tracer().endExceptionally(playControllerSpan, throwable); + tracer().endExceptionally(span, throwable); } - playControllerScope.closeScope(); - // span finished in RequestCompleteCallback - Span rootSpan = BaseTracer.getCurrentServerSpan(); // set the span name on the upstream akka/netty span - tracer().updateSpanName(rootSpan, req); + tracer().updateSpanName(BaseTracer.getCurrentServerSpan(), req); } // Unused method for muzzle diff --git a/instrumentation/play/play-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_6/PlayAdvice.java b/instrumentation/play/play-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_6/PlayAdvice.java index cf64aecfc8..de3f403e74 100644 --- a/instrumentation/play/play-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_6/PlayAdvice.java +++ b/instrumentation/play/play-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/play/v2_6/PlayAdvice.java @@ -9,8 +9,8 @@ import static io.opentelemetry.javaagent.instrumentation.play.v2_6.PlayTracer.tr import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Span.Kind; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.tracer.BaseTracer; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import net.bytebuddy.asm.Advice; import play.api.mvc.Action; import play.api.mvc.Request; @@ -19,36 +19,35 @@ import scala.concurrent.Future; public class PlayAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope onEnter(@Advice.Argument(0) Request req) { - Span span = tracer().startSpan("play.request", Kind.INTERNAL); - - return new SpanWithScope(span, span.makeCurrent()); + public static void onEnter( + @Advice.Argument(0) Request req, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + span = tracer().startSpan("play.request", Kind.INTERNAL); + scope = span.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void stopTraceOnResponse( - @Advice.Enter SpanWithScope playControllerScope, @Advice.This Object thisAction, @Advice.Thrown Throwable throwable, @Advice.Argument(0) Request req, - @Advice.Return(readOnly = false) Future responseFuture) { - Span playControllerSpan = playControllerScope.getSpan(); - + @Advice.Return(readOnly = false) Future responseFuture, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { // Call onRequest on return after tags are populated. - tracer().updateSpanName(playControllerSpan, req); + tracer().updateSpanName(span, req); + scope.close(); + // span finished in RequestCompleteCallback if (throwable == null) { responseFuture.onComplete( - new RequestCompleteCallback(playControllerSpan), - ((Action) thisAction).executionContext()); + new RequestCompleteCallback(span), ((Action) thisAction).executionContext()); } else { - tracer().endExceptionally(playControllerSpan, throwable); + tracer().endExceptionally(span, throwable); } - playControllerScope.closeScope(); - // span finished in RequestCompleteCallback - Span rootSpan = BaseTracer.getCurrentServerSpan(); // set the span name on the upstream akka/netty span - tracer().updateSpanName(rootSpan, req); + tracer().updateSpanName(BaseTracer.getCurrentServerSpan(), req); } } diff --git a/instrumentation/spring/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/server/HandlerAdapterAdvice.java b/instrumentation/spring/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/server/HandlerAdapterAdvice.java index 901a864a1e..257808df14 100644 --- a/instrumentation/spring/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/server/HandlerAdapterAdvice.java +++ b/instrumentation/spring/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/server/HandlerAdapterAdvice.java @@ -9,9 +9,9 @@ import static io.opentelemetry.javaagent.instrumentation.spring.webflux.server.S import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.servlet.ServletContextPath; import io.opentelemetry.instrumentation.api.tracer.BaseTracer; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import net.bytebuddy.asm.Advice; import org.springframework.web.method.HandlerMethod; import org.springframework.web.reactive.HandlerMapping; @@ -21,10 +21,11 @@ import org.springframework.web.util.pattern.PathPattern; public class HandlerAdapterAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope methodEnter( - @Advice.Argument(0) ServerWebExchange exchange, @Advice.Argument(1) Object handler) { + public static void methodEnter( + @Advice.Argument(0) ServerWebExchange exchange, + @Advice.Argument(1) Object handler, + @Advice.Local("otelScope") Scope scope) { - SpanWithScope spanWithScope = null; Context context = exchange.getAttribute(AdviceUtils.CONTEXT_ATTRIBUTE); if (handler != null && context != null) { Span span = Span.fromContext(context); @@ -44,7 +45,7 @@ public class HandlerAdapterAdvice { span.updateName(operationName); span.setAttribute("spring-webflux.handler.type", handlerType); - spanWithScope = new SpanWithScope(span, context.makeCurrent()); + scope = context.makeCurrent(); } if (context != null) { @@ -56,20 +57,18 @@ public class HandlerAdapterAdvice { ServletContextPath.prepend(Context.current(), bestPattern.toString())); } } - - return spanWithScope; } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void methodExit( @Advice.Argument(0) ServerWebExchange exchange, - @Advice.Enter SpanWithScope spanWithScope, - @Advice.Thrown Throwable throwable) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelScope") Scope scope) { if (throwable != null) { AdviceUtils.finishSpanIfPresent(exchange, throwable); } - if (spanWithScope != null) { - spanWithScope.closeScope(); + if (scope != null) { + scope.close(); // span finished in SpanFinishingSubscriber } } diff --git a/instrumentation/spring/spring-webmvc-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springwebmvc/DispatcherServletInstrumentation.java b/instrumentation/spring/spring-webmvc-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springwebmvc/DispatcherServletInstrumentation.java index a494485dba..395476db02 100644 --- a/instrumentation/spring/spring-webmvc-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springwebmvc/DispatcherServletInstrumentation.java +++ b/instrumentation/spring/spring-webmvc-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springwebmvc/DispatcherServletInstrumentation.java @@ -14,8 +14,8 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.HashMap; import java.util.List; @@ -84,21 +84,25 @@ public class DispatcherServletInstrumentation implements TypeInstrumentation { public static class RenderAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope onEnter(@Advice.Argument(0) ModelAndView mv) { - Span span = tracer().startSpan(mv); - return new SpanWithScope(span, span.makeCurrent()); + public static void onEnter( + @Advice.Argument(0) ModelAndView mv, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + span = tracer().startSpan(mv); + scope = span.makeCurrent(); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void stopSpan( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) { - Span span = spanWithScope.getSpan(); + @Advice.Thrown Throwable throwable, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + scope.close(); if (throwable == null) { tracer().end(span); } else { tracer().endExceptionally(span, throwable); } - spanWithScope.closeScope(); } } diff --git a/instrumentation/spring/spring-webmvc-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springwebmvc/HandlerAdapterInstrumentation.java b/instrumentation/spring/spring-webmvc-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springwebmvc/HandlerAdapterInstrumentation.java index 394cd85676..703dbc25ad 100644 --- a/instrumentation/spring/spring-webmvc-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springwebmvc/HandlerAdapterInstrumentation.java +++ b/instrumentation/spring/spring-webmvc-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springwebmvc/HandlerAdapterInstrumentation.java @@ -18,9 +18,9 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.tracer.BaseTracer; import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Map; import javax.servlet.http.HttpServletRequest; @@ -54,35 +54,36 @@ public class HandlerAdapterInstrumentation implements TypeInstrumentation { public static class ControllerAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope nameResourceAndStartSpan( - @Advice.Argument(0) HttpServletRequest request, @Advice.Argument(2) Object handler) { + public static void nameResourceAndStartSpan( + @Advice.Argument(0) HttpServletRequest request, + @Advice.Argument(2) Object handler, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { Context context = Java8BytecodeBridge.currentContext(); Span serverSpan = BaseTracer.getCurrentServerSpan(context); if (serverSpan != null) { // Name the parent span based on the matching pattern tracer().onRequest(context, serverSpan, request); // Now create a span for handler/controller execution. - Span span = tracer().startHandlerSpan(handler); - - return new SpanWithScope(span, context.with(span).makeCurrent()); - } else { - return null; + span = tracer().startHandlerSpan(handler); + scope = context.with(span).makeCurrent(); } } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void stopSpan( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) { - if (spanWithScope == null) { + @Advice.Thrown Throwable throwable, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + if (scope == null) { return; } - Span span = spanWithScope.getSpan(); + scope.close(); if (throwable == null) { tracer().end(span); } else { tracer().endExceptionally(span, throwable); } - spanWithScope.closeScope(); } } } diff --git a/instrumentation/twilio-6.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/twilio/TwilioAsyncInstrumentation.java b/instrumentation/twilio-6.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/twilio/TwilioAsyncInstrumentation.java index df6c0d6572..5415a5be4a 100644 --- a/instrumentation/twilio-6.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/twilio/TwilioAsyncInstrumentation.java +++ b/instrumentation/twilio-6.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/twilio/TwilioAsyncInstrumentation.java @@ -22,8 +22,8 @@ import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.twilio.Twilio; import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -75,52 +75,48 @@ public class TwilioAsyncInstrumentation implements TypeInstrumentation { /** Method entry instrumentation. */ @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope methodEnter( - @Advice.This Object that, @Advice.Origin("#m") String methodName) { + public static void methodEnter( + @Advice.This Object that, + @Advice.Origin("#m") String methodName, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { // Ensure that we only create a span for the top-level Twilio client method; except in the // case of async operations where we want visibility into how long the task was delayed from // starting. Our call depth checker does not span threads, so the async case is handled // automatically for us. - int callDepth = CallDepthThreadLocalMap.incrementCallDepth(Twilio.class); - if (callDepth > 0) { - return null; + if (CallDepthThreadLocalMap.incrementCallDepth(Twilio.class) > 0) { + return; } // Don't automatically close the span with the scope if we're executing an async method - Span span = tracer().startSpan(that, methodName); - - return new SpanWithScope(span, tracer().startScope(span)); + span = tracer().startSpan(that, methodName); + scope = tracer().startScope(span); } /** Method exit instrumentation. */ @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void methodExit( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable, - @Advice.Return ListenableFuture response) { - if (spanWithScope == null) { + @Advice.Return ListenableFuture response, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + if (scope == null) { return; } CallDepthThreadLocalMap.reset(Twilio.class); - // If we have a scope (i.e. we were the top-level Twilio SDK invocation), - try { - Span span = spanWithScope.getSpan(); - - if (throwable != null) { - // There was an synchronous error, - // which means we shouldn't wait for a callback to close the span. - tracer().endExceptionally(span, throwable); - } else { - // We're calling an async operation, we still need to finish the span when it's - // complete and report the results; set an appropriate callback - Futures.addCallback( - response, new SpanFinishingCallback<>(span), Twilio.getExecutorService()); - } - } finally { - spanWithScope.closeScope(); - // span finished in SpanFinishingCallback + // span finished in SpanFinishingCallback + scope.close(); + if (throwable != null) { + // There was an synchronous error, + // which means we shouldn't wait for a callback to close the span. + tracer().endExceptionally(span, throwable); + } else { + // We're calling an async operation, we still need to finish the span when it's + // complete and report the results; set an appropriate callback + Futures.addCallback( + response, new SpanFinishingCallback<>(span), Twilio.getExecutorService()); } } } diff --git a/instrumentation/twilio-6.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/twilio/TwilioSyncInstrumentation.java b/instrumentation/twilio-6.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/twilio/TwilioSyncInstrumentation.java index b040bf6d9d..d76295c406 100644 --- a/instrumentation/twilio-6.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/twilio/TwilioSyncInstrumentation.java +++ b/instrumentation/twilio-6.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/twilio/TwilioSyncInstrumentation.java @@ -17,8 +17,8 @@ import static net.bytebuddy.matcher.ElementMatchers.not; import com.twilio.Twilio; import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; -import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope; import io.opentelemetry.javaagent.tooling.TypeInstrumentation; import java.util.Map; import net.bytebuddy.asm.Advice; @@ -71,45 +71,41 @@ public class TwilioSyncInstrumentation implements TypeInstrumentation { /** Method entry instrumentation. */ @Advice.OnMethodEnter(suppress = Throwable.class) - public static SpanWithScope methodEnter( - @Advice.This Object that, @Advice.Origin("#m") String methodName) { + public static void methodEnter( + @Advice.This Object that, + @Advice.Origin("#m") String methodName, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { // Ensure that we only create a span for the top-level Twilio client method; except in the // case of async operations where we want visibility into how long the task was delayed from // starting. Our call depth checker does not span threads, so the async case is handled // automatically for us. - int callDepth = CallDepthThreadLocalMap.incrementCallDepth(Twilio.class); - if (callDepth > 0) { - return null; + if (CallDepthThreadLocalMap.incrementCallDepth(Twilio.class) > 0) { + return; } - Span span = tracer().startSpan(that, methodName); - - return new SpanWithScope(span, tracer().startScope(span)); + span = tracer().startSpan(that, methodName); + scope = tracer().startScope(span); } /** Method exit instrumentation. */ @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void methodExit( - @Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable, - @Advice.Return Object response) { - if (spanWithScope == null) { + @Advice.Return Object response, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + if (scope == null) { return; } CallDepthThreadLocalMap.reset(Twilio.class); - // If we have a scope (i.e. we were the top-level Twilio SDK invocation), - try { - Span span = spanWithScope.getSpan(); - - if (throwable != null) { - tracer().endExceptionally(span, throwable); - } else { - tracer().end(span, response); - } - } finally { - spanWithScope.closeScope(); + scope.close(); + if (throwable != null) { + tracer().endExceptionally(span, throwable); + } else { + tracer().end(span, response); } } } diff --git a/javaagent-api/src/main/java/io/opentelemetry/javaagent/instrumentation/api/SpanWithScope.java b/javaagent-api/src/main/java/io/opentelemetry/javaagent/instrumentation/api/SpanWithScope.java deleted file mode 100644 index 266a475a14..0000000000 --- a/javaagent-api/src/main/java/io/opentelemetry/javaagent/instrumentation/api/SpanWithScope.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.api; - -import io.opentelemetry.api.trace.Span; -import io.opentelemetry.context.Scope; - -/** - * This is deprecated. - * - *

Originally, we used {@code SpanWithScope} to pass the {@link Span} and {@link Scope} between - * {@code @Advice.OnMethodEnter} and {@code @Advice.OnMethodExit}, e.g. - * - *

- *   @Advice.OnMethodEnter(...)
- *     public static SpanWithScope onEnter(...) {
- *     ...
- *     Span span = ...
- *     return new SpanWithScope(span, span.makeCurrent());
- *   }
- *
- *   @Advice.OnMethodExit(...)
- *   public static void stopSpan(
- *       ...
- *       @Advice.Enter final SpanWithScope spanWithScope) {
- *     Span span = spanWithScope.getSpan();
- *     ...
- *     span.end();
- *     spanWithScope.closeScope();
- *   }
- * 
- * - *

We are (slowly) migrating to a new pattern using `@Advice.Local`: - * - *

- *   @Advice.OnMethodEnter(...)
- *   public static void onEnter(
- *       ...
- *       @Advice.Local("otelSpan") Span span,
- *       @Advice.Local("otelScope") Scope scope) {
- *     ...
- *     span = ...
- *     scope = ...
- *   }
- *
- *   @Advice.OnMethodExit
- *   public static void onExit(
- *       ...
- *       @Advice.Local("otelSpan") Span span,
- *       @Advice.Local("otelScope") Scope scope) {
- *       ...
- *     span.end();
- *     scope.close();
- *   }
- * 
- * - *

This new pattern has the following benefits: - * - *

    - *
  • The new pattern is more efficient since it doesn't require instantiating the {@code - * SpanWithScope} holder object - *
  • The new pattern extends nicely in the common case where we also need to pass {@link - * CallDepth} between the methods - *
- * - * @deprecated see above - */ -@Deprecated -public class SpanWithScope { - private final Span span; - private final Scope scope; - - public SpanWithScope(Span span, Scope scope) { - this.span = span; - this.scope = scope; - } - - public Span getSpan() { - return span; - } - - public void closeScope() { - scope.close(); - } -}