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 .v4_0 .client .VertxClientSingletons .CONTEXTS ;
1011import static io .opentelemetry .javaagent .instrumentation .vertx .v4_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,61 +88,71 @@ public void transform(TypeTransformer transformer) {
8588 @ SuppressWarnings ("unused" )
8689 public static class EndRequestAdvice {
8790
91+ public static class AdviceScope {
92+ public final Context context ;
93+ public final Scope scope ;
94+
95+ public AdviceScope (Context context , Scope scope ) {
96+ this .context = context ;
97+ this .scope = scope ;
98+ }
99+
100+ public void end (HttpClientRequest request , Throwable throwable ) {
101+ scope .close ();
102+ if (throwable != null ) {
103+ instrumenter ().end (context , request , null , throwable );
104+ }
105+ }
106+ }
107+
108+ @ Nullable
88109 @ 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 ();
110+ public static AdviceScope attachContext (@ Advice .This HttpClientRequest request ) {
94111
112+ Context parentContext = Java8BytecodeBridge .currentContext ();
95113 if (!instrumenter ().shouldStart (parentContext , request )) {
96- return ;
114+ return null ;
97115 }
98116
99- context = instrumenter ().start (parentContext , request );
117+ Context context = instrumenter ().start (parentContext , request );
100118 Contexts contexts = new Contexts (parentContext , context );
101- VirtualField . find ( HttpClientRequest . class , Contexts . class ) .set (request , contexts );
119+ CONTEXTS .set (request , contexts );
102120
103- scope = context .makeCurrent ();
121+ return new AdviceScope ( context , context .makeCurrent () );
104122 }
105123
106124 @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class )
107125 public static void endScope (
108126 @ 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 );
127+ @ Advice .Thrown Throwable throwable ,
128+ @ Advice .Enter @ Nullable AdviceScope adviceScope ) {
129+ if (adviceScope != null ) {
130+ adviceScope .end (request , throwable );
117131 }
118132 }
119133 }
120134
121135 @ SuppressWarnings ("unused" )
122136 public static class HandleExceptionAdvice {
123137
138+ @ Nullable
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 );
140+ public static Scope handleException (
141+ @ Advice .This HttpClientRequest request , @ Advice .Argument (0 ) Throwable t ) {
142+ Contexts contexts = CONTEXTS .get (request );
130143
131144 if (contexts == null ) {
132- return ;
145+ return null ;
133146 }
134147
135148 instrumenter ().end (contexts .context , request , null , t );
136149
137150 // Scoping all potential callbacks etc to the parent context
138- scope = contexts .parentContext .makeCurrent ();
151+ return contexts .parentContext .makeCurrent ();
139152 }
140153
141154 @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class )
142- public static void handleResponseExit (@ Advice .Local ( "otelScope" ) Scope scope ) {
155+ public static void handleResponseExit (@ Advice .Enter @ Nullable Scope scope ) {
143156 if (scope != null ) {
144157 scope .close ();
145158 }
@@ -149,25 +162,24 @@ public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) {
149162 @ SuppressWarnings ("unused" )
150163 public static class HandleResponseAdvice {
151164
165+ @ Nullable
152166 @ 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 );
167+ public static Scope handleResponseEnter (
168+ @ Advice .This HttpClientRequest request , @ Advice .Argument (1 ) HttpClientResponse response ) {
169+ Contexts contexts = CONTEXTS .get (request );
158170
159171 if (contexts == null ) {
160- return ;
172+ return null ;
161173 }
162174
163175 instrumenter ().end (contexts .context , request , response , null );
164176
165177 // Scoping all potential callbacks etc to the parent context
166- scope = contexts .parentContext .makeCurrent ();
178+ return contexts .parentContext .makeCurrent ();
167179 }
168180
169181 @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class )
170- public static void handleResponseExit (@ Advice .Local ( "otelScope" ) Scope scope ) {
182+ public static void handleResponseExit (@ Advice .Enter @ Nullable Scope scope ) {
171183 if (scope != null ) {
172184 scope .close ();
173185 }
@@ -177,19 +189,19 @@ public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) {
177189 @ SuppressWarnings ("unused" )
178190 public static class MountContextAdvice {
179191
192+ @ Nullable
180193 @ 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 );
194+ public static Scope mountContext (@ Advice .This HttpClientRequest request ) {
195+ Contexts contexts = CONTEXTS .get (request );
184196 if (contexts == null ) {
185- return ;
197+ return null ;
186198 }
187199
188- scope = contexts .context .makeCurrent ();
200+ return contexts .context .makeCurrent ();
189201 }
190202
191203 @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class )
192- public static void unmountContext (@ Advice .Local ( "otelScope" ) Scope scope ) {
204+ public static void unmountContext (@ Advice .Enter @ Nullable Scope scope ) {
193205 if (scope != null ) {
194206 scope .close ();
195207 }
@@ -199,15 +211,16 @@ public static void unmountContext(@Advice.Local("otelScope") Scope scope) {
199211 @ SuppressWarnings ("unused" )
200212 public static class ExceptionHandlerAdvice {
201213
214+ @ Nullable
215+ @ AssignReturned .ToArguments (@ ToArgument (0 ))
202216 @ Advice .OnMethodEnter (suppress = Throwable .class )
203- public static void wrapExceptionHandler (
217+ public static Handler < Throwable > wrapExceptionHandler (
204218 @ Advice .This HttpClientRequest request ,
205- @ Advice .Argument (value = 0 , readOnly = false ) Handler <Throwable > handler ) {
206- if (handler != null ) {
207- VirtualField <HttpClientRequest , Contexts > virtualField =
208- VirtualField .find (HttpClientRequest .class , Contexts .class );
209- handler = ExceptionHandlerWrapper .wrap (instrumenter (), request , virtualField , handler );
219+ @ Advice .Argument (0 ) @ Nullable Handler <Throwable > handler ) {
220+ if (handler == null ) {
221+ return null ;
210222 }
223+ return ExceptionHandlerWrapper .wrap (instrumenter (), request , CONTEXTS , handler );
211224 }
212225 }
213226}
0 commit comments