Remove deprecated SpanWithScope class (#1834)
This commit is contained in:
parent
ef02da9090
commit
f520c2cd33
|
@ -18,8 +18,8 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||||
import com.google.auto.service.AutoService;
|
import com.google.auto.service.AutoService;
|
||||||
import io.dropwizard.views.View;
|
import io.dropwizard.views.View;
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
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.InstrumentationModule;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -65,27 +65,30 @@ public class DropwizardViewsInstrumentationModule extends InstrumentationModule
|
||||||
public static class RenderAdvice {
|
public static class RenderAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope onEnter(@Advice.Argument(0) View view) {
|
public static void onEnter(
|
||||||
if (!Java8BytecodeBridge.currentSpan().getSpanContext().isValid()) {
|
@Advice.Argument(0) View view,
|
||||||
return null;
|
@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)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void stopSpan(
|
public static void stopSpan(
|
||||||
@Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) {
|
@Advice.Thrown Throwable throwable,
|
||||||
if (spanWithScope == null) {
|
@Advice.Local("otelSpan") Span span,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
if (scope == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Span span = spanWithScope.getSpan();
|
scope.close();
|
||||||
if (throwable == null) {
|
if (throwable == null) {
|
||||||
tracer().end(span);
|
tracer().end(span);
|
||||||
} else {
|
} else {
|
||||||
tracer().endExceptionally(span, throwable);
|
tracer().endExceptionally(span, throwable);
|
||||||
}
|
}
|
||||||
spanWithScope.closeScope();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ import com.twitter.finatra.http.contexts.RouteInfo;
|
||||||
import com.twitter.util.Future;
|
import com.twitter.util.Future;
|
||||||
import com.twitter.util.FutureEventListener;
|
import com.twitter.util.FutureEventListener;
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
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.InstrumentationModule;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -71,60 +71,61 @@ public class FinatraInstrumentationModule extends InstrumentationModule {
|
||||||
|
|
||||||
public static class RouteAdvice {
|
public static class RouteAdvice {
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope nameSpan(
|
public static void nameSpan(
|
||||||
@Advice.FieldValue("routeInfo") RouteInfo routeInfo,
|
@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();
|
Span serverSpan = BaseTracer.getCurrentServerSpan();
|
||||||
if (serverSpan != null) {
|
if (serverSpan != null) {
|
||||||
serverSpan.updateName(routeInfo.path());
|
serverSpan.updateName(routeInfo.path());
|
||||||
}
|
}
|
||||||
|
|
||||||
Span span = tracer().startSpan(clazz);
|
span = tracer().startSpan(clazz);
|
||||||
|
scope = span.makeCurrent();
|
||||||
return new SpanWithScope(span, span.makeCurrent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void setupCallback(
|
public static void setupCallback(
|
||||||
@Advice.Enter SpanWithScope spanWithScope,
|
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Return Some<Future<Response>> responseOption) {
|
@Advice.Return Some<Future<Response>> responseOption,
|
||||||
|
@Advice.Local("otelSpan") Span span,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
|
||||||
if (spanWithScope == null) {
|
if (scope == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Span span = spanWithScope.getSpan();
|
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
|
scope.close();
|
||||||
tracer().endExceptionally(span, throwable);
|
tracer().endExceptionally(span, throwable);
|
||||||
spanWithScope.closeScope();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
responseOption.get().addEventListener(new Listener(spanWithScope));
|
responseOption.get().addEventListener(new Listener(span, scope));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Listener implements FutureEventListener<Response> {
|
public static class Listener implements FutureEventListener<Response> {
|
||||||
private final SpanWithScope spanWithScope;
|
private final Span span;
|
||||||
|
private final Scope scope;
|
||||||
|
|
||||||
public Listener(SpanWithScope spanWithScope) {
|
public Listener(Span span, Scope scope) {
|
||||||
this.spanWithScope = spanWithScope;
|
this.span = span;
|
||||||
|
this.scope = scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuccess(Response response) {
|
public void onSuccess(Response response) {
|
||||||
Span span = spanWithScope.getSpan();
|
scope.close();
|
||||||
tracer().end(span);
|
tracer().end(span);
|
||||||
spanWithScope.closeScope();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Throwable cause) {
|
public void onFailure(Throwable cause) {
|
||||||
Span span = spanWithScope.getSpan();
|
scope.close();
|
||||||
tracer().endExceptionally(span, cause);
|
tracer().endExceptionally(span, cause);
|
||||||
spanWithScope.closeScope();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,9 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
|
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.instrumentation.hibernate.SessionMethodUtils;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -48,24 +48,33 @@ public class CriteriaInstrumentation implements TypeInstrumentation {
|
||||||
public static class CriteriaMethodAdvice {
|
public static class CriteriaMethodAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope startMethod(
|
public static void startMethod(
|
||||||
@Advice.This Criteria criteria, @Advice.Origin("#m") String name) {
|
@Advice.This Criteria criteria,
|
||||||
|
@Advice.Origin("#m") String name,
|
||||||
|
@Advice.Local("otelContext") Context context,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
|
||||||
ContextStore<Criteria, Context> contextStore =
|
ContextStore<Criteria, Context> contextStore =
|
||||||
InstrumentationContext.get(Criteria.class, Context.class);
|
InstrumentationContext.get(Criteria.class, Context.class);
|
||||||
|
|
||||||
return SessionMethodUtils.startScopeFrom(
|
context = SessionMethodUtils.startSpanFrom(contextStore, criteria, "Criteria." + name, null);
|
||||||
contextStore, criteria, "Criteria." + name, null, true);
|
if (context != null) {
|
||||||
|
scope = context.makeCurrent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void endMethod(
|
public static void endMethod(
|
||||||
@Advice.Enter SpanWithScope spanWithScope,
|
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Return(typing = Assigner.Typing.DYNAMIC) Object entity,
|
@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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,9 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
|
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.instrumentation.hibernate.SessionMethodUtils;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -47,20 +47,30 @@ public class QueryInstrumentation implements TypeInstrumentation {
|
||||||
public static class QueryMethodAdvice {
|
public static class QueryMethodAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@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<Query, Context> contextStore =
|
ContextStore<Query, Context> contextStore =
|
||||||
InstrumentationContext.get(Query.class, Context.class);
|
InstrumentationContext.get(Query.class, Context.class);
|
||||||
|
|
||||||
return SessionMethodUtils.startScopeFrom(
|
context = SessionMethodUtils.startSpanFrom(contextStore, query, query.getQueryString(), null);
|
||||||
contextStore, query, query.getQueryString(), null, true);
|
if (context != null) {
|
||||||
|
scope = context.makeCurrent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void endMethod(
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,11 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||||
|
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
import io.opentelemetry.context.Context;
|
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.ContextStore;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
|
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
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.instrumentation.hibernate.SessionMethodUtils;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -137,34 +138,53 @@ public class SessionInstrumentation implements TypeInstrumentation {
|
||||||
public static class SessionMethodAdvice {
|
public static class SessionMethodAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope startMethod(
|
public static void startMethod(
|
||||||
@Advice.This Object session,
|
@Advice.This Object session,
|
||||||
@Advice.Origin("#m") String name,
|
@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) {
|
if (session instanceof Session) {
|
||||||
ContextStore<Session, Context> contextStore =
|
ContextStore<Session, Context> contextStore =
|
||||||
InstrumentationContext.get(Session.class, Context.class);
|
InstrumentationContext.get(Session.class, Context.class);
|
||||||
return SessionMethodUtils.startScopeFrom(
|
sessionContext = contextStore.get((Session) session);
|
||||||
contextStore, (Session) session, "Session." + name, entity, startSpan);
|
|
||||||
} else if (session instanceof StatelessSession) {
|
} else if (session instanceof StatelessSession) {
|
||||||
ContextStore<StatelessSession, Context> contextStore =
|
ContextStore<StatelessSession, Context> contextStore =
|
||||||
InstrumentationContext.get(StatelessSession.class, Context.class);
|
InstrumentationContext.get(StatelessSession.class, Context.class);
|
||||||
return SessionMethodUtils.startScopeFrom(
|
sessionContext = contextStore.get((StatelessSession) session);
|
||||||
contextStore, (StatelessSession) session, "Session." + name, entity, startSpan);
|
}
|
||||||
|
|
||||||
|
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)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void endMethod(
|
public static void endMethod(
|
||||||
@Advice.Enter SpanWithScope spanWithScope,
|
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returned,
|
@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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,9 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||||
|
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
|
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.instrumentation.hibernate.SessionMethodUtils;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -47,20 +47,31 @@ public class TransactionInstrumentation implements TypeInstrumentation {
|
||||||
public static class TransactionCommitAdvice {
|
public static class TransactionCommitAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@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<Transaction, Context> contextStore =
|
ContextStore<Transaction, Context> contextStore =
|
||||||
InstrumentationContext.get(Transaction.class, Context.class);
|
InstrumentationContext.get(Transaction.class, Context.class);
|
||||||
|
|
||||||
return SessionMethodUtils.startScopeFrom(
|
context =
|
||||||
contextStore, transaction, "Transaction.commit", null, true);
|
SessionMethodUtils.startSpanFrom(contextStore, transaction, "Transaction.commit", null);
|
||||||
|
if (context != null) {
|
||||||
|
scope = context.makeCurrent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void endCommit(
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,9 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
|
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.instrumentation.hibernate.SessionMethodUtils;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -48,24 +48,33 @@ public class CriteriaInstrumentation implements TypeInstrumentation {
|
||||||
public static class CriteriaMethodAdvice {
|
public static class CriteriaMethodAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope startMethod(
|
public static void startMethod(
|
||||||
@Advice.This Criteria criteria, @Advice.Origin("#m") String name) {
|
@Advice.This Criteria criteria,
|
||||||
|
@Advice.Origin("#m") String name,
|
||||||
|
@Advice.Local("otelContext") Context context,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
|
||||||
ContextStore<Criteria, Context> contextStore =
|
ContextStore<Criteria, Context> contextStore =
|
||||||
InstrumentationContext.get(Criteria.class, Context.class);
|
InstrumentationContext.get(Criteria.class, Context.class);
|
||||||
|
|
||||||
return SessionMethodUtils.startScopeFrom(
|
context = SessionMethodUtils.startSpanFrom(contextStore, criteria, "Criteria." + name, null);
|
||||||
contextStore, criteria, "Criteria." + name, null, true);
|
if (context != null) {
|
||||||
|
scope = context.makeCurrent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void endMethod(
|
public static void endMethod(
|
||||||
@Advice.Enter SpanWithScope spanWithScope,
|
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Return(typing = Assigner.Typing.DYNAMIC) Object entity,
|
@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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,9 +13,9 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
|
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.instrumentation.hibernate.SessionMethodUtils;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -47,20 +47,30 @@ public class QueryInstrumentation implements TypeInstrumentation {
|
||||||
public static class QueryMethodAdvice {
|
public static class QueryMethodAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@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<Query, Context> contextStore =
|
ContextStore<Query, Context> contextStore =
|
||||||
InstrumentationContext.get(Query.class, Context.class);
|
InstrumentationContext.get(Query.class, Context.class);
|
||||||
|
|
||||||
return SessionMethodUtils.startScopeFrom(
|
context = SessionMethodUtils.startSpanFrom(contextStore, query, query.getQueryString(), null);
|
||||||
contextStore, query, query.getQueryString(), null, true);
|
if (context != null) {
|
||||||
|
scope = context.makeCurrent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void endMethod(
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,11 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||||
|
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
import io.opentelemetry.context.Context;
|
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.ContextStore;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
|
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
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.instrumentation.hibernate.SessionMethodUtils;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -126,26 +127,46 @@ public class SessionInstrumentation implements TypeInstrumentation {
|
||||||
public static class SessionMethodAdvice {
|
public static class SessionMethodAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope startMethod(
|
public static void startMethod(
|
||||||
@Advice.This SharedSessionContract session,
|
@Advice.This SharedSessionContract session,
|
||||||
@Advice.Origin("#m") String name,
|
@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<SharedSessionContract, Context> contextStore =
|
ContextStore<SharedSessionContract, Context> contextStore =
|
||||||
InstrumentationContext.get(SharedSessionContract.class, Context.class);
|
InstrumentationContext.get(SharedSessionContract.class, Context.class);
|
||||||
return SessionMethodUtils.startScopeFrom(
|
Context sessionContext = contextStore.get(session);
|
||||||
contextStore, session, "Session." + name, entity, startSpan);
|
|
||||||
|
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)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void endMethod(
|
public static void endMethod(
|
||||||
@Advice.Enter SpanWithScope spanWithScope,
|
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returned,
|
@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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,9 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||||
|
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
|
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.instrumentation.hibernate.SessionMethodUtils;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -47,20 +47,31 @@ public class TransactionInstrumentation implements TypeInstrumentation {
|
||||||
public static class TransactionCommitAdvice {
|
public static class TransactionCommitAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@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<Transaction, Context> contextStore =
|
ContextStore<Transaction, Context> contextStore =
|
||||||
InstrumentationContext.get(Transaction.class, Context.class);
|
InstrumentationContext.get(Transaction.class, Context.class);
|
||||||
|
|
||||||
return SessionMethodUtils.startScopeFrom(
|
context =
|
||||||
contextStore, transaction, "Transaction.commit", null, true);
|
SessionMethodUtils.startSpanFrom(contextStore, transaction, "Transaction.commit", null);
|
||||||
|
if (context != null) {
|
||||||
|
scope = context.makeCurrent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void endCommit(
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,9 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.InstrumentationContext;
|
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.instrumentation.hibernate.SessionMethodUtils;
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -46,20 +46,33 @@ public class ProcedureCallInstrumentation implements TypeInstrumentation {
|
||||||
public static class ProcedureCallMethodAdvice {
|
public static class ProcedureCallMethodAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope startMethod(
|
public static void startMethod(
|
||||||
@Advice.This ProcedureCall call, @Advice.Origin("#m") String name) {
|
@Advice.This ProcedureCall call,
|
||||||
|
@Advice.Origin("#m") String name,
|
||||||
|
@Advice.Local("otelContext") Context context,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
|
||||||
ContextStore<ProcedureCall, Context> contextStore =
|
ContextStore<ProcedureCall, Context> contextStore =
|
||||||
InstrumentationContext.get(ProcedureCall.class, Context.class);
|
InstrumentationContext.get(ProcedureCall.class, Context.class);
|
||||||
|
|
||||||
return SessionMethodUtils.startScopeFrom(
|
context =
|
||||||
contextStore, call, "ProcedureCall." + name, call.getProcedureName(), true);
|
SessionMethodUtils.startSpanFrom(
|
||||||
|
contextStore, call, "ProcedureCall." + name, call.getProcedureName());
|
||||||
|
if (context != null) {
|
||||||
|
scope = context.makeCurrent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void endMethod(
|
public static void endMethod(
|
||||||
@Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) {
|
@Advice.Thrown Throwable throwable,
|
||||||
SessionMethodUtils.closeScope(spanWithScope, throwable, null, null);
|
@Advice.Local("otelContext") Context context,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
|
||||||
|
if (scope != null) {
|
||||||
|
scope.close();
|
||||||
|
SessionMethodUtils.end(context, throwable, null, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,24 +11,21 @@ import io.opentelemetry.api.trace.Span;
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
|
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
import io.opentelemetry.javaagent.instrumentation.api.ContextStore;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
public class SessionMethodUtils {
|
public class SessionMethodUtils {
|
||||||
|
|
||||||
public static final Set<String> SCOPE_ONLY_METHODS =
|
public static final Set<String> SCOPE_ONLY_METHODS =
|
||||||
new HashSet<>(Arrays.asList("immediateLoad", "internalLoad"));
|
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
|
public static <TARGET, ENTITY> Context startSpanFrom(
|
||||||
// the given contextStore.
|
|
||||||
public static <TARGET, ENTITY> SpanWithScope startScopeFrom(
|
|
||||||
ContextStore<TARGET, Context> contextStore,
|
ContextStore<TARGET, Context> contextStore,
|
||||||
TARGET spanKey,
|
TARGET spanKey,
|
||||||
String operationName,
|
String operationName,
|
||||||
ENTITY entity,
|
ENTITY entity) {
|
||||||
boolean createSpan) {
|
|
||||||
|
|
||||||
Context sessionContext = contextStore.get(spanKey);
|
Context sessionContext = contextStore.get(spanKey);
|
||||||
if (sessionContext == null) {
|
if (sessionContext == null) {
|
||||||
|
@ -40,40 +37,31 @@ public class SessionMethodUtils {
|
||||||
return null; // This method call is being traced already.
|
return null; // This method call is being traced already.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (createSpan) {
|
Span span = tracer().startSpan(sessionContext, operationName, entity);
|
||||||
Span span = tracer().startSpan(sessionContext, operationName, entity);
|
return sessionContext.with(span);
|
||||||
return new SpanWithScope(span, sessionContext.with(span).makeCurrent());
|
|
||||||
} else {
|
|
||||||
return new SpanWithScope(null, sessionContext.makeCurrent());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Closes a Scope/Span, adding an error tag if the given Throwable is not null.
|
public static void end(
|
||||||
public static void closeScope(
|
@Nullable Context context, Throwable throwable, String operationName, Object entity) {
|
||||||
SpanWithScope spanWithScope, 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);
|
CallDepthThreadLocalMap.reset(SessionMethodUtils.class);
|
||||||
|
|
||||||
Span span = spanWithScope.getSpan();
|
if (context == null) {
|
||||||
if (span != null) {
|
return;
|
||||||
if (operationName != null && entity != null) {
|
}
|
||||||
String entityName = tracer().entityName(entity);
|
|
||||||
if (entityName != null) {
|
Span span = Span.fromContext(context);
|
||||||
span.updateName(operationName + " " + entityName);
|
if (operationName != null && entity != null) {
|
||||||
}
|
String entityName = tracer().entityName(entity);
|
||||||
}
|
if (entityName != null) {
|
||||||
if (throwable != null) {
|
span.updateName(operationName + " " + entityName);
|
||||||
tracer().endExceptionally(span, throwable);
|
|
||||||
} else {
|
|
||||||
tracer().end(span);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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
|
// Copies a span from the given Session ContextStore into the targetContextStore. Used to
|
||||||
|
|
|
@ -17,8 +17,8 @@ import static net.bytebuddy.matcher.ElementMatchers.isMethod;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
|
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
|
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -63,31 +63,34 @@ public class JaxRsAnnotationsInstrumentation implements TypeInstrumentation {
|
||||||
public static class JaxRsAnnotationsAdvice {
|
public static class JaxRsAnnotationsAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@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) {
|
if (CallDepthThreadLocalMap.incrementCallDepth(Path.class) > 0) {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
span = tracer().startSpan(target.getClass(), method);
|
||||||
Span span = tracer().startSpan(target.getClass(), method);
|
scope = span.makeCurrent();
|
||||||
|
|
||||||
return new SpanWithScope(span, span.makeCurrent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void stopSpan(
|
public static void stopSpan(
|
||||||
@Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) {
|
@Advice.Thrown Throwable throwable,
|
||||||
if (spanWithScope == null) {
|
@Advice.Local("otelSpan") Span span,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
if (scope == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CallDepthThreadLocalMap.reset(Path.class);
|
CallDepthThreadLocalMap.reset(Path.class);
|
||||||
|
|
||||||
Span span = spanWithScope.getSpan();
|
scope.close();
|
||||||
if (throwable == null) {
|
if (throwable == null) {
|
||||||
tracer().end(span);
|
tracer().end(span);
|
||||||
} else {
|
} else {
|
||||||
tracer().endExceptionally(span, throwable);
|
tracer().endExceptionally(span, throwable);
|
||||||
}
|
}
|
||||||
spanWithScope.closeScope();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
package io.opentelemetry.javaagent.instrumentation.kafkaclients;
|
package io.opentelemetry.javaagent.instrumentation.kafkaclients;
|
||||||
|
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
import io.opentelemetry.context.Scope;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -24,7 +24,9 @@ public class TracingIterator implements Iterator<ConsumerRecord<?, ?>> {
|
||||||
* Note: this may potentially create problems if this iterator is used from different threads. But
|
* Note: this may potentially create problems if this iterator is used from different threads. But
|
||||||
* at the moment we cannot do much about this.
|
* at the moment we cannot do much about this.
|
||||||
*/
|
*/
|
||||||
private SpanWithScope currentSpanWithScope;
|
private Span currentSpan;
|
||||||
|
|
||||||
|
private Scope currentScope;
|
||||||
|
|
||||||
public TracingIterator(
|
public TracingIterator(
|
||||||
Iterator<ConsumerRecord<?, ?>> delegateIterator, KafkaConsumerTracer tracer) {
|
Iterator<ConsumerRecord<?, ?>> delegateIterator, KafkaConsumerTracer tracer) {
|
||||||
|
@ -35,30 +37,21 @@ public class TracingIterator implements Iterator<ConsumerRecord<?, ?>> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
if (currentSpanWithScope != null) {
|
closeScopeAndEndSpan();
|
||||||
tracer.end(currentSpanWithScope.getSpan());
|
|
||||||
currentSpanWithScope.closeScope();
|
|
||||||
currentSpanWithScope = null;
|
|
||||||
}
|
|
||||||
return delegateIterator.hasNext();
|
return delegateIterator.hasNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ConsumerRecord<?, ?> next() {
|
public ConsumerRecord<?, ?> next() {
|
||||||
if (currentSpanWithScope != null) {
|
// in case they didn't call hasNext()...
|
||||||
// in case they didn't call hasNext()...
|
closeScopeAndEndSpan();
|
||||||
tracer.end(currentSpanWithScope.getSpan());
|
|
||||||
currentSpanWithScope.closeScope();
|
|
||||||
currentSpanWithScope = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
ConsumerRecord<?, ?> next = delegateIterator.next();
|
ConsumerRecord<?, ?> next = delegateIterator.next();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (next != null) {
|
if (next != null) {
|
||||||
Span span = tracer.startSpan(next);
|
currentSpan = tracer.startSpan(next);
|
||||||
|
currentScope = currentSpan.makeCurrent();
|
||||||
currentSpanWithScope = new SpanWithScope(span, span.makeCurrent());
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.debug("Error during decoration", e);
|
log.debug("Error during decoration", e);
|
||||||
|
@ -66,6 +59,15 @@ public class TracingIterator implements Iterator<ConsumerRecord<?, ?>> {
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void closeScopeAndEndSpan() {
|
||||||
|
if (currentScope != null) {
|
||||||
|
currentScope.close();
|
||||||
|
currentScope = null;
|
||||||
|
tracer.end(currentSpan);
|
||||||
|
currentSpan = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove() {
|
public void remove() {
|
||||||
delegateIterator.remove();
|
delegateIterator.remove();
|
||||||
|
|
|
@ -5,18 +5,25 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.kafkastreams;
|
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 class SpanScopeHolder {
|
||||||
public static final ThreadLocal<SpanScopeHolder> HOLDER = new ThreadLocal<>();
|
public static final ThreadLocal<SpanScopeHolder> HOLDER = new ThreadLocal<>();
|
||||||
|
|
||||||
private SpanWithScope spanWithScope;
|
private Span span;
|
||||||
|
private Scope scope;
|
||||||
|
|
||||||
public SpanWithScope getSpanWithScope() {
|
public void closeScope() {
|
||||||
return spanWithScope;
|
scope.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSpanWithScope(SpanWithScope spanWithScope) {
|
public Span getSpan() {
|
||||||
this.spanWithScope = spanWithScope;
|
return span;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set(Span span, Scope scope) {
|
||||||
|
this.span = span;
|
||||||
|
this.scope = scope;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
import static net.bytebuddy.matcher.ElementMatchers.returns;
|
||||||
|
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
@ -56,7 +55,7 @@ public class StreamTaskStartInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
Span span = tracer().startSpan(record);
|
Span span = tracer().startSpan(record);
|
||||||
|
|
||||||
holder.setSpanWithScope(new SpanWithScope(span, span.makeCurrent()));
|
holder.set(span, span.makeCurrent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@ import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||||
|
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
@ -49,11 +48,9 @@ public class StreamTaskStopInstrumentation implements TypeInstrumentation {
|
||||||
public static void stopSpan(
|
public static void stopSpan(
|
||||||
@Advice.Enter SpanScopeHolder holder, @Advice.Thrown Throwable throwable) {
|
@Advice.Enter SpanScopeHolder holder, @Advice.Thrown Throwable throwable) {
|
||||||
HOLDER.remove();
|
HOLDER.remove();
|
||||||
SpanWithScope spanWithScope = holder.getSpanWithScope();
|
Span span = holder.getSpan();
|
||||||
if (spanWithScope != null) {
|
if (span != null) {
|
||||||
spanWithScope.closeScope();
|
holder.closeScope();
|
||||||
|
|
||||||
Span span = spanWithScope.getSpan();
|
|
||||||
|
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
tracer().endExceptionally(span, throwable);
|
tracer().endExceptionally(span, throwable);
|
||||||
|
|
|
@ -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.CommandKeyword.SEGFAULT;
|
||||||
import static com.lambdaworks.redis.protocol.CommandType.DEBUG;
|
import static com.lambdaworks.redis.protocol.CommandType.DEBUG;
|
||||||
import static com.lambdaworks.redis.protocol.CommandType.SHUTDOWN;
|
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.AsyncCommand;
|
||||||
import com.lambdaworks.redis.protocol.CommandType;
|
import com.lambdaworks.redis.protocol.CommandType;
|
||||||
import com.lambdaworks.redis.protocol.ProtocolKeyword;
|
import com.lambdaworks.redis.protocol.ProtocolKeyword;
|
||||||
import com.lambdaworks.redis.protocol.RedisCommand;
|
import com.lambdaworks.redis.protocol.RedisCommand;
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CancellationException;
|
import java.util.concurrent.CancellationException;
|
||||||
|
@ -24,52 +23,30 @@ public final class InstrumentationPoints {
|
||||||
|
|
||||||
private static final Set<CommandType> NON_INSTRUMENTING_COMMANDS = EnumSet.of(SHUTDOWN, DEBUG);
|
private static final Set<CommandType> 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(
|
public static void afterCommand(
|
||||||
RedisCommand<?, ?, ?> command,
|
RedisCommand<?, ?, ?> command,
|
||||||
SpanWithScope spanWithScope,
|
Span span,
|
||||||
Throwable throwable,
|
Throwable throwable,
|
||||||
AsyncCommand<?, ?, ?> asyncCommand) {
|
AsyncCommand<?, ?, ?> asyncCommand) {
|
||||||
Span span = spanWithScope.getSpan();
|
|
||||||
if (throwable != null) {
|
if (throwable != null) {
|
||||||
LettuceDatabaseClientTracer.tracer().endExceptionally(span, throwable);
|
tracer().endExceptionally(span, throwable);
|
||||||
} else if (expectsResponse(command)) {
|
} else if (expectsResponse(command)) {
|
||||||
asyncCommand.handleAsync(
|
asyncCommand.handleAsync(
|
||||||
(value, ex) -> {
|
(value, ex) -> {
|
||||||
if (ex == null) {
|
if (ex == null) {
|
||||||
LettuceDatabaseClientTracer.tracer().end(span);
|
tracer().end(span);
|
||||||
} else if (ex instanceof CancellationException) {
|
} else if (ex instanceof CancellationException) {
|
||||||
span.setAttribute("lettuce.command.cancelled", true);
|
span.setAttribute("lettuce.command.cancelled", true);
|
||||||
LettuceDatabaseClientTracer.tracer().end(span);
|
tracer().end(span);
|
||||||
} else {
|
} else {
|
||||||
LettuceDatabaseClientTracer.tracer().endExceptionally(span, ex);
|
tracer().endExceptionally(span, ex);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// No response is expected, so we must finish the span now.
|
// 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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -5,24 +5,33 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.lettuce.v4_0;
|
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.AsyncCommand;
|
||||||
import com.lambdaworks.redis.protocol.RedisCommand;
|
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;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
|
||||||
public class LettuceAsyncCommandsAdvice {
|
public class LettuceAsyncCommandsAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope onEnter(@Advice.Argument(0) RedisCommand<?, ?, ?> command) {
|
public static void onEnter(
|
||||||
return InstrumentationPoints.beforeCommand(command);
|
@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)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void onExit(
|
public static void onExit(
|
||||||
@Advice.Argument(0) RedisCommand<?, ?, ?> command,
|
@Advice.Argument(0) RedisCommand<?, ?, ?> command,
|
||||||
@Advice.Enter SpanWithScope spanWithScope,
|
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Return AsyncCommand<?, ?, ?> asyncCommand) {
|
@Advice.Return AsyncCommand<?, ?, ?> asyncCommand,
|
||||||
InstrumentationPoints.afterCommand(command, spanWithScope, throwable, asyncCommand);
|
@Advice.Local("otelSpan") Span span,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
scope.close();
|
||||||
|
InstrumentationPoints.afterCommand(command, span, throwable, asyncCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,19 +5,34 @@
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.instrumentation.lettuce.v4_0;
|
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 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;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
|
||||||
public class RedisConnectionAdvice {
|
public class RedisConnectionAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope onEnter(@Advice.Argument(1) RedisURI redisUri) {
|
public static void onEnter(
|
||||||
return InstrumentationPoints.beforeConnect(redisUri);
|
@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)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void onExit(@Advice.Enter SpanWithScope scope, @Advice.Thrown Throwable throwable) {
|
public static void onExit(
|
||||||
InstrumentationPoints.afterConnect(scope, throwable);
|
@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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
import io.opentelemetry.api.trace.Span.Kind;
|
import io.opentelemetry.api.trace.Span.Kind;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
import play.api.mvc.Action;
|
import play.api.mvc.Action;
|
||||||
import play.api.mvc.Headers;
|
import play.api.mvc.Headers;
|
||||||
|
@ -20,30 +20,31 @@ import scala.concurrent.Future;
|
||||||
|
|
||||||
public class PlayAdvice {
|
public class PlayAdvice {
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope onEnter(@Advice.Argument(0) final Request<?> req) {
|
public static void onEnter(
|
||||||
Span span = tracer().startSpan("play.request", Kind.INTERNAL);
|
@Advice.Argument(0) final Request<?> req,
|
||||||
|
@Advice.Local("otelSpan") Span span,
|
||||||
return new SpanWithScope(span, span.makeCurrent());
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
span = tracer().startSpan("play.request", Kind.INTERNAL);
|
||||||
|
scope = span.makeCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void stopTraceOnResponse(
|
public static void stopTraceOnResponse(
|
||||||
@Advice.Enter SpanWithScope playControllerScope,
|
|
||||||
@Advice.This Object thisAction,
|
@Advice.This Object thisAction,
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Argument(0) Request<?> req,
|
@Advice.Argument(0) Request<?> req,
|
||||||
@Advice.Return(readOnly = false) Future<Result> responseFuture) {
|
@Advice.Return(readOnly = false) Future<Result> responseFuture,
|
||||||
Span playControllerSpan = playControllerScope.getSpan();
|
@Advice.Local("otelSpan") Span span,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
|
||||||
|
scope.close();
|
||||||
|
// span finished in RequestCompleteCallback
|
||||||
if (throwable == null) {
|
if (throwable == null) {
|
||||||
responseFuture.onComplete(
|
responseFuture.onComplete(
|
||||||
new RequestCompleteCallback(playControllerSpan),
|
new RequestCompleteCallback(span), ((Action<?>) thisAction).executionContext());
|
||||||
((Action<?>) thisAction).executionContext());
|
|
||||||
} else {
|
} 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
|
// set the span name on the upstream akka/netty span
|
||||||
tracer().updateSpanName(BaseTracer.getCurrentServerSpan(), req);
|
tracer().updateSpanName(BaseTracer.getCurrentServerSpan(), req);
|
||||||
|
|
|
@ -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;
|
||||||
import io.opentelemetry.api.trace.Span.Kind;
|
import io.opentelemetry.api.trace.Span.Kind;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
import play.api.mvc.Action;
|
import play.api.mvc.Action;
|
||||||
import play.api.mvc.Headers;
|
import play.api.mvc.Headers;
|
||||||
|
@ -20,36 +20,36 @@ import scala.concurrent.Future;
|
||||||
|
|
||||||
public class PlayAdvice {
|
public class PlayAdvice {
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope onEnter(@Advice.Argument(0) Request<?> req) {
|
public static void onEnter(
|
||||||
Span span = tracer().startSpan("play.request", Kind.INTERNAL);
|
@Advice.Argument(0) Request<?> req,
|
||||||
return new SpanWithScope(span, span.makeCurrent());
|
@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)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void stopTraceOnResponse(
|
public static void stopTraceOnResponse(
|
||||||
@Advice.Enter SpanWithScope playControllerScope,
|
|
||||||
@Advice.This Object thisAction,
|
@Advice.This Object thisAction,
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Argument(0) Request<?> req,
|
@Advice.Argument(0) Request<?> req,
|
||||||
@Advice.Return(readOnly = false) Future<Result> responseFuture) {
|
@Advice.Return(readOnly = false) Future<Result> responseFuture,
|
||||||
Span playControllerSpan = playControllerScope.getSpan();
|
@Advice.Local("otelSpan") Span span,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
// Call onRequest on return after tags are populated.
|
// 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) {
|
if (throwable == null) {
|
||||||
responseFuture.onComplete(
|
responseFuture.onComplete(
|
||||||
new RequestCompleteCallback(playControllerSpan),
|
new RequestCompleteCallback(span), ((Action<?>) thisAction).executionContext());
|
||||||
((Action<?>) thisAction).executionContext());
|
|
||||||
} else {
|
} 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
|
// set the span name on the upstream akka/netty span
|
||||||
tracer().updateSpanName(rootSpan, req);
|
tracer().updateSpanName(BaseTracer.getCurrentServerSpan(), req);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unused method for muzzle
|
// Unused method for muzzle
|
||||||
|
|
|
@ -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;
|
||||||
import io.opentelemetry.api.trace.Span.Kind;
|
import io.opentelemetry.api.trace.Span.Kind;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
import play.api.mvc.Action;
|
import play.api.mvc.Action;
|
||||||
import play.api.mvc.Request;
|
import play.api.mvc.Request;
|
||||||
|
@ -19,36 +19,35 @@ import scala.concurrent.Future;
|
||||||
|
|
||||||
public class PlayAdvice {
|
public class PlayAdvice {
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope onEnter(@Advice.Argument(0) Request<?> req) {
|
public static void onEnter(
|
||||||
Span span = tracer().startSpan("play.request", Kind.INTERNAL);
|
@Advice.Argument(0) Request<?> req,
|
||||||
|
@Advice.Local("otelSpan") Span span,
|
||||||
return new SpanWithScope(span, span.makeCurrent());
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
span = tracer().startSpan("play.request", Kind.INTERNAL);
|
||||||
|
scope = span.makeCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void stopTraceOnResponse(
|
public static void stopTraceOnResponse(
|
||||||
@Advice.Enter SpanWithScope playControllerScope,
|
|
||||||
@Advice.This Object thisAction,
|
@Advice.This Object thisAction,
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Argument(0) Request<?> req,
|
@Advice.Argument(0) Request<?> req,
|
||||||
@Advice.Return(readOnly = false) Future<Result> responseFuture) {
|
@Advice.Return(readOnly = false) Future<Result> responseFuture,
|
||||||
Span playControllerSpan = playControllerScope.getSpan();
|
@Advice.Local("otelSpan") Span span,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
// Call onRequest on return after tags are populated.
|
// 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) {
|
if (throwable == null) {
|
||||||
responseFuture.onComplete(
|
responseFuture.onComplete(
|
||||||
new RequestCompleteCallback(playControllerSpan),
|
new RequestCompleteCallback(span), ((Action<?>) thisAction).executionContext());
|
||||||
((Action<?>) thisAction).executionContext());
|
|
||||||
} else {
|
} 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
|
// set the span name on the upstream akka/netty span
|
||||||
tracer().updateSpanName(rootSpan, req);
|
tracer().updateSpanName(BaseTracer.getCurrentServerSpan(), req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@ import static io.opentelemetry.javaagent.instrumentation.spring.webflux.server.S
|
||||||
|
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.instrumentation.api.servlet.ServletContextPath;
|
import io.opentelemetry.instrumentation.api.servlet.ServletContextPath;
|
||||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
import org.springframework.web.method.HandlerMethod;
|
import org.springframework.web.method.HandlerMethod;
|
||||||
import org.springframework.web.reactive.HandlerMapping;
|
import org.springframework.web.reactive.HandlerMapping;
|
||||||
|
@ -21,10 +21,11 @@ import org.springframework.web.util.pattern.PathPattern;
|
||||||
public class HandlerAdapterAdvice {
|
public class HandlerAdapterAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope methodEnter(
|
public static void methodEnter(
|
||||||
@Advice.Argument(0) ServerWebExchange exchange, @Advice.Argument(1) Object handler) {
|
@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);
|
Context context = exchange.getAttribute(AdviceUtils.CONTEXT_ATTRIBUTE);
|
||||||
if (handler != null && context != null) {
|
if (handler != null && context != null) {
|
||||||
Span span = Span.fromContext(context);
|
Span span = Span.fromContext(context);
|
||||||
|
@ -44,7 +45,7 @@ public class HandlerAdapterAdvice {
|
||||||
span.updateName(operationName);
|
span.updateName(operationName);
|
||||||
span.setAttribute("spring-webflux.handler.type", handlerType);
|
span.setAttribute("spring-webflux.handler.type", handlerType);
|
||||||
|
|
||||||
spanWithScope = new SpanWithScope(span, context.makeCurrent());
|
scope = context.makeCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context != null) {
|
if (context != null) {
|
||||||
|
@ -56,20 +57,18 @@ public class HandlerAdapterAdvice {
|
||||||
ServletContextPath.prepend(Context.current(), bestPattern.toString()));
|
ServletContextPath.prepend(Context.current(), bestPattern.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return spanWithScope;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void methodExit(
|
public static void methodExit(
|
||||||
@Advice.Argument(0) ServerWebExchange exchange,
|
@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) {
|
if (throwable != null) {
|
||||||
AdviceUtils.finishSpanIfPresent(exchange, throwable);
|
AdviceUtils.finishSpanIfPresent(exchange, throwable);
|
||||||
}
|
}
|
||||||
if (spanWithScope != null) {
|
if (scope != null) {
|
||||||
spanWithScope.closeScope();
|
scope.close();
|
||||||
// span finished in SpanFinishingSubscriber
|
// span finished in SpanFinishingSubscriber
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,8 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
|
||||||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||||
|
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -84,21 +84,25 @@ public class DispatcherServletInstrumentation implements TypeInstrumentation {
|
||||||
public static class RenderAdvice {
|
public static class RenderAdvice {
|
||||||
|
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope onEnter(@Advice.Argument(0) ModelAndView mv) {
|
public static void onEnter(
|
||||||
Span span = tracer().startSpan(mv);
|
@Advice.Argument(0) ModelAndView mv,
|
||||||
return new SpanWithScope(span, span.makeCurrent());
|
@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)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void stopSpan(
|
public static void stopSpan(
|
||||||
@Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) {
|
@Advice.Thrown Throwable throwable,
|
||||||
Span span = spanWithScope.getSpan();
|
@Advice.Local("otelSpan") Span span,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
scope.close();
|
||||||
if (throwable == null) {
|
if (throwable == null) {
|
||||||
tracer().end(span);
|
tracer().end(span);
|
||||||
} else {
|
} else {
|
||||||
tracer().endExceptionally(span, throwable);
|
tracer().endExceptionally(span, throwable);
|
||||||
}
|
}
|
||||||
spanWithScope.closeScope();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,9 @@ import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||||
|
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
import io.opentelemetry.context.Context;
|
import io.opentelemetry.context.Context;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
import io.opentelemetry.instrumentation.api.tracer.BaseTracer;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
@ -54,35 +54,36 @@ public class HandlerAdapterInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
public static class ControllerAdvice {
|
public static class ControllerAdvice {
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope nameResourceAndStartSpan(
|
public static void nameResourceAndStartSpan(
|
||||||
@Advice.Argument(0) HttpServletRequest request, @Advice.Argument(2) Object handler) {
|
@Advice.Argument(0) HttpServletRequest request,
|
||||||
|
@Advice.Argument(2) Object handler,
|
||||||
|
@Advice.Local("otelSpan") Span span,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
Context context = Java8BytecodeBridge.currentContext();
|
Context context = Java8BytecodeBridge.currentContext();
|
||||||
Span serverSpan = BaseTracer.getCurrentServerSpan(context);
|
Span serverSpan = BaseTracer.getCurrentServerSpan(context);
|
||||||
if (serverSpan != null) {
|
if (serverSpan != null) {
|
||||||
// Name the parent span based on the matching pattern
|
// Name the parent span based on the matching pattern
|
||||||
tracer().onRequest(context, serverSpan, request);
|
tracer().onRequest(context, serverSpan, request);
|
||||||
// Now create a span for handler/controller execution.
|
// Now create a span for handler/controller execution.
|
||||||
Span span = tracer().startHandlerSpan(handler);
|
span = tracer().startHandlerSpan(handler);
|
||||||
|
scope = context.with(span).makeCurrent();
|
||||||
return new SpanWithScope(span, context.with(span).makeCurrent());
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void stopSpan(
|
public static void stopSpan(
|
||||||
@Advice.Enter SpanWithScope spanWithScope, @Advice.Thrown Throwable throwable) {
|
@Advice.Thrown Throwable throwable,
|
||||||
if (spanWithScope == null) {
|
@Advice.Local("otelSpan") Span span,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
if (scope == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Span span = spanWithScope.getSpan();
|
scope.close();
|
||||||
if (throwable == null) {
|
if (throwable == null) {
|
||||||
tracer().end(span);
|
tracer().end(span);
|
||||||
} else {
|
} else {
|
||||||
tracer().endExceptionally(span, throwable);
|
tracer().endExceptionally(span, throwable);
|
||||||
}
|
}
|
||||||
spanWithScope.closeScope();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,8 @@ import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.twilio.Twilio;
|
import com.twilio.Twilio;
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
|
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
@ -75,52 +75,48 @@ public class TwilioAsyncInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
/** Method entry instrumentation. */
|
/** Method entry instrumentation. */
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope methodEnter(
|
public static void methodEnter(
|
||||||
@Advice.This Object that, @Advice.Origin("#m") String methodName) {
|
@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
|
// 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
|
// 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
|
// starting. Our call depth checker does not span threads, so the async case is handled
|
||||||
// automatically for us.
|
// automatically for us.
|
||||||
int callDepth = CallDepthThreadLocalMap.incrementCallDepth(Twilio.class);
|
if (CallDepthThreadLocalMap.incrementCallDepth(Twilio.class) > 0) {
|
||||||
if (callDepth > 0) {
|
return;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't automatically close the span with the scope if we're executing an async method
|
// Don't automatically close the span with the scope if we're executing an async method
|
||||||
Span span = tracer().startSpan(that, methodName);
|
span = tracer().startSpan(that, methodName);
|
||||||
|
scope = tracer().startScope(span);
|
||||||
return new SpanWithScope(span, tracer().startScope(span));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Method exit instrumentation. */
|
/** Method exit instrumentation. */
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void methodExit(
|
public static void methodExit(
|
||||||
@Advice.Enter SpanWithScope spanWithScope,
|
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Return ListenableFuture<?> response) {
|
@Advice.Return ListenableFuture<?> response,
|
||||||
if (spanWithScope == null) {
|
@Advice.Local("otelSpan") Span span,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
if (scope == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CallDepthThreadLocalMap.reset(Twilio.class);
|
CallDepthThreadLocalMap.reset(Twilio.class);
|
||||||
|
|
||||||
// If we have a scope (i.e. we were the top-level Twilio SDK invocation),
|
// span finished in SpanFinishingCallback
|
||||||
try {
|
scope.close();
|
||||||
Span span = spanWithScope.getSpan();
|
if (throwable != null) {
|
||||||
|
// There was an synchronous error,
|
||||||
if (throwable != null) {
|
// which means we shouldn't wait for a callback to close the span.
|
||||||
// There was an synchronous error,
|
tracer().endExceptionally(span, throwable);
|
||||||
// which means we shouldn't wait for a callback to close the span.
|
} else {
|
||||||
tracer().endExceptionally(span, throwable);
|
// We're calling an async operation, we still need to finish the span when it's
|
||||||
} else {
|
// complete and report the results; set an appropriate callback
|
||||||
// We're calling an async operation, we still need to finish the span when it's
|
Futures.addCallback(
|
||||||
// complete and report the results; set an appropriate callback
|
response, new SpanFinishingCallback<>(span), Twilio.getExecutorService());
|
||||||
Futures.addCallback(
|
|
||||||
response, new SpanFinishingCallback<>(span), Twilio.getExecutorService());
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
spanWithScope.closeScope();
|
|
||||||
// span finished in SpanFinishingCallback
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
|
||||||
|
|
||||||
import com.twilio.Twilio;
|
import com.twilio.Twilio;
|
||||||
import io.opentelemetry.api.trace.Span;
|
import io.opentelemetry.api.trace.Span;
|
||||||
|
import io.opentelemetry.context.Scope;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
|
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
|
||||||
import io.opentelemetry.javaagent.instrumentation.api.SpanWithScope;
|
|
||||||
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import net.bytebuddy.asm.Advice;
|
import net.bytebuddy.asm.Advice;
|
||||||
|
@ -71,45 +71,41 @@ public class TwilioSyncInstrumentation implements TypeInstrumentation {
|
||||||
|
|
||||||
/** Method entry instrumentation. */
|
/** Method entry instrumentation. */
|
||||||
@Advice.OnMethodEnter(suppress = Throwable.class)
|
@Advice.OnMethodEnter(suppress = Throwable.class)
|
||||||
public static SpanWithScope methodEnter(
|
public static void methodEnter(
|
||||||
@Advice.This Object that, @Advice.Origin("#m") String methodName) {
|
@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
|
// 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
|
// 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
|
// starting. Our call depth checker does not span threads, so the async case is handled
|
||||||
// automatically for us.
|
// automatically for us.
|
||||||
int callDepth = CallDepthThreadLocalMap.incrementCallDepth(Twilio.class);
|
if (CallDepthThreadLocalMap.incrementCallDepth(Twilio.class) > 0) {
|
||||||
if (callDepth > 0) {
|
return;
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Span span = tracer().startSpan(that, methodName);
|
span = tracer().startSpan(that, methodName);
|
||||||
|
scope = tracer().startScope(span);
|
||||||
return new SpanWithScope(span, tracer().startScope(span));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Method exit instrumentation. */
|
/** Method exit instrumentation. */
|
||||||
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
@Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class)
|
||||||
public static void methodExit(
|
public static void methodExit(
|
||||||
@Advice.Enter SpanWithScope spanWithScope,
|
|
||||||
@Advice.Thrown Throwable throwable,
|
@Advice.Thrown Throwable throwable,
|
||||||
@Advice.Return Object response) {
|
@Advice.Return Object response,
|
||||||
if (spanWithScope == null) {
|
@Advice.Local("otelSpan") Span span,
|
||||||
|
@Advice.Local("otelScope") Scope scope) {
|
||||||
|
if (scope == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CallDepthThreadLocalMap.reset(Twilio.class);
|
CallDepthThreadLocalMap.reset(Twilio.class);
|
||||||
|
|
||||||
// If we have a scope (i.e. we were the top-level Twilio SDK invocation),
|
scope.close();
|
||||||
try {
|
if (throwable != null) {
|
||||||
Span span = spanWithScope.getSpan();
|
tracer().endExceptionally(span, throwable);
|
||||||
|
} else {
|
||||||
if (throwable != null) {
|
tracer().end(span, response);
|
||||||
tracer().endExceptionally(span, throwable);
|
|
||||||
} else {
|
|
||||||
tracer().end(span, response);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
spanWithScope.closeScope();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
|
||||||
*
|
|
||||||
* <p>Originally, we used {@code SpanWithScope} to pass the {@link Span} and {@link Scope} between
|
|
||||||
* {@code @Advice.OnMethodEnter} and {@code @Advice.OnMethodExit}, e.g.
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* @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();
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* <p>We are (slowly) migrating to a new pattern using `@Advice.Local`:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* @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();
|
|
||||||
* }
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* <p>This new pattern has the following benefits:
|
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li>The new pattern is more efficient since it doesn't require instantiating the {@code
|
|
||||||
* SpanWithScope} holder object
|
|
||||||
* <li>The new pattern extends nicely in the common case where we also need to pass {@link
|
|
||||||
* CallDepth} between the methods
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @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();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue