Skip to content

Commit 4fb1b2e

Browse files
authored
Fix npe on ConflatingMetricsAggregator when the resource is null (#9909)
1 parent 4255dc0 commit 4fb1b2e

File tree

2 files changed

+49
-7
lines changed

2 files changed

+49
-7
lines changed

dd-trace-core/src/main/java/datadog/trace/common/metrics/ConflatingMetricsAggregator.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,8 @@ public boolean publish(List<? extends CoreSpan<?>> trace) {
277277
for (CoreSpan<?> span : trace) {
278278
boolean isTopLevel = span.isTopLevel();
279279
if (shouldComputeMetric(span)) {
280-
if (ignoredResources.contains(span.getResourceName().toString())) {
280+
final CharSequence resourceName = span.getResourceName();
281+
if (resourceName != null && ignoredResources.contains(resourceName.toString())) {
281282
// skip publishing all children
282283
forceKeep = false;
283284
break;

dd-trace-core/src/test/groovy/datadog/trace/common/metrics/ConflatingMetricAggregatorTest.groovy

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
package datadog.trace.common.metrics
22

3+
import static datadog.trace.bootstrap.instrumentation.api.Tags.SPAN_KIND
4+
import static java.util.concurrent.TimeUnit.MILLISECONDS
5+
import static java.util.concurrent.TimeUnit.SECONDS
6+
37
import datadog.communication.ddagent.DDAgentFeaturesDiscovery
48
import datadog.trace.api.WellKnownTags
59
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString
610
import datadog.trace.core.CoreSpan
711
import datadog.trace.core.monitor.HealthMetrics
812
import datadog.trace.test.util.DDSpecification
9-
import spock.lang.Shared
10-
1113
import java.util.concurrent.CompletableFuture
1214
import java.util.concurrent.CountDownLatch
1315
import java.util.concurrent.TimeUnit
1416
import java.util.concurrent.TimeoutException
1517
import java.util.function.Supplier
16-
17-
import static datadog.trace.bootstrap.instrumentation.api.Tags.SPAN_KIND
18-
import static java.util.concurrent.TimeUnit.MILLISECONDS
19-
import static java.util.concurrent.TimeUnit.SECONDS
18+
import spock.lang.Shared
2019

2120
class ConflatingMetricAggregatorTest extends DDSpecification {
2221

@@ -96,6 +95,48 @@ class ConflatingMetricAggregatorTest extends DDSpecification {
9695
aggregator.close()
9796
}
9897

98+
def "should be resilient to null resource names"() {
99+
setup:
100+
MetricWriter writer = Mock(MetricWriter)
101+
Sink sink = Stub(Sink)
102+
DDAgentFeaturesDiscovery features = Mock(DDAgentFeaturesDiscovery)
103+
features.supportsMetrics() >> true
104+
features.peerTags() >> []
105+
ConflatingMetricsAggregator aggregator = new ConflatingMetricsAggregator(empty,
106+
features, HealthMetrics.NO_OP, sink, writer, 10, queueSize, reportingInterval, SECONDS)
107+
aggregator.start()
108+
109+
when:
110+
CountDownLatch latch = new CountDownLatch(1)
111+
aggregator.publish([
112+
new SimpleSpan("service", "operation", null, "type", false, true, false, 0, 100, HTTP_OK)
113+
.setTag(SPAN_KIND, "baz")
114+
])
115+
aggregator.report()
116+
def latchTriggered = latch.await(2, SECONDS)
117+
118+
then:
119+
latchTriggered
120+
1 * writer.startBucket(1, _, _)
121+
1 * writer.add(new MetricKey(
122+
null,
123+
"service",
124+
"operation",
125+
"type",
126+
HTTP_OK,
127+
false,
128+
false,
129+
"baz",
130+
[]
131+
), _) >> { MetricKey key, AggregateMetric value ->
132+
value.getHitCount() == 1 && value.getTopLevelCount() == 1 && value.getDuration() == 100
133+
}
134+
1 * writer.finishBucket() >> { latch.countDown() }
135+
136+
cleanup:
137+
aggregator.close()
138+
}
139+
99140
def "unmeasured top level spans have metrics computed"() {
100141
setup:
101142
MetricWriter writer = Mock(MetricWriter)

0 commit comments

Comments
 (0)