27
27
28
28
import com .google .auto .service .AutoService ;
29
29
import io .opentelemetry .javaagent .instrumentation .api .CallDepthThreadLocalMap ;
30
+ import io .opentelemetry .javaagent .instrumentation .api .ContextStore ;
31
+ import io .opentelemetry .javaagent .instrumentation .api .InstrumentationContext ;
30
32
import io .opentelemetry .javaagent .tooling .InstrumentationModule ;
31
33
import io .opentelemetry .javaagent .tooling .TypeInstrumentation ;
32
34
import java .io .IOException ;
39
41
import net .bytebuddy .description .method .MethodDescription ;
40
42
import net .bytebuddy .description .type .TypeDescription ;
41
43
import 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 ;
44
45
45
46
/**
46
47
* {@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.
49
50
*
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.
54
55
*
55
56
* <p>Maybe we could add optimization to instrument the input streams only when certain classes are
56
57
* present in classloader e.g. classes from frameworks that we instrument.
@@ -117,7 +118,8 @@ public Map<? extends ElementMatcher<? super MethodDescription>, String> transfor
117
118
public static class InputStream_ReadNoArgsAdvice {
118
119
@ Advice .OnMethodEnter (suppress = Throwable .class )
119
120
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 ));
121
123
}
122
124
123
125
@ Advice .OnMethodExit (suppress = Throwable .class , onThrowable = Throwable .class )
@@ -133,14 +135,19 @@ public static void exit(
133
135
return ;
134
136
}
135
137
136
- InputStreamUtils .read (thizz , spanAndBuffer , read );
138
+ InputStreamUtils .read (
139
+ thizz ,
140
+ spanAndBuffer ,
141
+ InstrumentationContext .get (InputStream .class , SpanAndBuffer .class ),
142
+ read );
137
143
}
138
144
}
139
145
140
146
public static class InputStream_ReadByteArrayAdvice {
141
147
@ Advice .OnMethodEnter (suppress = Throwable .class )
142
148
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 ));
144
151
}
145
152
146
153
@ Advice .OnMethodExit (suppress = Throwable .class , onThrowable = Throwable .class )
@@ -164,7 +171,8 @@ public static void exit(
164
171
public static class InputStream_ReadByteArrayOffsetAdvice {
165
172
@ Advice .OnMethodEnter (suppress = Throwable .class )
166
173
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 ));
168
176
}
169
177
170
178
@ Advice .OnMethodExit (suppress = Throwable .class , onThrowable = Throwable .class )
@@ -183,14 +191,22 @@ public static void exit(
183
191
return ;
184
192
}
185
193
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 );
187
202
}
188
203
}
189
204
190
205
public static class InputStream_ReadAllBytes {
191
206
@ Advice .OnMethodEnter (suppress = Throwable .class )
192
207
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 ));
194
210
}
195
211
196
212
@ Advice .OnMethodExit (suppress = Throwable .class , onThrowable = Throwable .class )
@@ -207,14 +223,19 @@ public static void exit(
207
223
return ;
208
224
}
209
225
210
- InputStreamUtils .readAll (thizz , spanAndBuffer , b );
226
+ InputStreamUtils .readAll (
227
+ thizz ,
228
+ spanAndBuffer ,
229
+ InstrumentationContext .get (InputStream .class , SpanAndBuffer .class ),
230
+ b );
211
231
}
212
232
}
213
233
214
234
public static class InputStream_ReadNBytes {
215
235
@ Advice .OnMethodEnter (suppress = Throwable .class )
216
236
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 ));
218
239
}
219
240
220
241
@ Advice .OnMethodExit (suppress = Throwable .class , onThrowable = Throwable .class )
@@ -232,14 +253,35 @@ public static void exit(
232
253
if (callDepth > 0 ) {
233
254
return ;
234
255
}
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 );
236
264
}
237
265
}
238
266
239
267
public static class InputStream_Available {
240
268
@ Advice .OnMethodExit (suppress = Throwable .class )
241
269
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
+ }
243
285
}
244
286
}
245
287
}
0 commit comments