Skip to content

Commit bb722f2

Browse files
authored
Add Servlet no wrapping instrumentation (#235)
* Add servlet no wrapping instrumentation Signed-off-by: Pavol Loffay <[email protected]> * cleanup Signed-off-by: Pavol Loffay <[email protected]> * Servlet input stream instrumentation Signed-off-by: Pavol Loffay <[email protected]> * broken out stream Signed-off-by: Pavol Loffay <[email protected]> * capture output, not working in spring * Not capturing the response body Signed-off-by: Pavol Loffay <[email protected]> * Working build Signed-off-by: Pavol Loffay <[email protected]> * Working Signed-off-by: Pavol Loffay <[email protected]> * Working build Signed-off-by: Pavol Loffay <[email protected]> * passing build Signed-off-by: Pavol Loffay <[email protected]> * Passing nowrapping Signed-off-by: Pavol Loffay <[email protected]> * working Signed-off-by: Pavol Loffay <[email protected]> * rename passing Signed-off-by: Pavol Loffay <[email protected]> * remove unused Signed-off-by: Pavol Loffay <[email protected]> * remove unused Signed-off-by: Pavol Loffay <[email protected]> * Rename Signed-off-by: Pavol Loffay <[email protected]> * Remove response buffer Signed-off-by: Pavol Loffay <[email protected]> * Working Signed-off-by: Pavol Loffay <[email protected]> * Split modules to pass muzzle Signed-off-by: Pavol Loffay <[email protected]> * Some cleanup Signed-off-by: Pavol Loffay <[email protected]> * Refactor packages Signed-off-by: Pavol Loffay <[email protected]> * Add more stream tests Signed-off-by: Pavol Loffay <[email protected]> * More tests, writer Signed-off-by: Pavol Loffay <[email protected]> * urlencoded tests Signed-off-by: Pavol Loffay <[email protected]> * Fix wrapping Signed-off-by: Pavol Loffay <[email protected]> * Remove print Signed-off-by: Pavol Loffay <[email protected]> * Fixed wrapper of req/resp objects Signed-off-by: Pavol Loffay <[email protected]> * Wrapping of input stream Signed-off-by: Pavol Loffay <[email protected]> * wrapping reader test Signed-off-by: Pavol Loffay <[email protected]> * Wrap output stream Signed-off-by: Pavol Loffay <[email protected]> * Small corrections to the outstream Signed-off-by: Pavol Loffay <[email protected]> * reader and writer instr Signed-off-by: Pavol Loffay <[email protected]> * Foo bar Signed-off-by: Pavol Loffay <[email protected]> * Delagating types Signed-off-by: Pavol Loffay <[email protected]> * Revert back Signed-off-by: Pavol Loffay <[email protected]> * Align inputstream instrumentation with servlet Signed-off-by: Pavol Loffay <[email protected]> * Adapt outputstream impl Signed-off-by: Pavol Loffay <[email protected]> * Use older jetty Signed-off-by: Pavol Loffay <[email protected]> * Add async test Signed-off-by: Pavol Loffay <[email protected]> * remove prints Signed-off-by: Pavol Loffay <[email protected]> * outputstream tests Signed-off-by: Pavol Loffay <[email protected]> * Rename metadata Signed-off-by: Pavol Loffay <[email protected]> * Remove mockito Signed-off-by: Pavol Loffay <[email protected]> * Fix names Signed-off-by: Pavol Loffay <[email protected]> * test blocking Signed-off-by: Pavol Loffay <[email protected]>
1 parent e157c1c commit bb722f2

File tree

48 files changed

+3480
-147
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+3480
-147
lines changed

Diff for: instrumentation/build.gradle.kts

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ dependencies{
3333
implementation(project(":instrumentation:servlet:servlet-2.3"))
3434
implementation(project(":instrumentation:servlet:servlet-3.0"))
3535
implementation(project(":instrumentation:servlet:servlet-3.1"))
36+
implementation(project(":instrumentation:servlet:servlet-rw"))
37+
implementation(project(":instrumentation:servlet:servlet-3.0-no-wrapping"))
3638
implementation(project(":instrumentation:spark-2.3"))
3739
implementation(project(":instrumentation:grpc-1.5"))
3840
implementation(project(":instrumentation:okhttp:okhttp-3.0"))

Diff for: instrumentation/java-streams/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/java/inputstream/InputStreamInstrumentationModule.java

+49-14
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717
package io.opentelemetry.javaagent.instrumentation.hypertrace.java.inputstream;
1818

1919
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.extendsClass;
20+
import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.safeHasSuperType;
2021
import static net.bytebuddy.matcher.ElementMatchers.is;
2122
import static net.bytebuddy.matcher.ElementMatchers.isPublic;
2223
import static net.bytebuddy.matcher.ElementMatchers.named;
24+
import static net.bytebuddy.matcher.ElementMatchers.not;
2325
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
2426
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
2527

2628
import com.google.auto.service.AutoService;
29+
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
2730
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
2831
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
2932
import java.io.IOException;
@@ -68,7 +71,8 @@ static class InputStreamInstrumentation implements TypeInstrumentation {
6871

6972
@Override
7073
public ElementMatcher<? super TypeDescription> typeMatcher() {
71-
return extendsClass(named(InputStream.class.getName()));
74+
return extendsClass(named(InputStream.class.getName()))
75+
.and(not(safeHasSuperType(named("javax.servlet.ServletInputStream"))));
7276
}
7377

7478
@Override
@@ -116,14 +120,20 @@ public static SpanAndBuffer enter(@Advice.This InputStream thizz) {
116120
return InputStreamUtils.check(thizz);
117121
}
118122

119-
@Advice.OnMethodExit(suppress = Throwable.class)
123+
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)
120124
public static void exit(
121125
@Advice.This InputStream thizz,
122126
@Advice.Return int read,
123127
@Advice.Enter SpanAndBuffer spanAndBuffer) {
124-
if (spanAndBuffer != null) {
125-
InputStreamUtils.read(thizz, spanAndBuffer, read);
128+
if (spanAndBuffer == null) {
129+
return;
130+
}
131+
int callDepth = CallDepthThreadLocalMap.decrementCallDepth(InputStream.class);
132+
if (callDepth > 0) {
133+
return;
126134
}
135+
136+
InputStreamUtils.read(thizz, spanAndBuffer, read);
127137
}
128138
}
129139

@@ -133,15 +143,21 @@ public static SpanAndBuffer enter(@Advice.This InputStream thizz) {
133143
return InputStreamUtils.check(thizz);
134144
}
135145

136-
@Advice.OnMethodExit(suppress = Throwable.class)
146+
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)
137147
public static void exit(
138148
@Advice.This InputStream thizz,
139149
@Advice.Return int read,
140150
@Advice.Argument(0) byte b[],
141151
@Advice.Enter SpanAndBuffer spanAndBuffer) {
142-
if (spanAndBuffer != null) {
143-
InputStreamUtils.read(thizz, spanAndBuffer, read, b);
152+
if (spanAndBuffer == null) {
153+
return;
144154
}
155+
int callDepth = CallDepthThreadLocalMap.decrementCallDepth(InputStream.class);
156+
if (callDepth > 0) {
157+
return;
158+
}
159+
160+
InputStreamUtils.read(thizz, spanAndBuffer, read, b);
145161
}
146162
}
147163

@@ -151,17 +167,23 @@ public static SpanAndBuffer enter(@Advice.This InputStream thizz) {
151167
return InputStreamUtils.check(thizz);
152168
}
153169

154-
@Advice.OnMethodExit(suppress = Throwable.class)
170+
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)
155171
public static void exit(
156172
@Advice.This InputStream thizz,
157173
@Advice.Return int read,
158174
@Advice.Argument(0) byte b[],
159175
@Advice.Argument(1) int off,
160176
@Advice.Argument(2) int len,
161177
@Advice.Enter SpanAndBuffer spanAndBuffer) {
162-
if (spanAndBuffer != null) {
163-
InputStreamUtils.read(thizz, spanAndBuffer, read, b, off, len);
178+
if (spanAndBuffer == null) {
179+
return;
180+
}
181+
int callDepth = CallDepthThreadLocalMap.decrementCallDepth(InputStream.class);
182+
if (callDepth > 0) {
183+
return;
164184
}
185+
186+
InputStreamUtils.read(thizz, spanAndBuffer, read, b, off, len);
165187
}
166188
}
167189

@@ -171,15 +193,21 @@ public static SpanAndBuffer enter(@Advice.This InputStream thizz) {
171193
return InputStreamUtils.check(thizz);
172194
}
173195

174-
@Advice.OnMethodExit(suppress = Throwable.class)
196+
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)
175197
public static void exit(
176198
@Advice.This InputStream thizz,
177199
@Advice.Return byte[] b,
178200
@Advice.Enter SpanAndBuffer spanAndBuffer)
179201
throws IOException {
180-
if (spanAndBuffer != null) {
181-
InputStreamUtils.readAll(thizz, spanAndBuffer, b);
202+
if (spanAndBuffer == null) {
203+
return;
182204
}
205+
int callDepth = CallDepthThreadLocalMap.decrementCallDepth(InputStream.class);
206+
if (callDepth > 0) {
207+
return;
208+
}
209+
210+
InputStreamUtils.readAll(thizz, spanAndBuffer, b);
183211
}
184212
}
185213

@@ -189,14 +217,21 @@ public static SpanAndBuffer enter(@Advice.This InputStream thizz) {
189217
return InputStreamUtils.check(thizz);
190218
}
191219

192-
@Advice.OnMethodExit(suppress = Throwable.class)
220+
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)
193221
public static void exit(
194222
@Advice.This InputStream thizz,
195223
@Advice.Return int read,
196224
@Advice.Argument(0) byte[] b,
197225
@Advice.Argument(1) int off,
198226
@Advice.Argument(2) int len,
199227
@Advice.Enter SpanAndBuffer spanAndBuffer) {
228+
if (spanAndBuffer == null) {
229+
return;
230+
}
231+
int callDepth = CallDepthThreadLocalMap.decrementCallDepth(InputStream.class);
232+
if (callDepth > 0) {
233+
return;
234+
}
200235
InputStreamUtils.readNBytes(thizz, spanAndBuffer, read, b, off, len);
201236
}
202237
}

Diff for: instrumentation/java-streams/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/java/inputstream/InputStreamUtils.java

+1-9
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,7 @@ public static SpanAndBuffer check(InputStream inputStream) {
7676
return null;
7777
}
7878

79-
int callDepth = CallDepthThreadLocalMap.incrementCallDepth(InputStream.class);
80-
if (callDepth > 0) {
81-
return null;
82-
}
79+
CallDepthThreadLocalMap.incrementCallDepth(InputStream.class);
8380
return spanAndBuffer;
8481
}
8582

@@ -94,7 +91,6 @@ public static void read(InputStream inputStream, SpanAndBuffer spanAndBuffer, in
9491
spanAndBuffer.charset);
9592
GlobalObjectRegistry.inputStreamToSpanAndBufferMap.remove(inputStream);
9693
}
97-
CallDepthThreadLocalMap.reset(InputStream.class);
9894
}
9995

10096
public static void read(
@@ -109,7 +105,6 @@ public static void read(
109105
spanAndBuffer.charset);
110106
GlobalObjectRegistry.inputStreamToSpanAndBufferMap.remove(inputStream);
111107
}
112-
CallDepthThreadLocalMap.reset(InputStream.class);
113108
}
114109

115110
public static void read(
@@ -124,14 +119,12 @@ public static void read(
124119
spanAndBuffer.charset);
125120
GlobalObjectRegistry.inputStreamToSpanAndBufferMap.remove(inputStream);
126121
}
127-
CallDepthThreadLocalMap.reset(InputStream.class);
128122
}
129123

130124
public static void readAll(InputStream inputStream, SpanAndBuffer spanAndBuffer, byte[] b)
131125
throws IOException {
132126
spanAndBuffer.byteArrayBuffer.write(b);
133127
GlobalObjectRegistry.inputStreamToSpanAndBufferMap.remove(inputStream);
134-
CallDepthThreadLocalMap.reset(InputStream.class);
135128
}
136129

137130
public static void readNBytes(
@@ -146,7 +139,6 @@ public static void readNBytes(
146139
} else {
147140
spanAndBuffer.byteArrayBuffer.write(b, off, read);
148141
}
149-
CallDepthThreadLocalMap.reset(InputStream.class);
150142
}
151143

152144
public static void available(InputStream inputStream, int available) {

Diff for: instrumentation/java-streams/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/java/outputstream/OutputStreamInstrumentationModule.java

+56-26
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
2525

2626
import com.google.auto.service.AutoService;
27+
import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap;
2728
import io.opentelemetry.javaagent.tooling.InstrumentationModule;
2829
import io.opentelemetry.javaagent.tooling.TypeInstrumentation;
2930
import java.io.IOException;
@@ -37,6 +38,7 @@
3738
import net.bytebuddy.description.type.TypeDescription;
3839
import net.bytebuddy.matcher.ElementMatcher;
3940
import org.hypertrace.agent.core.instrumentation.GlobalObjectRegistry;
41+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStream;
4042

4143
/**
4244
* {@link OutputStream} instrumentation. The type matcher applies to all implementations. However
@@ -96,51 +98,79 @@ public Map<? extends ElementMatcher<? super MethodDescription>, String> transfor
9698

9799
static class OutputStream_WriteIntAdvice {
98100
@Advice.OnMethodEnter(suppress = Throwable.class)
99-
public static boolean enter(@Advice.This OutputStream thizz) {
100-
return OutputStreamUtils.check(thizz);
101+
public static BoundedByteArrayOutputStream enter(
102+
@Advice.This OutputStream thizz, @Advice.Argument(0) int b) {
103+
BoundedByteArrayOutputStream buffer = GlobalObjectRegistry.outputStreamToBufferMap.get(thizz);
104+
if (buffer == null) {
105+
return null;
106+
}
107+
int callDepth = CallDepthThreadLocalMap.incrementCallDepth(OutputStream.class);
108+
if (callDepth > 0) {
109+
return buffer;
110+
}
111+
112+
buffer.write(b);
113+
return buffer;
101114
}
102115

103116
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)
104-
public static void exit(
105-
@Advice.This OutputStream thizz,
106-
@Advice.Argument(0) int b,
107-
@Advice.Enter boolean retEnterAdvice)
108-
throws IOException {
109-
OutputStreamUtils.write(thizz, retEnterAdvice, b);
117+
public static void exit(@Advice.Enter BoundedByteArrayOutputStream buffer) {
118+
if (buffer != null) {
119+
CallDepthThreadLocalMap.decrementCallDepth(OutputStream.class);
120+
}
110121
}
111122
}
112123

113124
static class OutputStream_WriteByteArrAdvice {
114125
@Advice.OnMethodEnter(suppress = Throwable.class)
115-
public static boolean enter(@Advice.This OutputStream thizz) {
116-
return OutputStreamUtils.check(thizz);
126+
public static BoundedByteArrayOutputStream enter(
127+
@Advice.This OutputStream thizz, @Advice.Argument(0) byte b[]) throws IOException {
128+
BoundedByteArrayOutputStream buffer = GlobalObjectRegistry.outputStreamToBufferMap.get(thizz);
129+
if (buffer == null) {
130+
return null;
131+
}
132+
int callDepth = CallDepthThreadLocalMap.incrementCallDepth(OutputStream.class);
133+
if (callDepth > 0) {
134+
return buffer;
135+
}
136+
137+
buffer.write(b);
138+
return buffer;
117139
}
118140

119141
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)
120-
public static void exit(
121-
@Advice.This OutputStream thizz,
122-
@Advice.Argument(0) byte b[],
123-
@Advice.Enter boolean retEnterAdvice)
124-
throws IOException {
125-
OutputStreamUtils.write(thizz, retEnterAdvice, b);
142+
public static void exit(@Advice.Enter BoundedByteArrayOutputStream buffer) {
143+
if (buffer != null) {
144+
CallDepthThreadLocalMap.decrementCallDepth(OutputStream.class);
145+
}
126146
}
127147
}
128148

129149
static class OutputStream_WriteByteArrOffsetAdvice {
130150
@Advice.OnMethodEnter(suppress = Throwable.class)
131-
public static boolean enter(@Advice.This OutputStream thizz) {
132-
return OutputStreamUtils.check(thizz);
133-
}
134-
135-
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)
136-
public static void exit(
151+
public static BoundedByteArrayOutputStream enter(
137152
@Advice.This OutputStream thizz,
138153
@Advice.Argument(0) byte b[],
139154
@Advice.Argument(1) int off,
140-
@Advice.Argument(2) int len,
141-
@Advice.Enter boolean retEnterAdvice)
142-
throws IOException {
143-
OutputStreamUtils.write(thizz, retEnterAdvice, b, off, len);
155+
@Advice.Argument(2) int len) {
156+
BoundedByteArrayOutputStream buffer = GlobalObjectRegistry.outputStreamToBufferMap.get(thizz);
157+
if (buffer == null) {
158+
return null;
159+
}
160+
int callDepth = CallDepthThreadLocalMap.incrementCallDepth(OutputStream.class);
161+
if (callDepth > 0) {
162+
return buffer;
163+
}
164+
165+
buffer.write(b, off, len);
166+
return buffer;
167+
}
168+
169+
@Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class)
170+
public static void exit(@Advice.Enter BoundedByteArrayOutputStream buffer) {
171+
if (buffer != null) {
172+
CallDepthThreadLocalMap.decrementCallDepth(OutputStream.class);
173+
}
144174
}
145175
}
146176
}

0 commit comments

Comments
 (0)