1010import static net .bytebuddy .matcher .ElementMatchers .named ;
1111import static net .bytebuddy .matcher .ElementMatchers .returns ;
1212
13+ import io .opentelemetry .api .trace .Span ;
1314import io .opentelemetry .context .Context ;
1415import io .opentelemetry .context .Scope ;
1516import io .opentelemetry .instrumentation .jdbc .internal .JdbcUtils ;
1617import io .opentelemetry .javaagent .bootstrap .CallDepth ;
17- import io .opentelemetry .javaagent .bootstrap .Java8BytecodeBridge ;
1818import io .opentelemetry .javaagent .bootstrap .jdbc .DbInfo ;
1919import io .opentelemetry .javaagent .extension .instrumentation .TypeInstrumentation ;
2020import io .opentelemetry .javaagent .extension .instrumentation .TypeTransformer ;
2121import java .sql .Connection ;
22+ import javax .annotation .Nullable ;
2223import javax .sql .DataSource ;
2324import net .bytebuddy .asm .Advice ;
2425import net .bytebuddy .description .type .TypeDescription ;
@@ -41,52 +42,68 @@ public void transform(TypeTransformer transformer) {
4142 @ SuppressWarnings ("unused" )
4243 public static class GetConnectionAdvice {
4344
44- @ Advice . OnMethodEnter ( suppress = Throwable . class )
45- public static void start (
46- @ Advice . This DataSource ds ,
47- @ Advice . Local ( "otelContext" ) Context context ,
48- @ Advice . Local ( "otelScope" ) Scope scope ,
49- @ Advice . Local ( "otelCallDepth" ) CallDepth callDepth ) {
50- callDepth = CallDepth . forClass ( DataSource . class ) ;
51- if ( callDepth . getAndIncrement () > 0 ) {
52- return ;
45+ public static class AdviceScope {
46+ private final CallDepth callDepth ;
47+ private final Context context ;
48+ private final Scope scope ;
49+
50+ private AdviceScope ( CallDepth callDepth , Context context , Scope scope ) {
51+ this . callDepth = callDepth ;
52+ this . context = context ;
53+ this . scope = scope ;
5354 }
5455
55- Context parentContext = Java8BytecodeBridge .currentContext ();
56- if (!Java8BytecodeBridge .spanFromContext (parentContext ).getSpanContext ().isValid ()) {
57- // this instrumentation is already very noisy, and calls to getConnection outside of an
58- // existing trace do not tend to be very interesting
59- return ;
56+ public static AdviceScope start (DataSource ds ) {
57+ CallDepth callDepth = CallDepth .forClass (DataSource .class );
58+ if (callDepth .getAndIncrement () > 0 ) {
59+ return new AdviceScope (callDepth , null , null );
60+ }
61+
62+ Context parentContext = Context .current ();
63+ if (!Span .fromContext (parentContext ).getSpanContext ().isValid ()) {
64+ // this instrumentation is already very noisy, and calls to getConnection outside of an
65+ // existing trace do not tend to be very interesting
66+ return new AdviceScope (callDepth , null , null );
67+ }
68+
69+ if (!dataSourceInstrumenter ().shouldStart (parentContext , ds )) {
70+ return new AdviceScope (callDepth , null , null );
71+ }
72+
73+ Context context = dataSourceInstrumenter ().start (parentContext , ds );
74+
75+ return new AdviceScope (callDepth , context , context .makeCurrent ());
6076 }
6177
62- if (dataSourceInstrumenter ().shouldStart (parentContext , ds )) {
63- context = dataSourceInstrumenter ().start (parentContext , ds );
64- scope = context .makeCurrent ();
78+ public void end (@ Nullable Throwable throwable , DataSource ds , Connection connection ) {
79+ if (callDepth .decrementAndGet () > 0 ) {
80+ return ;
81+ }
82+ if (scope == null ) {
83+ return ;
84+ }
85+ scope .close ();
86+ DbInfo dbInfo = null ;
87+ Connection realConnection = JdbcUtils .unwrapConnection (connection );
88+ if (realConnection != null ) {
89+ dbInfo = JdbcUtils .extractDbInfo (realConnection );
90+ }
91+ dataSourceInstrumenter ().end (context , ds , dbInfo , throwable );
6592 }
6693 }
6794
95+ @ Advice .OnMethodEnter (suppress = Throwable .class )
96+ public static AdviceScope start (@ Advice .This DataSource ds ) {
97+ return AdviceScope .start (ds );
98+ }
99+
68100 @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class )
69101 public static void stopSpan (
70102 @ Advice .This DataSource ds ,
71- @ Advice .Return Connection connection ,
72- @ Advice .Thrown Throwable throwable ,
73- @ Advice .Local ("otelContext" ) Context context ,
74- @ Advice .Local ("otelScope" ) Scope scope ,
75- @ Advice .Local ("otelCallDepth" ) CallDepth callDepth ) {
76- if (callDepth .decrementAndGet () > 0 ) {
77- return ;
78- }
79-
80- if (scope == null ) {
81- return ;
82- }
83- scope .close ();
84- DbInfo dbInfo = null ;
85- Connection realConnection = JdbcUtils .unwrapConnection (connection );
86- if (realConnection != null ) {
87- dbInfo = JdbcUtils .extractDbInfo (realConnection );
88- }
89- dataSourceInstrumenter ().end (context , ds , dbInfo , throwable );
103+ @ Advice .Return @ Nullable Connection connection ,
104+ @ Advice .Thrown @ Nullable Throwable throwable ,
105+ @ Advice .Enter AdviceScope adviceScope ) {
106+ adviceScope .end (throwable , ds , connection );
90107 }
91108 }
92109}
0 commit comments