Skip to content

Commit 2a1f676

Browse files
committed
Add tags to all metrics
1 parent a5352ff commit 2a1f676

File tree

10 files changed

+415
-406
lines changed

10 files changed

+415
-406
lines changed

dd-java-agent/instrumentation/servlet/request-3/src/main/java/datadog/trace/instrumentation/servlet3/RumHttpServletResponseWrapper.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class RumHttpServletResponseWrapper extends HttpServletResponseWrapper {
1919
private InjectingPipeWriter wrappedPipeWriter;
2020
private boolean shouldInject = true;
2121
private long injectionStartTime = -1;
22+
private String contentEncoding = "none";
2223

2324
private static final MethodHandle SET_CONTENT_LENGTH_LONG = getMh("setContentLengthLong");
2425

@@ -46,7 +47,7 @@ public ServletOutputStream getOutputStream() throws IOException {
4647
return outputStream;
4748
}
4849
if (!shouldInject) {
49-
RumInjector.getTelemetryCollector().onInjectionSkipped();
50+
RumInjector.getTelemetryCollector().onInjectionSkipped("3");
5051
return super.getOutputStream();
5152
}
5253
// start timing injection
@@ -63,9 +64,10 @@ public ServletOutputStream getOutputStream() throws IOException {
6364
super.getOutputStream(),
6465
rumInjector.getMarkerBytes(encoding),
6566
rumInjector.getSnippetBytes(encoding),
66-
this::onInjected);
67+
this::onInjected,
68+
bytes -> RumInjector.getTelemetryCollector().onInjectionResponseSize("3", bytes));
6769
} catch (Exception e) {
68-
RumInjector.getTelemetryCollector().onInjectionFailed();
70+
RumInjector.getTelemetryCollector().onInjectionFailed("3", contentEncoding);
6971
throw e;
7072
}
7173

@@ -78,7 +80,7 @@ public PrintWriter getWriter() throws IOException {
7880
return printWriter;
7981
}
8082
if (!shouldInject) {
81-
RumInjector.getTelemetryCollector().onInjectionSkipped();
83+
RumInjector.getTelemetryCollector().onInjectionSkipped("3");
8284
return super.getWriter();
8385
}
8486
// start timing injection
@@ -94,7 +96,7 @@ public PrintWriter getWriter() throws IOException {
9496
this::onInjected);
9597
printWriter = new PrintWriter(wrappedPipeWriter);
9698
} catch (Exception e) {
97-
RumInjector.getTelemetryCollector().onInjectionFailed();
99+
RumInjector.getTelemetryCollector().onInjectionFailed("3", contentEncoding);
98100
throw e;
99101
}
100102

@@ -104,8 +106,11 @@ public PrintWriter getWriter() throws IOException {
104106
@Override
105107
public void setHeader(String name, String value) {
106108
if (name != null) {
107-
if (name.toLowerCase().startsWith("content-security-policy")) {
108-
RumInjector.getTelemetryCollector().onContentSecurityPolicyDetected();
109+
String lowerName = name.toLowerCase();
110+
if (lowerName.startsWith("content-security-policy")) {
111+
RumInjector.getTelemetryCollector().onContentSecurityPolicyDetected("3");
112+
} else if (lowerName.equals("content-encoding")) {
113+
this.contentEncoding = value;
109114
}
110115
}
111116
super.setHeader(name, value);
@@ -114,8 +119,11 @@ public void setHeader(String name, String value) {
114119
@Override
115120
public void addHeader(String name, String value) {
116121
if (name != null) {
117-
if (name.toLowerCase().startsWith("content-security-policy")) {
118-
RumInjector.getTelemetryCollector().onContentSecurityPolicyDetected();
122+
String lowerName = name.toLowerCase();
123+
if (lowerName.startsWith("content-security-policy")) {
124+
RumInjector.getTelemetryCollector().onContentSecurityPolicyDetected("3");
125+
} else if (lowerName.equals("content-encoding")) {
126+
this.contentEncoding = value;
119127
}
120128
}
121129
super.addHeader(name, value);
@@ -159,13 +167,13 @@ public void resetBuffer() {
159167
}
160168

161169
public void onInjected() {
162-
RumInjector.getTelemetryCollector().onInjectionSucceed();
170+
RumInjector.getTelemetryCollector().onInjectionSucceed("3");
163171

164172
// report injection time
165173
if (injectionStartTime != -1) {
166174
long nanoseconds = System.nanoTime() - injectionStartTime;
167175
long milliseconds = nanoseconds / 1_000_000L;
168-
RumInjector.getTelemetryCollector().onInjectionTime(milliseconds);
176+
RumInjector.getTelemetryCollector().onInjectionTime("3", milliseconds);
169177
injectionStartTime = -1;
170178
}
171179

dd-java-agent/instrumentation/servlet/request-3/src/test/groovy/RumHttpServletResponseWrapperTest.groovy

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
2828
wrapper.onInjected()
2929

3030
then:
31-
1 * mockTelemetryCollector.onInjectionSucceed()
31+
1 * mockTelemetryCollector.onInjectionSucceed("3")
3232
}
3333

3434
void 'getOutputStream with non-HTML content reports skipped'() {
@@ -39,7 +39,7 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
3939
wrapper.getOutputStream()
4040

4141
then:
42-
1 * mockTelemetryCollector.onInjectionSkipped()
42+
1 * mockTelemetryCollector.onInjectionSkipped("3")
4343
1 * mockResponse.getOutputStream()
4444
}
4545

@@ -51,7 +51,7 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
5151
wrapper.getWriter()
5252

5353
then:
54-
1 * mockTelemetryCollector.onInjectionSkipped()
54+
1 * mockTelemetryCollector.onInjectionSkipped("3")
5555
1 * mockResponse.getWriter()
5656
}
5757

@@ -66,7 +66,7 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
6666
} catch (IOException ignored) {}
6767

6868
then:
69-
1 * mockTelemetryCollector.onInjectionFailed()
69+
1 * mockTelemetryCollector.onInjectionFailed("3", "none")
7070
}
7171

7272
void 'getWriter exception reports failure'() {
@@ -80,15 +80,15 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
8080
} catch (IOException ignored) {}
8181

8282
then:
83-
1 * mockTelemetryCollector.onInjectionFailed()
83+
1 * mockTelemetryCollector.onInjectionFailed("3", "none")
8484
}
8585

8686
void 'setHeader with Content-Security-Policy reports CSP detected'() {
8787
when:
8888
wrapper.setHeader("Content-Security-Policy", "test")
8989

9090
then:
91-
1 * mockTelemetryCollector.onContentSecurityPolicyDetected()
91+
1 * mockTelemetryCollector.onContentSecurityPolicyDetected("3")
9292
1 * mockResponse.setHeader("Content-Security-Policy", "test")
9393
}
9494

@@ -97,7 +97,7 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
9797
wrapper.addHeader("Content-Security-Policy", "test")
9898

9999
then:
100-
1 * mockTelemetryCollector.onContentSecurityPolicyDetected()
100+
1 * mockTelemetryCollector.onContentSecurityPolicyDetected("3")
101101
1 * mockResponse.addHeader("Content-Security-Policy", "test")
102102
}
103103

@@ -119,7 +119,29 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
119119
1 * mockResponse.addHeader("X-Content-Security-Policy", "test")
120120
}
121121

122-
void 'response sizes are reported correctly'() {
122+
// Callback is created in the RumHttpServletResponseWrapper and passed to InjectingPipeOutputStream via WrappedServletOutputStream.
123+
// When the stream is closed, the callback is called with the total number of bytes written to the stream.
124+
void 'response sizes are reported to the telemetry collector via the WrappedServletOutputStream callback'() {
125+
setup:
126+
def downstream = Mock(javax.servlet.ServletOutputStream)
127+
def marker = "</head>".getBytes("UTF-8")
128+
def contentToInject = "<script></script>".getBytes("UTF-8")
129+
def onBytesWritten = { bytes ->
130+
mockTelemetryCollector.onInjectionResponseSize("3", bytes)
131+
}
132+
def wrappedStream = new datadog.trace.instrumentation.servlet3.WrappedServletOutputStream(
133+
downstream, marker, contentToInject, null, onBytesWritten)
134+
135+
when:
136+
wrappedStream.write("test".getBytes("UTF-8"))
137+
wrappedStream.write("content".getBytes("UTF-8"))
138+
wrappedStream.close()
139+
140+
then:
141+
1 * mockTelemetryCollector.onInjectionResponseSize("3", 11)
142+
}
143+
144+
void 'response sizes are reported by the InjectingPipeOutputStream callback'() {
123145
setup:
124146
def downstream = Mock(java.io.OutputStream)
125147
def marker = "</head>".getBytes("UTF-8")
@@ -149,6 +171,6 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
149171
wrapper.onInjected() // report timing when injection "is successful"
150172

151173
then:
152-
1 * mockTelemetryCollector.onInjectionTime({ it > 0 })
174+
1 * mockTelemetryCollector.onInjectionTime("3", { it >= 0 })
153175
}
154176
}

dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/RumHttpServletResponseWrapper.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public class RumHttpServletResponseWrapper extends HttpServletResponseWrapper {
1616
private PrintWriter printWriter;
1717
private boolean shouldInject = true;
1818
private long injectionStartTime = -1;
19+
private String contentEncoding = "none";
1920

2021
public RumHttpServletResponseWrapper(HttpServletResponse response) {
2122
super(response);
@@ -28,7 +29,7 @@ public ServletOutputStream getOutputStream() throws IOException {
2829
return outputStream;
2930
}
3031
if (!shouldInject) {
31-
RumInjector.getTelemetryCollector().onInjectionSkipped();
32+
RumInjector.getTelemetryCollector().onInjectionSkipped("5");
3233
return super.getOutputStream();
3334
}
3435
// start timing injection
@@ -45,9 +46,10 @@ public ServletOutputStream getOutputStream() throws IOException {
4546
super.getOutputStream(),
4647
rumInjector.getMarkerBytes(encoding),
4748
rumInjector.getSnippetBytes(encoding),
48-
this::onInjected);
49+
this::onInjected,
50+
bytes -> RumInjector.getTelemetryCollector().onInjectionResponseSize("5", bytes));
4951
} catch (Exception e) {
50-
RumInjector.getTelemetryCollector().onInjectionFailed();
52+
RumInjector.getTelemetryCollector().onInjectionFailed("5", contentEncoding);
5153
throw e;
5254
}
5355
return outputStream;
@@ -59,7 +61,7 @@ public PrintWriter getWriter() throws IOException {
5961
return printWriter;
6062
}
6163
if (!shouldInject) {
62-
RumInjector.getTelemetryCollector().onInjectionSkipped();
64+
RumInjector.getTelemetryCollector().onInjectionSkipped("5");
6365
return super.getWriter();
6466
}
6567
// start timing installation
@@ -75,7 +77,7 @@ public PrintWriter getWriter() throws IOException {
7577
this::onInjected);
7678
printWriter = new PrintWriter(wrappedPipeWriter);
7779
} catch (Exception e) {
78-
RumInjector.getTelemetryCollector().onInjectionFailed();
80+
RumInjector.getTelemetryCollector().onInjectionFailed("5", contentEncoding);
7981
throw e;
8082
}
8183

@@ -85,8 +87,11 @@ public PrintWriter getWriter() throws IOException {
8587
@Override
8688
public void setHeader(String name, String value) {
8789
if (name != null) {
88-
if (name.toLowerCase().startsWith("content-security-policy")) {
89-
RumInjector.getTelemetryCollector().onContentSecurityPolicyDetected();
90+
String lowerName = name.toLowerCase();
91+
if (lowerName.startsWith("content-security-policy")) {
92+
RumInjector.getTelemetryCollector().onContentSecurityPolicyDetected("5");
93+
} else if (lowerName.equals("content-encoding")) {
94+
this.contentEncoding = value;
9095
}
9196
}
9297
super.setHeader(name, value);
@@ -95,8 +100,11 @@ public void setHeader(String name, String value) {
95100
@Override
96101
public void addHeader(String name, String value) {
97102
if (name != null) {
98-
if (name.toLowerCase().startsWith("content-security-policy")) {
99-
RumInjector.getTelemetryCollector().onContentSecurityPolicyDetected();
103+
String lowerName = name.toLowerCase();
104+
if (lowerName.startsWith("content-security-policy")) {
105+
RumInjector.getTelemetryCollector().onContentSecurityPolicyDetected("5");
106+
} else if (lowerName.equals("content-encoding")) {
107+
this.contentEncoding = value;
100108
}
101109
}
102110
super.addHeader(name, value);
@@ -136,13 +144,13 @@ public void resetBuffer() {
136144
}
137145

138146
public void onInjected() {
139-
RumInjector.getTelemetryCollector().onInjectionSucceed();
147+
RumInjector.getTelemetryCollector().onInjectionSucceed("5");
140148

141149
// report injection time
142150
if (injectionStartTime != -1) {
143151
long nanoseconds = System.nanoTime() - injectionStartTime;
144152
long milliseconds = nanoseconds / 1_000_000L;
145-
RumInjector.getTelemetryCollector().onInjectionTime(milliseconds);
153+
RumInjector.getTelemetryCollector().onInjectionTime("5", milliseconds);
146154
injectionStartTime = -1;
147155
}
148156

dd-java-agent/instrumentation/servlet/request-5/src/main/java/datadog/trace/instrumentation/servlet5/WrappedServletOutputStream.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import jakarta.servlet.ServletOutputStream;
55
import jakarta.servlet.WriteListener;
66
import java.io.IOException;
7-
import java.io.OutputStream;
87
import java.util.function.LongConsumer;
98

109
public class WrappedServletOutputStream extends ServletOutputStream {

dd-java-agent/instrumentation/servlet/request-5/src/test/groovy/RumHttpServletResponseWrapperTest.groovy

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
2828
wrapper.onInjected()
2929

3030
then:
31-
1 * mockTelemetryCollector.onInjectionSucceed()
31+
1 * mockTelemetryCollector.onInjectionSucceed("5")
3232
}
3333

3434
void 'getOutputStream with non-HTML content reports skipped'() {
@@ -39,7 +39,7 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
3939
wrapper.getOutputStream()
4040

4141
then:
42-
1 * mockTelemetryCollector.onInjectionSkipped()
42+
1 * mockTelemetryCollector.onInjectionSkipped("5")
4343
1 * mockResponse.getOutputStream()
4444
}
4545

@@ -51,7 +51,7 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
5151
wrapper.getWriter()
5252

5353
then:
54-
1 * mockTelemetryCollector.onInjectionSkipped()
54+
1 * mockTelemetryCollector.onInjectionSkipped("5")
5555
1 * mockResponse.getWriter()
5656
}
5757

@@ -66,7 +66,7 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
6666
} catch (IOException ignored) {}
6767

6868
then:
69-
1 * mockTelemetryCollector.onInjectionFailed()
69+
1 * mockTelemetryCollector.onInjectionFailed("5", "none")
7070
}
7171

7272
void 'getWriter exception reports failure'() {
@@ -80,15 +80,15 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
8080
} catch (IOException ignored) {}
8181

8282
then:
83-
1 * mockTelemetryCollector.onInjectionFailed()
83+
1 * mockTelemetryCollector.onInjectionFailed("5", "none")
8484
}
8585

8686
void 'setHeader with Content-Security-Policy reports CSP detected'() {
8787
when:
8888
wrapper.setHeader("Content-Security-Policy", "test")
8989

9090
then:
91-
1 * mockTelemetryCollector.onContentSecurityPolicyDetected()
91+
1 * mockTelemetryCollector.onContentSecurityPolicyDetected("5")
9292
1 * mockResponse.setHeader("Content-Security-Policy", "test")
9393
}
9494

@@ -97,7 +97,7 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
9797
wrapper.addHeader("Content-Security-Policy", "test")
9898

9999
then:
100-
1 * mockTelemetryCollector.onContentSecurityPolicyDetected()
100+
1 * mockTelemetryCollector.onContentSecurityPolicyDetected("5")
101101
1 * mockResponse.addHeader("Content-Security-Policy", "test")
102102
}
103103

@@ -119,7 +119,29 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
119119
1 * mockResponse.addHeader("X-Content-Security-Policy", "test")
120120
}
121121

122-
void 'response sizes are reported correctly'() {
122+
// Callback is created in the RumHttpServletResponseWrapper and passed to InjectingPipeOutputStream via WrappedServletOutputStream.
123+
// When the stream is closed, the callback is called with the total number of bytes written to the stream.
124+
void 'response sizes are reported to the telemetry collector via the WrappedServletOutputStream callback'() {
125+
setup:
126+
def downstream = Mock(jakarta.servlet.ServletOutputStream)
127+
def marker = "</head>".getBytes("UTF-8")
128+
def contentToInject = "<script></script>".getBytes("UTF-8")
129+
def onBytesWritten = { bytes ->
130+
mockTelemetryCollector.onInjectionResponseSize("5", bytes)
131+
}
132+
def wrappedStream = new datadog.trace.instrumentation.servlet5.WrappedServletOutputStream(
133+
downstream, marker, contentToInject, null, onBytesWritten)
134+
135+
when:
136+
wrappedStream.write("test".getBytes("UTF-8"))
137+
wrappedStream.write("content".getBytes("UTF-8"))
138+
wrappedStream.close()
139+
140+
then:
141+
1 * mockTelemetryCollector.onInjectionResponseSize("5", 11)
142+
}
143+
144+
void 'response sizes are reported by the InjectingPipeOutputStream callback'() {
123145
setup:
124146
def downstream = Mock(java.io.OutputStream)
125147
def marker = "</head>".getBytes("UTF-8")
@@ -149,6 +171,6 @@ class RumHttpServletResponseWrapperTest extends AgentTestRunner {
149171
wrapper.onInjected() // report timing when injection "is successful"
150172

151173
then:
152-
1 * mockTelemetryCollector.onInjectionTime({ it > 0 })
174+
1 * mockTelemetryCollector.onInjectionTime("5", { it >= 0 })
153175
}
154176
}

0 commit comments

Comments
 (0)