Skip to content

Commit 4989a26

Browse files
authored
Bounded Grpc payload sizes (#211)
* Buffer impl Signed-off-by: Pavol Loffay <[email protected]> * Add test Signed-off-by: Pavol Loffay <[email protected]>
1 parent 17fbe22 commit 4989a26

File tree

14 files changed

+213
-35
lines changed

14 files changed

+213
-35
lines changed

instrumentation/apache-httpclient-4.0/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/apachehttpclient/v4_0/ApacheHttpClientUtils.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
import org.hypertrace.agent.config.Config.AgentConfig;
3333
import org.hypertrace.agent.core.config.HypertraceConfig;
3434
import org.hypertrace.agent.core.instrumentation.HypertraceSemanticAttributes;
35+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedBuffersFactory;
3536
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStream;
36-
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStreamFactory;
3737
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeCharsetUtils;
3838
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeUtils;
3939
import org.slf4j.Logger;
@@ -107,7 +107,7 @@ public static void traceEntity(
107107
if (entity.isRepeatable()) {
108108
try {
109109
BoundedByteArrayOutputStream byteArrayOutputStream =
110-
BoundedByteArrayOutputStreamFactory.create(charset);
110+
BoundedBuffersFactory.createStream(charset);
111111
entity.writeTo(byteArrayOutputStream);
112112

113113
try {

instrumentation/apache-httpclient-4.0/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/apachehttpclient/v4_0/HttpEntityInstrumentation.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
import org.apache.http.HttpEntity;
4040
import org.hypertrace.agent.core.instrumentation.GlobalObjectRegistry;
4141
import org.hypertrace.agent.core.instrumentation.GlobalObjectRegistry.SpanAndBuffer;
42+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedBuffersFactory;
4243
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStream;
43-
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStreamFactory;
4444
import org.hypertrace.agent.core.instrumentation.utils.ContentLengthUtils;
4545
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeCharsetUtils;
4646
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeUtils;
@@ -100,7 +100,7 @@ public static void exit(@Advice.This HttpEntity thizz, @Advice.Return InputStrea
100100
SpanAndBuffer spanAndBuffer =
101101
new SpanAndBuffer(
102102
clientSpan.span,
103-
BoundedByteArrayOutputStreamFactory.create((int) contentSize, charset),
103+
BoundedBuffersFactory.createStream((int) contentSize, charset),
104104
clientSpan.attributeKey,
105105
charset);
106106
GlobalObjectRegistry.inputStreamToSpanAndBufferMap.put(inputStream, spanAndBuffer);
@@ -129,7 +129,7 @@ public static void enter(
129129
Charset charset = ContentTypeCharsetUtils.toCharset(charsetStr);
130130

131131
BoundedByteArrayOutputStream byteArrayOutputStream =
132-
BoundedByteArrayOutputStreamFactory.create((int) contentSize, charset);
132+
BoundedBuffersFactory.createStream((int) contentSize, charset);
133133

134134
GlobalObjectRegistry.outputStreamToBufferMap.put(outputStream, byteArrayOutputStream);
135135
}

instrumentation/apache-httpclient-4.0/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/apachehttpclient/v4_0/readall/ApacheClientReadAllInstrumentationModule.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
import org.apache.http.HttpResponse;
5252
import org.hypertrace.agent.core.instrumentation.GlobalObjectRegistry;
5353
import org.hypertrace.agent.core.instrumentation.HypertraceSemanticAttributes;
54-
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStreamFactory;
54+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedBuffersFactory;
5555
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeUtils;
5656

5757
@AutoService(InstrumentationModule.class)
@@ -198,8 +198,7 @@ public static void exit(@Return Object response) {
198198

199199
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
200200
ByteArrayOutputStream buffer =
201-
BoundedByteArrayOutputStreamFactory.create(
202-
(int) contentSize, Charset.defaultCharset());
201+
BoundedBuffersFactory.createStream((int) contentSize, Charset.defaultCharset());
203202
byte ch;
204203
while ((ch = (byte) bufferedInputStream.read()) != -1) {
205204
buffer.write(ch);

instrumentation/grpc-1.5/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/grpc/v1_5/GrpcSpanDecorator.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,19 @@
1616

1717
package io.opentelemetry.javaagent.instrumentation.hypertrace.grpc.v1_5;
1818

19-
import com.google.protobuf.InvalidProtocolBufferException;
2019
import com.google.protobuf.Message;
2120
import com.google.protobuf.util.JsonFormat;
2221
import io.grpc.Metadata;
2322
import io.grpc.Metadata.Key;
2423
import io.opentelemetry.api.common.AttributeKey;
2524
import io.opentelemetry.api.trace.Span;
25+
import java.io.IOException;
2626
import java.util.LinkedHashMap;
2727
import java.util.Map;
2828
import java.util.function.Function;
2929
import org.hypertrace.agent.core.instrumentation.HypertraceSemanticAttributes;
30+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedBuffersFactory;
31+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedCharArrayWriter;
3032
import org.slf4j.Logger;
3133
import org.slf4j.LoggerFactory;
3234

@@ -41,9 +43,10 @@ public static void addMessageAttribute(Object message, Span span, AttributeKey<S
4143
if (message instanceof Message) {
4244
Message mb = (Message) message;
4345
try {
44-
String requestBody = PRINTER.print(mb);
45-
span.setAttribute(key, requestBody);
46-
} catch (InvalidProtocolBufferException e) {
46+
BoundedCharArrayWriter writer = BoundedBuffersFactory.createWriter();
47+
PRINTER.appendTo(mb, writer);
48+
span.setAttribute(key, writer.toString());
49+
} catch (IOException e) {
4750
log.error("Failed to decode message to JSON", e);
4851
}
4952
}

instrumentation/java-streams/src/test/java/io/opentelemetry/javaagent/instrumentation/hypertrace/java/outputstream/OutputStreamInstrumentationModuleTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
import java.nio.charset.Charset;
2323
import java.nio.charset.StandardCharsets;
2424
import org.hypertrace.agent.core.instrumentation.GlobalObjectRegistry;
25+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedBuffersFactory;
2526
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStream;
26-
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStreamFactory;
2727
import org.hypertrace.agent.testing.AbstractInstrumenterTest;
2828
import org.junit.jupiter.api.Assertions;
2929
import org.junit.jupiter.api.Test;
@@ -87,7 +87,7 @@ public void writeBytesOffset() {
8787

8888
private void write(OutputStream outputStream, Runnable read, String expected) {
8989
BoundedByteArrayOutputStream buffer =
90-
BoundedByteArrayOutputStreamFactory.create(MAX_SIZE, DEFAULT_CHARSET);
90+
BoundedBuffersFactory.createStream(MAX_SIZE, DEFAULT_CHARSET);
9191
GlobalObjectRegistry.outputStreamToBufferMap.put(outputStream, buffer);
9292
read.run();
9393
Assertions.assertEquals(expected, buffer.toString());

instrumentation/jaxrs-client-2.0/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/jaxrs/v2_0/JaxrsClientEntityInterceptor.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
import org.hypertrace.agent.core.instrumentation.GlobalObjectRegistry;
3636
import org.hypertrace.agent.core.instrumentation.GlobalObjectRegistry.SpanAndBuffer;
3737
import org.hypertrace.agent.core.instrumentation.HypertraceSemanticAttributes;
38+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedBuffersFactory;
3839
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStream;
39-
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStreamFactory;
4040
import org.hypertrace.agent.core.instrumentation.utils.ContentLengthUtils;
4141
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeCharsetUtils;
4242
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeUtils;
@@ -86,7 +86,7 @@ public Object aroundReadFrom(ReaderInterceptorContext responseContext)
8686
Charset charset = ContentTypeCharsetUtils.toCharset(charsetStr);
8787

8888
BoundedByteArrayOutputStream buffer =
89-
BoundedByteArrayOutputStreamFactory.create(contentLength, charset);
89+
BoundedBuffersFactory.createStream(contentLength, charset);
9090
GlobalObjectRegistry.inputStreamToSpanAndBufferMap.put(
9191
entityStream,
9292
new SpanAndBuffer(
@@ -130,7 +130,7 @@ public void aroundWriteTo(WriterInterceptorContext requestContext)
130130
Charset charset = ContentTypeCharsetUtils.toCharset(charsetStr);
131131

132132
// TODO length is not known
133-
BoundedByteArrayOutputStream buffer = BoundedByteArrayOutputStreamFactory.create(charset);
133+
BoundedByteArrayOutputStream buffer = BoundedBuffersFactory.createStream(charset);
134134
OutputStream entityStream = requestContext.getOutputStream();
135135
try {
136136
GlobalObjectRegistry.outputStreamToBufferMap.put(entityStream, buffer);

instrumentation/netty/netty-4.0/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/netty/v4_0/server/HttpServerRequestTracingHandler.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
import org.hypertrace.agent.config.Config.AgentConfig;
3535
import org.hypertrace.agent.core.config.HypertraceConfig;
3636
import org.hypertrace.agent.core.instrumentation.HypertraceSemanticAttributes;
37+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedBuffersFactory;
3738
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStream;
38-
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStreamFactory;
3939
import org.hypertrace.agent.core.instrumentation.utils.ContentLengthUtils;
4040
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeCharsetUtils;
4141
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeUtils;
@@ -79,7 +79,7 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) {
7979
// the buffer is used byt captureBody method
8080
Attribute<BoundedByteArrayOutputStream> bufferAttr =
8181
ctx.channel().attr(AttributeKeys.REQUEST_BODY_BUFFER);
82-
bufferAttr.set(BoundedByteArrayOutputStreamFactory.create(contentLength, charset));
82+
bufferAttr.set(BoundedBuffersFactory.createStream(contentLength, charset));
8383
}
8484
}
8585

instrumentation/netty/netty-4.0/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/netty/v4_0/server/HttpServerResponseTracingHandler.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
import org.hypertrace.agent.config.Config.AgentConfig;
4040
import org.hypertrace.agent.core.config.HypertraceConfig;
4141
import org.hypertrace.agent.core.instrumentation.HypertraceSemanticAttributes;
42+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedBuffersFactory;
4243
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStream;
43-
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStreamFactory;
4444
import org.hypertrace.agent.core.instrumentation.utils.ContentLengthUtils;
4545
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeCharsetUtils;
4646
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeUtils;
@@ -79,7 +79,7 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise prm) {
7979
// the buffer is used byt captureBody method
8080
Attribute<BoundedByteArrayOutputStream> bufferAttr =
8181
ctx.channel().attr(AttributeKeys.RESPONSE_BODY_BUFFER);
82-
bufferAttr.set(BoundedByteArrayOutputStreamFactory.create(contentLength, charset));
82+
bufferAttr.set(BoundedBuffersFactory.createStream(contentLength, charset));
8383
}
8484
}
8585

instrumentation/netty/netty-4.1/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/netty/v4_1/server/HttpServerRequestTracingHandler.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
import org.hypertrace.agent.config.Config.AgentConfig;
3535
import org.hypertrace.agent.core.config.HypertraceConfig;
3636
import org.hypertrace.agent.core.instrumentation.HypertraceSemanticAttributes;
37+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedBuffersFactory;
3738
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStream;
38-
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStreamFactory;
3939
import org.hypertrace.agent.core.instrumentation.utils.ContentLengthUtils;
4040
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeCharsetUtils;
4141
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeUtils;
@@ -79,7 +79,7 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) {
7979
// the buffer is used byt captureBody method
8080
Attribute<BoundedByteArrayOutputStream> bufferAttr =
8181
ctx.channel().attr(AttributeKeys.REQUEST_BODY_BUFFER);
82-
bufferAttr.set(BoundedByteArrayOutputStreamFactory.create(contentLength, charset));
82+
bufferAttr.set(BoundedBuffersFactory.createStream(contentLength, charset));
8383
}
8484
}
8585

instrumentation/netty/netty-4.1/src/main/java/io/opentelemetry/javaagent/instrumentation/hypertrace/netty/v4_1/server/HttpServerResponseTracingHandler.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
import org.hypertrace.agent.config.Config.AgentConfig;
3838
import org.hypertrace.agent.core.config.HypertraceConfig;
3939
import org.hypertrace.agent.core.instrumentation.HypertraceSemanticAttributes;
40+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedBuffersFactory;
4041
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStream;
41-
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStreamFactory;
4242
import org.hypertrace.agent.core.instrumentation.utils.ContentLengthUtils;
4343
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeCharsetUtils;
4444
import org.hypertrace.agent.core.instrumentation.utils.ContentTypeUtils;
@@ -77,7 +77,7 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise prm) {
7777
// the buffer is used byt captureBody method
7878
Attribute<BoundedByteArrayOutputStream> bufferAttr =
7979
ctx.channel().attr(AttributeKeys.RESPONSE_BODY_BUFFER);
80-
bufferAttr.set(BoundedByteArrayOutputStreamFactory.create(contentLength, charset));
80+
bufferAttr.set(BoundedBuffersFactory.createStream(contentLength, charset));
8181
}
8282
}
8383

Original file line numberDiff line numberDiff line change
@@ -19,19 +19,30 @@
1919
import java.nio.charset.Charset;
2020
import org.hypertrace.agent.core.config.HypertraceConfig;
2121

22-
public class BoundedByteArrayOutputStreamFactory {
22+
public class BoundedBuffersFactory {
2323

24-
public static final int DEFAULT_SIZE =
24+
public static final int MAX_SIZE =
2525
HypertraceConfig.get().getDataCapture().getBodyMaxSizeBytes().getValue();
2626

27-
public static BoundedByteArrayOutputStream create(Charset charset) {
28-
return new BoundedByteArrayOutputStream(DEFAULT_SIZE, charset);
27+
public static BoundedByteArrayOutputStream createStream(Charset charset) {
28+
return new BoundedByteArrayOutputStream(MAX_SIZE, charset);
2929
}
3030

31-
public static BoundedByteArrayOutputStream create(int initialSize, Charset charset) {
32-
if (initialSize > DEFAULT_SIZE) {
33-
initialSize = DEFAULT_SIZE;
31+
public static BoundedByteArrayOutputStream createStream(int initialSize, Charset charset) {
32+
if (initialSize > MAX_SIZE) {
33+
initialSize = MAX_SIZE;
3434
}
35-
return new BoundedByteArrayOutputStream(DEFAULT_SIZE, initialSize, charset);
35+
return new BoundedByteArrayOutputStream(MAX_SIZE, initialSize, charset);
36+
}
37+
38+
public static BoundedCharArrayWriter createWriter() {
39+
return new BoundedCharArrayWriter(MAX_SIZE);
40+
}
41+
42+
public static BoundedCharArrayWriter createWriter(int initialSize) {
43+
if (initialSize > MAX_SIZE) {
44+
initialSize = MAX_SIZE;
45+
}
46+
return new BoundedCharArrayWriter(MAX_SIZE, initialSize);
3647
}
3748
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* Copyright The Hypertrace Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.hypertrace.agent.core.instrumentation.buffer;
18+
19+
import java.io.CharArrayWriter;
20+
import java.io.IOException;
21+
import java.io.Writer;
22+
23+
public class BoundedCharArrayWriter extends CharArrayWriter {
24+
25+
private final int maxCapacity;
26+
27+
BoundedCharArrayWriter(int maxCapacity) {
28+
this.maxCapacity = maxCapacity;
29+
}
30+
31+
BoundedCharArrayWriter(int maxCapacity, int initialSize) {
32+
super(initialSize);
33+
this.maxCapacity = maxCapacity;
34+
}
35+
36+
@Override
37+
public void write(int c) {
38+
if (size() == maxCapacity) {
39+
return;
40+
}
41+
super.write(c);
42+
}
43+
44+
@Override
45+
public void write(char[] c, int off, int len) {
46+
int size = size();
47+
if (size + len > maxCapacity) {
48+
super.write(c, off, maxCapacity - size);
49+
return;
50+
}
51+
super.write(c, off, len);
52+
}
53+
54+
@Override
55+
public void write(String str, int off, int len) {
56+
int size = size();
57+
if (size + len > maxCapacity) {
58+
super.write(str, off, maxCapacity - size);
59+
return;
60+
}
61+
super.write(str, off, len);
62+
}
63+
64+
@Override
65+
public void writeTo(Writer out) throws IOException {
66+
// don't need to override, it will copy what is buffered
67+
super.writeTo(out);
68+
}
69+
70+
@Override
71+
public CharArrayWriter append(CharSequence csq) {
72+
// the same impl as the super class
73+
String s = (csq == null ? "null" : csq.toString());
74+
this.write(s, 0, s.length());
75+
return this;
76+
}
77+
78+
@Override
79+
public CharArrayWriter append(CharSequence csq, int start, int end) {
80+
String s = (csq == null ? "null" : csq).subSequence(start, end).toString();
81+
write(s, 0, s.length());
82+
return this;
83+
}
84+
85+
@Override
86+
public CharArrayWriter append(char c) {
87+
write(c);
88+
return this;
89+
}
90+
91+
@Override
92+
public void write(char[] cbuf) throws IOException {
93+
this.write(cbuf, 0, cbuf.length);
94+
}
95+
96+
@Override
97+
public void write(String str) throws IOException {
98+
this.write(str, 0, str.length());
99+
}
100+
}

javaagent-core/src/main/java/org/hypertrace/agent/core/instrumentation/utils/ContentLengthUtils.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616

1717
package org.hypertrace.agent.core.instrumentation.utils;
1818

19-
import org.hypertrace.agent.core.instrumentation.buffer.BoundedByteArrayOutputStreamFactory;
19+
import org.hypertrace.agent.core.instrumentation.buffer.BoundedBuffersFactory;
2020

2121
public class ContentLengthUtils {
2222
private ContentLengthUtils() {}
2323

2424
// default content length
25-
public static final int DEFAULT = BoundedByteArrayOutputStreamFactory.DEFAULT_SIZE;
25+
public static final int DEFAULT = BoundedBuffersFactory.MAX_SIZE;
2626

2727
public static int parseLength(CharSequence lengthStr) {
2828
if (lengthStr == null || lengthStr.length() == 0) {

0 commit comments

Comments
 (0)