2727
2828import com .google .auto .service .AutoService ;
2929import io .opentelemetry .javaagent .instrumentation .api .CallDepthThreadLocalMap ;
30+ import io .opentelemetry .javaagent .instrumentation .api .ContextStore ;
31+ import io .opentelemetry .javaagent .instrumentation .api .InstrumentationContext ;
3032import io .opentelemetry .javaagent .tooling .InstrumentationModule ;
3133import io .opentelemetry .javaagent .tooling .TypeInstrumentation ;
3234import java .io .IOException ;
3941import net .bytebuddy .description .method .MethodDescription ;
4042import net .bytebuddy .description .type .TypeDescription ;
4143import net .bytebuddy .matcher .ElementMatcher ;
42- import org .hypertrace .agent .core .instrumentation .GlobalObjectRegistry ;
43- import org .hypertrace .agent .core .instrumentation .GlobalObjectRegistry .SpanAndBuffer ;
44+ import org .hypertrace .agent .core .instrumentation .SpanAndBuffer ;
4445
4546/**
4647 * {@link InputStream} instrumentation. The type matcher applies to all implementations. However
47- * only streams that are in the {@link GlobalObjectRegistry#inputStreamToSpanAndBufferMap } are
48- * instrumented, otherwise the instrumentation is noop.
48+ * only streams that are in the {@link ContextStore } are instrumented, otherwise the instrumentation
49+ * is noop.
4950 *
50- * <p>If the stream is in the {@link GlobalObjectRegistry#inputStreamToSpanAndBufferMap } then result
51- * of read methods is also passed to the buffered stream (value) from the map. The instrumentation
52- * adds buffer to span from the map when read is finished (return -1), creates new span with buffer
53- * when the original span is not recording.
51+ * <p>If the stream is in the {@link ContextStore } then result of read methods is also passed to the
52+ * buffered stream (value) from the map. The instrumentation adds buffer to span from the map when
53+ * read is finished (return -1), creates new span with buffer when the original span is not
54+ * recording.
5455 *
5556 * <p>Maybe we could add optimization to instrument the input streams only when certain classes are
5657 * present in classloader e.g. classes from frameworks that we instrument.
@@ -117,7 +118,8 @@ public Map<? extends ElementMatcher<? super MethodDescription>, String> transfor
117118 public static class InputStream_ReadNoArgsAdvice {
118119 @ Advice .OnMethodEnter (suppress = Throwable .class )
119120 public static SpanAndBuffer enter (@ Advice .This InputStream thizz ) {
120- return InputStreamUtils .check (thizz );
121+ return InputStreamUtils .check (
122+ thizz , InstrumentationContext .get (InputStream .class , SpanAndBuffer .class ));
121123 }
122124
123125 @ Advice .OnMethodExit (suppress = Throwable .class , onThrowable = Throwable .class )
@@ -133,14 +135,19 @@ public static void exit(
133135 return ;
134136 }
135137
136- InputStreamUtils .read (thizz , spanAndBuffer , read );
138+ InputStreamUtils .read (
139+ thizz ,
140+ spanAndBuffer ,
141+ InstrumentationContext .get (InputStream .class , SpanAndBuffer .class ),
142+ read );
137143 }
138144 }
139145
140146 public static class InputStream_ReadByteArrayAdvice {
141147 @ Advice .OnMethodEnter (suppress = Throwable .class )
142148 public static SpanAndBuffer enter (@ Advice .This InputStream thizz ) {
143- return InputStreamUtils .check (thizz );
149+ return InputStreamUtils .check (
150+ thizz , InstrumentationContext .get (InputStream .class , SpanAndBuffer .class ));
144151 }
145152
146153 @ Advice .OnMethodExit (suppress = Throwable .class , onThrowable = Throwable .class )
@@ -164,7 +171,8 @@ public static void exit(
164171 public static class InputStream_ReadByteArrayOffsetAdvice {
165172 @ Advice .OnMethodEnter (suppress = Throwable .class )
166173 public static SpanAndBuffer enter (@ Advice .This InputStream thizz ) {
167- return InputStreamUtils .check (thizz );
174+ return InputStreamUtils .check (
175+ thizz , InstrumentationContext .get (InputStream .class , SpanAndBuffer .class ));
168176 }
169177
170178 @ Advice .OnMethodExit (suppress = Throwable .class , onThrowable = Throwable .class )
@@ -183,14 +191,22 @@ public static void exit(
183191 return ;
184192 }
185193
186- InputStreamUtils .read (thizz , spanAndBuffer , read , b , off , len );
194+ InputStreamUtils .read (
195+ thizz ,
196+ spanAndBuffer ,
197+ InstrumentationContext .get (InputStream .class , SpanAndBuffer .class ),
198+ read ,
199+ b ,
200+ off ,
201+ len );
187202 }
188203 }
189204
190205 public static class InputStream_ReadAllBytes {
191206 @ Advice .OnMethodEnter (suppress = Throwable .class )
192207 public static SpanAndBuffer enter (@ Advice .This InputStream thizz ) {
193- return InputStreamUtils .check (thizz );
208+ return InputStreamUtils .check (
209+ thizz , InstrumentationContext .get (InputStream .class , SpanAndBuffer .class ));
194210 }
195211
196212 @ Advice .OnMethodExit (suppress = Throwable .class , onThrowable = Throwable .class )
@@ -207,14 +223,19 @@ public static void exit(
207223 return ;
208224 }
209225
210- InputStreamUtils .readAll (thizz , spanAndBuffer , b );
226+ InputStreamUtils .readAll (
227+ thizz ,
228+ spanAndBuffer ,
229+ InstrumentationContext .get (InputStream .class , SpanAndBuffer .class ),
230+ b );
211231 }
212232 }
213233
214234 public static class InputStream_ReadNBytes {
215235 @ Advice .OnMethodEnter (suppress = Throwable .class )
216236 public static SpanAndBuffer enter (@ Advice .This InputStream thizz ) {
217- return InputStreamUtils .check (thizz );
237+ return InputStreamUtils .check (
238+ thizz , InstrumentationContext .get (InputStream .class , SpanAndBuffer .class ));
218239 }
219240
220241 @ Advice .OnMethodExit (suppress = Throwable .class , onThrowable = Throwable .class )
@@ -232,14 +253,35 @@ public static void exit(
232253 if (callDepth > 0 ) {
233254 return ;
234255 }
235- InputStreamUtils .readNBytes (thizz , spanAndBuffer , read , b , off , len );
256+ InputStreamUtils .readNBytes (
257+ thizz ,
258+ spanAndBuffer ,
259+ InstrumentationContext .get (InputStream .class , SpanAndBuffer .class ),
260+ read ,
261+ b ,
262+ off ,
263+ len );
236264 }
237265 }
238266
239267 public static class InputStream_Available {
240268 @ Advice .OnMethodExit (suppress = Throwable .class )
241269 public static void exit (@ Advice .This InputStream thizz , @ Advice .Return int available ) {
242- InputStreamUtils .available (thizz , available );
270+ if (available != 0 ) {
271+ return ;
272+ }
273+ ContextStore <InputStream , SpanAndBuffer > contextStore =
274+ InstrumentationContext .get (InputStream .class , SpanAndBuffer .class );
275+
276+ SpanAndBuffer spanAndBuffer = contextStore .get (thizz );
277+ if (spanAndBuffer != null ) {
278+ InputStreamUtils .addBody (
279+ spanAndBuffer .span ,
280+ spanAndBuffer .attributeKey ,
281+ spanAndBuffer .byteArrayBuffer ,
282+ spanAndBuffer .charset );
283+ contextStore .put (thizz , null );
284+ }
243285 }
244286 }
245287}
0 commit comments