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 .v3_0 .client .VertxClientSingletons .CONTEXTS ;
11+ import static io .opentelemetry .javaagent .instrumentation .vertx .v3_0 .client .VertxClientSingletons .REQUEST_INFO ;
1012import static io .opentelemetry .javaagent .instrumentation .vertx .v3_0 .client .VertxClientSingletons .instrumenter ;
1113import static net .bytebuddy .matcher .ElementMatchers .isMethod ;
1214import static net .bytebuddy .matcher .ElementMatchers .isPrivate ;
1618
1719import io .opentelemetry .context .Context ;
1820import io .opentelemetry .context .Scope ;
19- import io .opentelemetry .instrumentation .api .util .VirtualField ;
2021import io .opentelemetry .javaagent .bootstrap .Java8BytecodeBridge ;
2122import io .opentelemetry .javaagent .extension .instrumentation .TypeInstrumentation ;
2223import io .opentelemetry .javaagent .extension .instrumentation .TypeTransformer ;
2526import io .vertx .core .Handler ;
2627import io .vertx .core .http .HttpClientRequest ;
2728import io .vertx .core .http .HttpClientResponse ;
29+ import javax .annotation .Nullable ;
2830import net .bytebuddy .asm .Advice ;
31+ import net .bytebuddy .asm .Advice .AssignReturned ;
32+ import net .bytebuddy .asm .Advice .AssignReturned .ToArguments .ToArgument ;
2933import net .bytebuddy .description .type .TypeDescription ;
3034import net .bytebuddy .matcher .ElementMatcher ;
3135
@@ -83,67 +87,71 @@ public void transform(TypeTransformer transformer) {
8387 @ SuppressWarnings ("unused" )
8488 public static class EndRequestAdvice {
8589
86- @ Advice .OnMethodEnter (suppress = Throwable .class )
87- public static void attachContext (
88- @ Advice .This HttpClientRequest request ,
89- @ Advice .Local ("otelContext" ) Context context ,
90- @ Advice .Local ("otelScope" ) Scope scope ) {
90+ public static class AdviceScope {
91+ private final Context context ;
92+ private final Scope scope ;
93+
94+ public AdviceScope (Context context , Scope scope ) {
95+ this .context = context ;
96+ this .scope = scope ;
97+ }
98+
99+ public void end (@ Nullable Throwable throwable , HttpClientRequest request ) {
100+ scope .close ();
101+ if (throwable != null ) {
102+ instrumenter ().end (context , request , null , throwable );
103+ }
104+ }
105+ }
91106
92- VertxRequestInfo requestInfo =
93- VirtualField .find (HttpClientRequest .class , VertxRequestInfo .class ).get (request );
107+ @ Nullable
108+ @ Advice .OnMethodEnter (suppress = Throwable .class )
109+ public static AdviceScope attachContext (@ Advice .This HttpClientRequest request ) {
110+ VertxRequestInfo requestInfo = REQUEST_INFO .get (request );
94111 if (requestInfo == null ) {
95- return ;
112+ return null ;
96113 }
97114
98115 Context parentContext = Java8BytecodeBridge .currentContext ();
99116 if (!instrumenter ().shouldStart (parentContext , request )) {
100- return ;
117+ return null ;
101118 }
102-
103- context = instrumenter ().start (parentContext , request );
104- Contexts contexts = new Contexts (parentContext , context );
105- VirtualField .find (HttpClientRequest .class , Contexts .class ).set (request , contexts );
106-
107- scope = context .makeCurrent ();
119+ Context context = instrumenter ().start (parentContext , request );
120+ CONTEXTS .set (request , new Contexts (parentContext , context ));
121+ return new AdviceScope (context , context .makeCurrent ());
108122 }
109123
110124 @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class )
111125 public static void endScope (
112126 @ Advice .This HttpClientRequest request ,
113- @ Advice .Local ("otelContext" ) Context context ,
114- @ Advice .Local ("otelScope" ) Scope scope ,
115- @ Advice .Thrown Throwable throwable ) {
116- if (scope != null ) {
117- scope .close ();
118- }
119- if (throwable != null ) {
120- instrumenter ().end (context , request , null , throwable );
127+ @ Advice .Thrown @ Nullable Throwable throwable ,
128+ @ Advice .Enter @ Nullable AdviceScope adviceScope ) {
129+ if (adviceScope != null ) {
130+ adviceScope .end (throwable , request );
121131 }
122132 }
123133 }
124134
125135 @ SuppressWarnings ("unused" )
126136 public static class HandleExceptionAdvice {
127137
138+ @ Nullable
128139 @ Advice .OnMethodEnter (suppress = Throwable .class )
129- public static void handleException (
130- @ Advice .This HttpClientRequest request ,
131- @ Advice .Argument (0 ) Throwable t ,
132- @ Advice .Local ("otelScope" ) Scope scope ) {
133- 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 ) {
134142
143+ Contexts contexts = CONTEXTS .get (request );
135144 if (contexts == null ) {
136- return ;
145+ return null ;
137146 }
138-
139147 instrumenter ().end (contexts .context , request , null , t );
140148
141149 // Scoping all potential callbacks etc to the parent context
142- scope = contexts .parentContext .makeCurrent ();
150+ return contexts .parentContext .makeCurrent ();
143151 }
144152
145153 @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class )
146- public static void handleResponseExit (@ Advice .Local ( "otelScope" ) Scope scope ) {
154+ public static void handleResponseExit (@ Advice .Enter @ Nullable Scope scope ) {
147155 if (scope != null ) {
148156 scope .close ();
149157 }
@@ -153,25 +161,23 @@ public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) {
153161 @ SuppressWarnings ("unused" )
154162 public static class HandleResponseAdvice {
155163
164+ @ Nullable
156165 @ Advice .OnMethodEnter (suppress = Throwable .class )
157- public static void handleResponseEnter (
158- @ Advice .This HttpClientRequest request ,
159- @ Advice .Argument (0 ) HttpClientResponse response ,
160- @ Advice .Local ("otelScope" ) Scope scope ) {
161- Contexts contexts = VirtualField .find (HttpClientRequest .class , Contexts .class ).get (request );
166+ public static Scope handleResponseEnter (
167+ @ Advice .This HttpClientRequest request , @ Advice .Argument (0 ) HttpClientResponse response ) {
162168
169+ Contexts contexts = CONTEXTS .get (request );
163170 if (contexts == null ) {
164- return ;
171+ return null ;
165172 }
166-
167173 instrumenter ().end (contexts .context , request , response , null );
168174
169175 // Scoping all potential callbacks etc to the parent context
170- scope = contexts .parentContext .makeCurrent ();
176+ return contexts .parentContext .makeCurrent ();
171177 }
172178
173179 @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class )
174- public static void handleResponseExit (@ Advice .Local ( "otelScope" ) Scope scope ) {
180+ public static void handleResponseExit (@ Advice .Enter @ Nullable Scope scope ) {
175181 if (scope != null ) {
176182 scope .close ();
177183 }
@@ -181,19 +187,18 @@ public static void handleResponseExit(@Advice.Local("otelScope") Scope scope) {
181187 @ SuppressWarnings ("unused" )
182188 public static class MountContextAdvice {
183189
190+ @ Nullable
184191 @ Advice .OnMethodEnter (suppress = Throwable .class )
185- public static void mountContext (
186- @ Advice .This HttpClientRequest request , @ Advice .Local ("otelScope" ) Scope scope ) {
187- Contexts contexts = VirtualField .find (HttpClientRequest .class , Contexts .class ).get (request );
192+ public static Scope mountContext (@ Advice .This HttpClientRequest request ) {
193+ Contexts contexts = CONTEXTS .get (request );
188194 if (contexts == null ) {
189- return ;
195+ return null ;
190196 }
191-
192- scope = contexts .context .makeCurrent ();
197+ return contexts .context .makeCurrent ();
193198 }
194199
195200 @ Advice .OnMethodExit (onThrowable = Throwable .class , suppress = Throwable .class )
196- public static void unmountContext (@ Advice .Local ( "otelScope" ) Scope scope ) {
201+ public static void unmountContext (@ Advice .Enter @ Nullable Scope scope ) {
197202 if (scope != null ) {
198203 scope .close ();
199204 }
@@ -203,15 +208,16 @@ public static void unmountContext(@Advice.Local("otelScope") Scope scope) {
203208 @ SuppressWarnings ("unused" )
204209 public static class ExceptionHandlerAdvice {
205210
211+ @ Nullable
212+ @ AssignReturned .ToArguments (@ ToArgument (0 ))
206213 @ Advice .OnMethodEnter (suppress = Throwable .class )
207- public static void wrapExceptionHandler (
214+ public static Handler < Throwable > wrapExceptionHandler (
208215 @ Advice .This HttpClientRequest request ,
209- @ Advice .Argument (value = 0 , readOnly = false ) Handler <Throwable > handler ) {
210- if (handler != null ) {
211- VirtualField <HttpClientRequest , Contexts > virtualField =
212- VirtualField .find (HttpClientRequest .class , Contexts .class );
213- handler = ExceptionHandlerWrapper .wrap (instrumenter (), request , virtualField , handler );
216+ @ Advice .Argument (0 ) @ Nullable Handler <Throwable > handler ) {
217+ if (handler == null ) {
218+ return null ;
214219 }
220+ return ExceptionHandlerWrapper .wrap (instrumenter (), request , CONTEXTS , handler );
215221 }
216222 }
217223}
0 commit comments