Skip to content

Commit 07db174

Browse files
committed
Add injection initialization success telemetry
1 parent 23e0455 commit 07db174

File tree

5 files changed

+78
-3
lines changed

5 files changed

+78
-3
lines changed

internal-api/src/main/java/datadog/trace/api/rum/RumInjector.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ public static void enableTelemetry(datadog.trace.api.StatsDClient statsDClient)
132132
RumInjectorMetrics metrics = new RumInjectorMetrics(statsDClient);
133133
metrics.start();
134134
telemetryCollector = metrics;
135+
136+
if (INSTANCE.isEnabled()) {
137+
telemetryCollector.onInitializationSucceed();
138+
}
135139
} else {
136140
telemetryCollector = RumTelemetryCollector.NO_OP;
137141
}

internal-api/src/main/java/datadog/trace/api/rum/RumInjectorMetrics.java

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ public class RumInjectorMetrics implements RumTelemetryCollector {
2424
private final AtomicLong injectionFailed = new AtomicLong();
2525
private final AtomicLong injectionSkipped = new AtomicLong();
2626
private final AtomicLong contentSecurityPolicyDetected = new AtomicLong();
27+
private final AtomicLong initializationSucceed = new AtomicLong();
2728

2829
private final StatsDClient statsd;
2930
private final long interval;
@@ -62,6 +63,11 @@ public void onInjectionSkipped() {
6263
injectionSkipped.incrementAndGet();
6364
}
6465

66+
@Override
67+
public void onInitializationSucceed() {
68+
initializationSucceed.incrementAndGet();
69+
}
70+
6571
@Override
6672
public void onContentSecurityPolicyDetected() {
6773
contentSecurityPolicyDetected.incrementAndGet();
@@ -93,12 +99,14 @@ public String summary() {
9399
+ "\ninjectionSkipped="
94100
+ injectionSkipped.get()
95101
+ "\ncontentSecurityPolicyDetected="
96-
+ contentSecurityPolicyDetected.get();
102+
+ contentSecurityPolicyDetected.get()
103+
+ "\ninitializationSucceed="
104+
+ initializationSucceed.get();
97105
}
98106

99107
private static class Flush implements AgentTaskScheduler.Task<RumInjectorMetrics> {
100108

101-
private final long[] previousCounts = new long[4]; // one per counter
109+
private final long[] previousCounts = new long[5]; // one per counter
102110
private int countIndex;
103111

104112
@Override
@@ -113,6 +121,11 @@ public void run(RumInjectorMetrics target) {
113121
"rum.injection.content_security_policy",
114122
target.contentSecurityPolicyDetected,
115123
NO_TAGS);
124+
reportIfChanged(
125+
target.statsd,
126+
"rum.injection.initialization.succeed",
127+
target.initializationSucceed,
128+
NO_TAGS);
116129
} catch (ArrayIndexOutOfBoundsException e) {
117130
log.warn(
118131
"previousCounts array needs resizing to at least {}, was {}",

internal-api/src/main/java/datadog/trace/api/rum/RumTelemetryCollector.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public void onInjectionFailed() {}
1818
@Override
1919
public void onInjectionSkipped() {}
2020

21+
@Override
22+
public void onInitializationSucceed() {}
23+
2124
@Override
2225
public void onContentSecurityPolicyDetected() {}
2326

@@ -47,6 +50,9 @@ default void start() {}
4750
// call when RUM injection is skipped
4851
void onInjectionSkipped();
4952

53+
// call when RUM injector initialization succeeds
54+
void onInitializationSucceed();
55+
5056
// call when a Content Security Policy header is detected
5157
void onContentSecurityPolicyDetected();
5258

internal-api/src/test/groovy/datadog/trace/api/rum/RumInjectorMetricsTest.groovy

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,27 @@ class RumInjectorMetricsTest extends Specification {
8585
metrics.close()
8686
}
8787

88+
def "test onInitializationSucceed"() {
89+
setup:
90+
def latch = new CountDownLatch(1)
91+
def metrics = new RumInjectorMetrics(new Latched(statsD, latch), 10, TimeUnit.MILLISECONDS)
92+
metrics.start()
93+
94+
when:
95+
metrics.onInitializationSucceed()
96+
latch.await(5, TimeUnit.SECONDS)
97+
98+
then:
99+
1 * statsD.count('rum.injection.initialization.succeed', 1, _)
100+
0 * _
101+
102+
cleanup:
103+
metrics.close()
104+
}
105+
88106
def "test multiple events"() {
89107
setup:
90-
def latch = new CountDownLatch(4) // expecting 4 metric types
108+
def latch = new CountDownLatch(5) // expecting 5 metric types
91109
def metrics = new RumInjectorMetrics(new Latched(statsD, latch), 10, TimeUnit.MILLISECONDS)
92110
metrics.start()
93111

@@ -96,13 +114,15 @@ class RumInjectorMetricsTest extends Specification {
96114
metrics.onInjectionFailed()
97115
metrics.onInjectionSkipped()
98116
metrics.onContentSecurityPolicyDetected()
117+
metrics.onInitializationSucceed()
99118
latch.await(5, TimeUnit.SECONDS)
100119

101120
then:
102121
1 * statsD.count('rum.injection.succeed', 1, _)
103122
1 * statsD.count('rum.injection.failed', 1, _)
104123
1 * statsD.count('rum.injection.skipped', 1, _)
105124
1 * statsD.count('rum.injection.content_security_policy', 1, _)
125+
1 * statsD.count('rum.injection.initialization.succeed', 1, _)
106126
0 * _
107127

108128
cleanup:
@@ -142,13 +162,15 @@ class RumInjectorMetricsTest extends Specification {
142162
metrics.onInjectionSucceed()
143163
metrics.onInjectionSkipped()
144164
metrics.onContentSecurityPolicyDetected()
165+
metrics.onInitializationSucceed()
145166
def summary = metrics.summary()
146167

147168
then:
148169
summary.contains("injectionSucceed=3")
149170
summary.contains("injectionFailed=2")
150171
summary.contains("injectionSkipped=1")
151172
summary.contains("contentSecurityPolicyDetected=2")
173+
summary.contains("initializationSucceed=1")
152174
0 * _
153175
}
154176

@@ -161,6 +183,7 @@ class RumInjectorMetricsTest extends Specification {
161183
summary.contains("injectionFailed=0")
162184
summary.contains("injectionSkipped=0")
163185
summary.contains("contentSecurityPolicyDetected=0")
186+
summary.contains("initializationSucceed=0")
164187
0 * _
165188
}
166189

internal-api/src/test/groovy/datadog/trace/api/rum/RumInjectorTest.groovy

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,20 @@ class RumInjectorTest extends DDSpecification {
118118
RumInjector.getTelemetryCollector() == RumTelemetryCollector.NO_OP
119119
}
120120

121+
void 'content security policy HTTP response detected'() {
122+
when:
123+
RumInjector.enableTelemetry(mock(datadog.trace.api.StatsDClient))
124+
def telemetryCollector = RumInjector.getTelemetryCollector()
125+
telemetryCollector.onContentSecurityPolicyDetected()
126+
def summary = telemetryCollector.summary()
127+
128+
then:
129+
summary.contains("contentSecurityPolicyDetected=1")
130+
131+
cleanup:
132+
RumInjector.shutdownTelemetry()
133+
}
134+
121135
void 'telemetry integration works end-to-end'() {
122136
when:
123137
// simulate CoreTracer enabling telemetry
@@ -140,6 +154,7 @@ class RumInjectorTest extends DDSpecification {
140154
summary.contains("injectionFailed=1")
141155
summary.contains("injectionSkipped=1")
142156
summary.contains("contentSecurityPolicyDetected=1")
157+
summary.contains("initializationSucceed=0") // rum injector not initialized in test environment
143158

144159
cleanup:
145160
RumInjector.shutdownTelemetry()
@@ -216,4 +231,18 @@ class RumInjectorTest extends DDSpecification {
216231
cleanup:
217232
RumInjector.shutdownTelemetry()
218233
}
234+
235+
void 'initialize rum injector successfully'() {
236+
when:
237+
RumInjector.enableTelemetry(mock(datadog.trace.api.StatsDClient))
238+
def telemetryCollector = RumInjector.getTelemetryCollector()
239+
telemetryCollector.onInitializationSucceed()
240+
def summary = telemetryCollector.summary()
241+
242+
then:
243+
summary.contains("initializationSucceed=1")
244+
245+
cleanup:
246+
RumInjector.shutdownTelemetry()
247+
}
219248
}

0 commit comments

Comments
 (0)