77
88import static io .opentelemetry .javaagent .extension .matcher .AgentElementMatchers .hasClassesNamed ;
99import static io .opentelemetry .javaagent .extension .matcher .AgentElementMatchers .implementsInterface ;
10+ import static io .opentelemetry .javaagent .instrumentation .vertx .v5_0 .client .VertxClientSingletons .CONTEXTS ;
1011import static io .opentelemetry .javaagent .instrumentation .vertx .v5_0 .client .VertxClientSingletons .instrumenter ;
1112import static net .bytebuddy .matcher .ElementMatchers .isMethod ;
1213import static net .bytebuddy .matcher .ElementMatchers .isPrivate ;
1617
1718import io .opentelemetry .context .Context ;
1819import io .opentelemetry .context .Scope ;
19- import io .opentelemetry .instrumentation .api .util .VirtualField ;
2020import io .opentelemetry .javaagent .bootstrap .Java8BytecodeBridge ;
2121import io .opentelemetry .javaagent .extension .instrumentation .TypeInstrumentation ;
2222import io .opentelemetry .javaagent .extension .instrumentation .TypeTransformer ;
2525import io .vertx .core .Handler ;
2626import io .vertx .core .http .HttpClientRequest ;
2727import io .vertx .core .http .HttpClientResponse ;
28+ import javax .annotation .Nullable ;
2829import net .bytebuddy .asm .Advice ;
30+ import net .bytebuddy .asm .Advice .AssignReturned ;
31+ import net .bytebuddy .asm .Advice .AssignReturned .ToArguments .ToArgument ;
2932import net .bytebuddy .description .type .TypeDescription ;
3033import net .bytebuddy .matcher .ElementMatcher ;
3134
@@ -85,35 +88,47 @@ public void transform(TypeTransformer transformer) {
8588 @ SuppressWarnings ("unused" )
8689 public static class EndRequestAdvice {
8790
88- @ Advice .OnMethodEnter (suppress = Throwable .class )
89- public static void attachContext (
90- @ Advice .This HttpClientRequest request ,
91- @ Advice .Local ("otelContext" ) Context context ,
92- @ Advice .Local ("otelScope" ) Scope scope ) {
93- Context parentContext = Java8BytecodeBridge .currentContext ();
91+ public static class AdviceScope {
92+ private final Context context ;
93+ private final Scope scope ;
94+
95+ private AdviceScope (Context context , Scope scope ) {
96+ this .context = context ;
97+ this .scope = scope ;
98+ }
9499
95- if (!instrumenter ().shouldStart (parentContext , request )) {
96- return ;
100+ @ Nullable
101+ public static AdviceScope startAndAttachContext (HttpClientRequest request ) {
102+ Context parentContext = Java8BytecodeBridge .currentContext ();
103+ if (!instrumenter ().shouldStart (parentContext , request )) {
104+ return null ;
105+ }
106+ Context context = instrumenter ().start (parentContext , request );
107+ CONTEXTS .set (request , new Contexts (parentContext , context ));
108+ return new AdviceScope (context , context .makeCurrent ());
97109 }
98110
99- context = instrumenter ().start (parentContext , request );
100- Contexts contexts = new Contexts (parentContext , context );
101- VirtualField .find (HttpClientRequest .class , Contexts .class ).set (request , contexts );
111+ public void end (HttpClientRequest request , @ Nullable Throwable throwable ) {
112+ scope .close ();
113+ if (throwable != null ) {
114+ instrumenter ().end (context , request , null , throwable );
115+ }
116+ }
117+ }
102118
103- scope = context .makeCurrent ();
119+ @ Nullable
120+ @ Advice .OnMethodEnter (suppress = Throwable .class )
121+ public static AdviceScope attachContext (@ Advice .This HttpClientRequest request ) {
122+ return AdviceScope .startAndAttachContext (request );
104123 }
105124
106125 @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class )
107126 public static void endScope (
108127 @ Advice .This HttpClientRequest request ,
109- @ Advice .Local ("otelContext" ) Context context ,
110- @ Advice .Local ("otelScope" ) Scope scope ,
111- @ Advice .Thrown Throwable throwable ) {
112- if (scope != null ) {
113- scope .close ();
114- }
115- if (throwable != null ) {
116- instrumenter ().end (context , request , null , throwable );
128+ @ Advice .Thrown @ Nullable Throwable throwable ,
129+ @ Advice .Enter @ Nullable AdviceScope adviceScope ) {
130+ if (adviceScope != null ) {
131+ adviceScope .end (request , throwable );
117132 }
118133 }
119134 }
@@ -122,24 +137,21 @@ public static void endScope(
122137 public static class HandleExceptionAdvice {
123138
124139 @ Advice .OnMethodEnter (suppress = Throwable .class )
125- public static void handleException (
126- @ Advice .This HttpClientRequest request ,
127- @ Advice .Argument (0 ) Throwable t ,
128- @ Advice .Local ("otelScope" ) Scope scope ) {
129- Contexts contexts = VirtualField .find (HttpClientRequest .class , Contexts .class ).get (request );
130-
140+ public static Scope handleException (
141+ @ Advice .This HttpClientRequest request , @ Advice .Argument (0 ) Throwable t ) {
142+ Contexts contexts = CONTEXTS .get (request );
131143 if (contexts == null ) {
132- return ;
144+ return null ;
133145 }
134146
135147 instrumenter ().end (contexts .context , request , null , t );
136148
137149 // Scoping all potential callbacks etc to the parent context
138- scope = contexts .parentContext .makeCurrent ();
150+ return contexts .parentContext .makeCurrent ();
139151 }
140152
141153 @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class )
142- public static void handleResponseExit (@ Advice .Local ( "otelScope" ) Scope scope ) {
154+ public static void handleResponseExit (@ Advice .Enter Scope scope ) {
143155 if (scope != null ) {
144156 scope .close ();
145157 }
@@ -150,24 +162,22 @@ public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) {
150162 public static class HandleResponseAdvice {
151163
152164 @ Advice .OnMethodEnter (suppress = Throwable .class )
153- public static void handleResponseEnter (
154- @ Advice .This HttpClientRequest request ,
155- @ Advice .Argument (1 ) HttpClientResponse response ,
156- @ Advice .Local ("otelScope" ) Scope scope ) {
157- Contexts contexts = VirtualField .find (HttpClientRequest .class , Contexts .class ).get (request );
165+ public static Scope handleResponseEnter (
166+ @ Advice .This HttpClientRequest request , @ Advice .Argument (1 ) HttpClientResponse response ) {
167+ Contexts contexts = CONTEXTS .get (request );
158168
159169 if (contexts == null ) {
160- return ;
170+ return null ;
161171 }
162172
163173 instrumenter ().end (contexts .context , request , response , null );
164174
165175 // Scoping all potential callbacks etc to the parent context
166- scope = contexts .parentContext .makeCurrent ();
176+ return contexts .parentContext .makeCurrent ();
167177 }
168178
169179 @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class )
170- public static void handleResponseExit (@ Advice .Local ( "otelScope" ) Scope scope ) {
180+ public static void handleResponseExit (@ Advice .Enter Scope scope ) {
171181 if (scope != null ) {
172182 scope .close ();
173183 }
@@ -178,18 +188,17 @@ public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) {
178188 public static class MountContextAdvice {
179189
180190 @ Advice .OnMethodEnter (suppress = Throwable .class )
181- public static void mountContext (
182- @ Advice .This HttpClientRequest request , @ Advice .Local ("otelScope" ) Scope scope ) {
183- Contexts contexts = VirtualField .find (HttpClientRequest .class , Contexts .class ).get (request );
191+ public static Scope mountContext (@ Advice .This HttpClientRequest request ) {
192+ Contexts contexts = CONTEXTS .get (request );
184193 if (contexts == null ) {
185- return ;
194+ return null ;
186195 }
187196
188- scope = contexts .context .makeCurrent ();
197+ return contexts .context .makeCurrent ();
189198 }
190199
191200 @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class )
192- public static void unmountContext (@ Advice .Local ( "otelScope" ) Scope scope ) {
201+ public static void unmountContext (@ Advice .Enter Scope scope ) {
193202 if (scope != null ) {
194203 scope .close ();
195204 }
@@ -199,15 +208,16 @@ public static void unmountContext(@Advice.Local("otelScope") Scope scope) {
199208 @ SuppressWarnings ("unused" )
200209 public static class ExceptionHandlerAdvice {
201210
211+ @ AssignReturned .ToArguments (@ ToArgument (0 ))
202212 @ Advice .OnMethodEnter (suppress = Throwable .class )
203- public static void wrapExceptionHandler (
213+ public static Handler < Throwable > wrapExceptionHandler (
204214 @ Advice .This HttpClientRequest request ,
205- @ Advice .Argument (value = 0 , readOnly = false ) Handler <Throwable > handler ) {
215+ @ Advice .Argument (0 ) Handler <Throwable > originalHandler ) {
216+ Handler <Throwable > handler = originalHandler ;
206217 if (handler != null ) {
207- VirtualField <HttpClientRequest , Contexts > virtualField =
208- VirtualField .find (HttpClientRequest .class , Contexts .class );
209- handler = ExceptionHandlerWrapper .wrap (instrumenter (), request , virtualField , handler );
218+ handler = ExceptionHandlerWrapper .wrap (instrumenter (), request , CONTEXTS , handler );
210219 }
220+ return handler ;
211221 }
212222 }
213223}
0 commit comments