|
17 | 17 | import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; |
18 | 18 | import java.util.function.BiConsumer; |
19 | 19 | import net.bytebuddy.asm.Advice; |
| 20 | +import net.bytebuddy.asm.Advice.AssignReturned; |
| 21 | +import net.bytebuddy.asm.Advice.AssignReturned.ToArguments.ToArgument; |
20 | 22 | import net.bytebuddy.description.type.TypeDescription; |
21 | 23 | import net.bytebuddy.matcher.ElementMatcher; |
22 | 24 | import reactor.netty.Connection; |
@@ -74,92 +76,111 @@ public void transform(TypeTransformer transformer) { |
74 | 76 | public static class CreateAdvice { |
75 | 77 |
|
76 | 78 | @Advice.OnMethodEnter(suppress = Throwable.class) |
77 | | - public static void onEnter(@Advice.Local("otelCallDepth") CallDepth callDepth) { |
78 | | - callDepth = CallDepth.forClass(HttpClient.class); |
| 79 | + public static CallDepth onEnter() { |
| 80 | + CallDepth callDepth = CallDepth.forClass(HttpClient.class); |
79 | 81 | callDepth.getAndIncrement(); |
| 82 | + return callDepth; |
80 | 83 | } |
81 | 84 |
|
| 85 | + @AssignReturned.ToReturned |
82 | 86 | @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) |
83 | | - public static void stopSpan( |
| 87 | + public static HttpClient stopSpan( |
84 | 88 | @Advice.Thrown Throwable throwable, |
85 | | - @Advice.Return(readOnly = false) HttpClient client, |
86 | | - @Advice.Local("otelCallDepth") CallDepth callDepth) { |
| 89 | + @Advice.Return HttpClient client, |
| 90 | + @Advice.Enter CallDepth callDepth) { |
87 | 91 |
|
88 | 92 | if (callDepth.decrementAndGet() == 0 && throwable == null) { |
89 | | - client = client.doOnRequest(new OnRequest()).mapConnect(new MapConnect()); |
| 93 | + return client.doOnRequest(new OnRequest()).mapConnect(new MapConnect()); |
90 | 94 | } |
| 95 | + return client; |
91 | 96 | } |
92 | 97 | } |
93 | 98 |
|
94 | 99 | @SuppressWarnings("unused") |
95 | 100 | public static class OnRequestAdvice { |
96 | 101 |
|
| 102 | + @AssignReturned.ToArguments(@ToArgument(0)) |
97 | 103 | @Advice.OnMethodEnter(suppress = Throwable.class) |
98 | | - public static void onEnter( |
99 | | - @Advice.Argument(value = 0, readOnly = false) |
100 | | - BiConsumer<? super HttpClientRequest, ? super Connection> callback) { |
| 104 | + public static BiConsumer<? super HttpClientRequest, ? super Connection> onEnter( |
| 105 | + @Advice.Argument(0) BiConsumer<? super HttpClientRequest, ? super Connection> callback) { |
101 | 106 | if (DecoratorFunctions.shouldDecorate(callback.getClass())) { |
102 | | - callback = new DecoratorFunctions.OnRequestDecorator(callback); |
| 107 | + return new DecoratorFunctions.OnRequestDecorator(callback); |
103 | 108 | } |
| 109 | + return callback; |
104 | 110 | } |
105 | 111 | } |
106 | 112 |
|
107 | 113 | @SuppressWarnings("unused") |
108 | 114 | public static class OnRequestErrorAdvice { |
109 | 115 |
|
| 116 | + @AssignReturned.ToArguments(@ToArgument(0)) |
110 | 117 | @Advice.OnMethodEnter(suppress = Throwable.class) |
111 | | - public static void onEnter( |
112 | | - @Advice.Argument(value = 0, readOnly = false) |
113 | | - BiConsumer<? super HttpClientRequest, ? super Throwable> callback) { |
| 118 | + public static BiConsumer<? super HttpClientRequest, ? super Throwable> onEnter( |
| 119 | + @Advice.Argument(0) BiConsumer<? super HttpClientRequest, ? super Throwable> callback) { |
114 | 120 | if (DecoratorFunctions.shouldDecorate(callback.getClass())) { |
115 | | - callback = new DecoratorFunctions.OnRequestErrorDecorator(callback); |
| 121 | + return new DecoratorFunctions.OnRequestErrorDecorator(callback); |
116 | 122 | } |
| 123 | + return callback; |
117 | 124 | } |
118 | 125 | } |
119 | 126 |
|
120 | 127 | @SuppressWarnings("unused") |
121 | 128 | public static class OnResponseAdvice { |
122 | 129 |
|
| 130 | + @AssignReturned.ToArguments(@ToArgument(0)) |
123 | 131 | @Advice.OnMethodEnter(suppress = Throwable.class) |
124 | | - public static void onEnter( |
125 | | - @Advice.Argument(value = 0, readOnly = false) |
126 | | - BiConsumer<? super HttpClientResponse, ? super Connection> callback, |
| 132 | + public static BiConsumer<? super HttpClientResponse, ? super Connection> onEnter( |
| 133 | + @Advice.Argument(0) BiConsumer<? super HttpClientResponse, ? super Connection> callback, |
127 | 134 | @Advice.Origin("#m") String methodName) { |
128 | 135 | if (DecoratorFunctions.shouldDecorate(callback.getClass())) { |
129 | 136 | boolean forceParentContext = methodName.equals("doAfterResponse"); |
130 | | - callback = new DecoratorFunctions.OnResponseDecorator(callback, forceParentContext); |
| 137 | + return new DecoratorFunctions.OnResponseDecorator(callback, forceParentContext); |
131 | 138 | } |
| 139 | + return callback; |
132 | 140 | } |
133 | 141 | } |
134 | 142 |
|
135 | 143 | @SuppressWarnings("unused") |
136 | 144 | public static class OnResponseErrorAdvice { |
137 | 145 |
|
| 146 | + @AssignReturned.ToArguments(@ToArgument(0)) |
138 | 147 | @Advice.OnMethodEnter(suppress = Throwable.class) |
139 | | - public static void onEnter( |
140 | | - @Advice.Argument(value = 0, readOnly = false) |
141 | | - BiConsumer<? super HttpClientResponse, ? super Throwable> callback) { |
| 148 | + public static BiConsumer<? super HttpClientResponse, ? super Throwable> onEnter( |
| 149 | + @Advice.Argument(0) BiConsumer<? super HttpClientResponse, ? super Throwable> callback) { |
142 | 150 | if (DecoratorFunctions.shouldDecorate(callback.getClass())) { |
143 | | - callback = new DecoratorFunctions.OnResponseErrorDecorator(callback); |
| 151 | + return new DecoratorFunctions.OnResponseErrorDecorator(callback); |
144 | 152 | } |
| 153 | + return callback; |
145 | 154 | } |
146 | 155 | } |
147 | 156 |
|
148 | 157 | @SuppressWarnings("unused") |
149 | 158 | public static class OnErrorAdvice { |
150 | 159 |
|
| 160 | + @AssignReturned.ToArguments({ |
| 161 | + @ToArgument(value = 0, index = 0), |
| 162 | + @ToArgument(value = 1, index = 1) |
| 163 | + }) |
151 | 164 | @Advice.OnMethodEnter(suppress = Throwable.class) |
152 | | - public static void onEnter( |
153 | | - @Advice.Argument(value = 0, readOnly = false) |
154 | | - BiConsumer<? super HttpClientRequest, ? super Throwable> requestCallback, |
155 | | - @Advice.Argument(value = 1, readOnly = false) |
156 | | - BiConsumer<? super HttpClientResponse, ? super Throwable> responseCallback) { |
| 165 | + public static Object[] onEnter( |
| 166 | + @Advice.Argument(0) |
| 167 | + BiConsumer<? super HttpClientRequest, ? super Throwable> originalRequestCallback, |
| 168 | + @Advice.Argument(1) |
| 169 | + BiConsumer<? super HttpClientResponse, ? super Throwable> originalResponseCallback) { |
| 170 | + |
| 171 | + // intermediate variables needed for inlined instrumentation |
| 172 | + BiConsumer<? super HttpClientRequest, ? super Throwable> requestCallback = |
| 173 | + originalRequestCallback; |
| 174 | + BiConsumer<? super HttpClientResponse, ? super Throwable> responseCallback = |
| 175 | + originalResponseCallback; |
| 176 | + |
157 | 177 | if (DecoratorFunctions.shouldDecorate(requestCallback.getClass())) { |
158 | 178 | requestCallback = new DecoratorFunctions.OnRequestErrorDecorator(requestCallback); |
159 | 179 | } |
160 | 180 | if (DecoratorFunctions.shouldDecorate(responseCallback.getClass())) { |
161 | 181 | responseCallback = new DecoratorFunctions.OnResponseErrorDecorator(responseCallback); |
162 | 182 | } |
| 183 | + return new Object[] {requestCallback, responseCallback}; |
163 | 184 | } |
164 | 185 | } |
165 | 186 | } |
0 commit comments