diff --git a/dd-trace-core/src/main/java/datadog/trace/common/metrics/ConflatingMetricsAggregator.java b/dd-trace-core/src/main/java/datadog/trace/common/metrics/ConflatingMetricsAggregator.java
index 2cfb4e8f3b4..9eaa0f34ad5 100644
--- a/dd-trace-core/src/main/java/datadog/trace/common/metrics/ConflatingMetricsAggregator.java
+++ b/dd-trace-core/src/main/java/datadog/trace/common/metrics/ConflatingMetricsAggregator.java
@@ -293,6 +293,8 @@ public boolean publish(List extends CoreSpan>> trace) {
private boolean shouldComputeMetric(CoreSpan> span) {
return (span.isMeasured() || span.isTopLevel() || spanKindEligible(span))
+ && span.getLongRunningVersion()
+ <= 0 // either not long-running or unpublished long-running span
&& span.getDurationNano() > 0;
}
diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreSpan.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreSpan.java
index ce088ee9512..7c3e65e0d41 100644
--- a/dd-trace-core/src/main/java/datadog/trace/core/CoreSpan.java
+++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreSpan.java
@@ -114,4 +114,14 @@ T setSamplingPriority(
* @return this
*/
T setMetaStruct(final String field, final Object value);
+
+ /**
+ * Version of a span that can be set by the long running spans feature:
+ *
eq 0 -> span is not long running.
+ * lt 0 -> finished span that had running versions previously written.
+ * gt 0 -> long running span and its write version.
+ *
+ * @return the version.
+ */
+ int getLongRunningVersion();
}
diff --git a/dd-trace-core/src/main/java/datadog/trace/core/DDSpan.java b/dd-trace-core/src/main/java/datadog/trace/core/DDSpan.java
index ac457e3dcbe..05a1ec50eb8 100644
--- a/dd-trace-core/src/main/java/datadog/trace/core/DDSpan.java
+++ b/dd-trace-core/src/main/java/datadog/trace/core/DDSpan.java
@@ -869,4 +869,9 @@ public void copyPropagationAndBaggage(final AgentSpan source) {
sourceSpanContext.getBaggageItems().forEach(context::setBaggageItem);
}
}
+
+ @Override
+ public int getLongRunningVersion() {
+ return longRunningVersion;
+ }
}
diff --git a/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/ConflatingMetricAggregatorTest.groovy b/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/ConflatingMetricAggregatorTest.groovy
index aa110058a01..52c1bb34de1 100644
--- a/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/ConflatingMetricAggregatorTest.groovy
+++ b/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/ConflatingMetricAggregatorTest.groovy
@@ -820,6 +820,48 @@ class ConflatingMetricAggregatorTest extends DDSpecification {
aggregator.close()
}
+ def "should not count partial snapshot(long running)"() {
+ setup:
+ MetricWriter writer = Mock(MetricWriter)
+ Sink sink = Stub(Sink)
+ DDAgentFeaturesDiscovery features = Mock(DDAgentFeaturesDiscovery)
+ features.supportsMetrics() >> true
+ ConflatingMetricsAggregator aggregator = new ConflatingMetricsAggregator(empty,
+ features, HealthMetrics.NO_OP, sink, writer, 10, queueSize, reportingInterval, SECONDS)
+ aggregator.start()
+
+ when:
+ CountDownLatch latch = new CountDownLatch(1)
+ aggregator.publish([
+ new SimpleSpan("service", "operation", "resource", "type", true, true, false, 0, 100, HTTP_OK, true, 12345),
+ new SimpleSpan("service", "operation", "resource", "type", true, true, false, 0, 100, HTTP_OK, true, 0)
+ ])
+ aggregator.report()
+ def latchTriggered = latch.await(2, SECONDS)
+
+ then:
+ latchTriggered
+ 1 * writer.startBucket(1, _, _)
+ 1 * writer.add(
+ new MetricKey(
+ "resource",
+ "service",
+ "operation",
+ "type",
+ HTTP_OK,
+ false,
+ true,
+ "",
+ []
+ ), { AggregateMetric aggregateMetric ->
+ aggregateMetric.getHitCount() == 1 && aggregateMetric.getTopLevelCount() == 1 && aggregateMetric.getDuration() == 100
+ })
+ 1 * writer.finishBucket() >> { latch.countDown() }
+
+ cleanup:
+ aggregator.close()
+ }
+
def reportAndWaitUntilEmpty(ConflatingMetricsAggregator aggregator) {
waitUntilEmpty(aggregator)
aggregator.report()
diff --git a/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SimpleSpan.groovy b/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SimpleSpan.groovy
index b16dd7a365e..ec2b3b73ce5 100644
--- a/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SimpleSpan.groovy
+++ b/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SimpleSpan.groovy
@@ -19,6 +19,7 @@ class SimpleSpan implements CoreSpan {
private final long duration
private final long startTime
+ private final long longRunningVersion
private final Map