From 189cc8515db5e99b147bb5b5b69d7cb6616c1930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?I=C3=B1igo=20Lopez=20de=20Heredia?= Date: Wed, 10 Jun 2026 15:21:24 +0200 Subject: [PATCH] Include git_commit_sha in client stats payload (APMSP-3043) --- .../metrics/SerializingMetricWriter.java | 2 +- .../SerializingMetricWriterTest.groovy | 60 +++++++++++++++++++ .../trace/api/WellKnownTagsTest.groovy | 10 ++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/dd-trace-core/src/main/java/datadog/trace/common/metrics/SerializingMetricWriter.java b/dd-trace-core/src/main/java/datadog/trace/common/metrics/SerializingMetricWriter.java index 972bd1e86ed..6a4582638aa 100644 --- a/dd-trace-core/src/main/java/datadog/trace/common/metrics/SerializingMetricWriter.java +++ b/dd-trace-core/src/main/java/datadog/trace/common/metrics/SerializingMetricWriter.java @@ -40,6 +40,7 @@ public final class SerializingMetricWriter implements MetricWriter { private static final byte[] OK_SUMMARY = "OkSummary".getBytes(ISO_8859_1); private static final byte[] ERROR_SUMMARY = "ErrorSummary".getBytes(ISO_8859_1); private static final byte[] PROCESS_TAGS = "ProcessTags".getBytes(ISO_8859_1); + private static final byte[] GIT_COMMIT_SHA = "GitCommitSha".getBytes(ISO_8859_1); private static final byte[] IS_TRACE_ROOT = "IsTraceRoot".getBytes(ISO_8859_1); private static final byte[] SPAN_KIND = "SpanKind".getBytes(ISO_8859_1); private static final byte[] PEER_TAGS = "PeerTags".getBytes(ISO_8859_1); @@ -47,7 +48,6 @@ public final class SerializingMetricWriter implements MetricWriter { private static final byte[] HTTP_ENDPOINT = "HTTPEndpoint".getBytes(ISO_8859_1); private static final byte[] GRPC_STATUS_CODE = "GRPCStatusCode".getBytes(ISO_8859_1); private static final byte[] SERVICE_SOURCE = "srv_src".getBytes(ISO_8859_1); - private static final byte[] GIT_COMMIT_SHA = "GitCommitSha".getBytes(ISO_8859_1); // Constant declared here for compile-time folding public static final int TRISTATE_TRUE = TriState.TRUE.serialValue; diff --git a/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SerializingMetricWriterTest.groovy b/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SerializingMetricWriterTest.groovy index cc0880bc30a..7d97810dba3 100644 --- a/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SerializingMetricWriterTest.groovy +++ b/dd-trace-core/src/test/groovy/datadog/trace/common/metrics/SerializingMetricWriterTest.groovy @@ -379,4 +379,64 @@ class SerializingMetricWriterTest extends DDSpecification { return validated } } + + def "ServiceSource optional in the payload"() { + setup: + long startTime = MILLISECONDS.toNanos(System.currentTimeMillis()) + long duration = SECONDS.toNanos(10) + WellKnownTags wellKnownTags = new WellKnownTags("runtimeid", "hostname", "env", "service", "version", "language") + + def keyWithNoSource = new MetricKey("resource", "service", "operation", null, "type", 200, false, false, "server", [], "GET", "/api/users") + def keyWithSource = new MetricKey("resource", "service", "operation", "source", "type", 200, false, false, "server", [], "POST", null) + + def content = [ + Pair.of(keyWithNoSource, new AggregateMetric().recordDurations(1, new AtomicLongArray(1L))), + Pair.of(keyWithSource, new AggregateMetric().recordDurations(1, new AtomicLongArray(1L))), + ] + + ValidatingSink sink = new ValidatingSink(wellKnownTags, startTime, duration, content) + SerializingMetricWriter writer = new SerializingMetricWriter(wellKnownTags, sink, 128) + + when: + writer.startBucket(content.size(), startTime, duration) + for (Pair pair : content) { + writer.add(pair.getLeft(), pair.getRight()) + } + writer.finishBucket() + + then: + sink.validatedInput() + } + + def "HTTPMethod and HTTPEndpoint fields are optional in payload"() { + setup: + long startTime = MILLISECONDS.toNanos(System.currentTimeMillis()) + long duration = SECONDS.toNanos(10) + WellKnownTags wellKnownTags = new WellKnownTags("runtimeid", "hostname", "env", "service", "version", "language") + + def keyWithBoth = new MetricKey("resource", "service", "operation", null, "type", 200, false, false, "server", [], "GET", "/api/users") + def keyWithMethodOnly = new MetricKey("resource", "service", "operation", null, "type", 200, false, false, "server", [], "POST", null) + def keyWithEndpointOnly = new MetricKey("resource", "service", "operation", null, "type", 200, false, false, "server", [], null, "/api/orders") + def keyWithNeither = new MetricKey("resource", "service", "operation", null, "type", 200, false, false, "client", [], null, null) + + def content = [ + Pair.of(keyWithBoth, new AggregateMetric().recordDurations(1, new AtomicLongArray(1L))), + Pair.of(keyWithMethodOnly, new AggregateMetric().recordDurations(1, new AtomicLongArray(1L))), + Pair.of(keyWithEndpointOnly, new AggregateMetric().recordDurations(1, new AtomicLongArray(1L))), + Pair.of(keyWithNeither, new AggregateMetric().recordDurations(1, new AtomicLongArray(1L))) + ] + + ValidatingSink sink = new ValidatingSink(wellKnownTags, startTime, duration, content) + SerializingMetricWriter writer = new SerializingMetricWriter(wellKnownTags, sink, 128) + + when: + writer.startBucket(content.size(), startTime, duration) + for (Pair pair : content) { + writer.add(pair.getLeft(), pair.getRight()) + } + writer.finishBucket() + + then: + sink.validatedInput() + } } diff --git a/internal-api/src/test/groovy/datadog/trace/api/WellKnownTagsTest.groovy b/internal-api/src/test/groovy/datadog/trace/api/WellKnownTagsTest.groovy index 6474142bced..d2d0f70d2d2 100644 --- a/internal-api/src/test/groovy/datadog/trace/api/WellKnownTagsTest.groovy +++ b/internal-api/src/test/groovy/datadog/trace/api/WellKnownTagsTest.groovy @@ -15,5 +15,15 @@ class WellKnownTagsTest extends DDSpecification { wellKnownTags.getService() as String == "service" wellKnownTags.getVersion() as String == "version" wellKnownTags.getLanguage() as String == "language" + wellKnownTags.getGitCommitSha() as String == "" + } + + def "well known tags with git commit sha"() { + given: + WellKnownTags wellKnownTags = + new WellKnownTags("runtimeid", "hostname", "env", "service", "version", "language", "abc123") + expect: + wellKnownTags.getRuntimeId() as String == "runtimeid" + wellKnownTags.getGitCommitSha() as String == "abc123" } }