Skip to content

Commit 8c4a17b

Browse files
committed
chore(css): Add peer tags, span kind and trace root flag to MetricKey bucket
1 parent 562e533 commit 8c4a17b

File tree

8 files changed

+403
-71
lines changed

8 files changed

+403
-71
lines changed

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import datadog.trace.core.CoreSpan;
2525
import datadog.trace.core.DDTraceCoreInfo;
2626
import datadog.trace.util.AgentTaskScheduler;
27+
import datadog.trace.util.TraceUtils;
28+
import java.util.ArrayList;
2729
import java.util.Collections;
2830
import java.util.List;
2931
import java.util.Map;
@@ -249,7 +251,10 @@ private boolean publish(CoreSpan<?> span, boolean isTopLevel) {
249251
span.getOperationName(),
250252
span.getType(),
251253
span.getHttpStatusCode(),
252-
isSynthetic(span));
254+
isSynthetic(span),
255+
span.isTopLevel(),
256+
span.getTag(SPAN_KIND, ""),
257+
getPeerTags(span));
253258
boolean isNewKey = false;
254259
MetricKey key = keys.putIfAbsent(newKey, newKey);
255260
if (null == key) {
@@ -284,6 +289,17 @@ private boolean publish(CoreSpan<?> span, boolean isTopLevel) {
284289
return isNewKey || span.getError() > 0;
285290
}
286291

292+
private List<CharSequence> getPeerTags(CoreSpan<?> span) {
293+
List<CharSequence> peerTags = new ArrayList<>();
294+
for (String peerTag : features.peerTags()) {
295+
Object value = span.getTag(peerTag);
296+
if (value != null) {
297+
peerTags.add(peerTag + ":" + TraceUtils.normalizeTag(value.toString()));
298+
}
299+
}
300+
return peerTags;
301+
}
302+
287303
private static boolean isSynthetic(CoreSpan<?> span) {
288304
return span.getOrigin() != null && SYNTHETICS_ORIGIN.equals(span.getOrigin().toString());
289305
}

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

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import static datadog.trace.bootstrap.instrumentation.api.UTF8BytesString.EMPTY;
44

55
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString;
6+
import java.util.Arrays;
7+
import java.util.List;
68

79
/** The aggregation key for tracked metrics. */
810
public final class MetricKey {
@@ -13,25 +15,45 @@ public final class MetricKey {
1315
private final int httpStatusCode;
1416
private final boolean synthetics;
1517
private final int hash;
18+
private final boolean isTraceRoot;
19+
private final UTF8BytesString spanKind;
20+
private final UTF8BytesString[] peerTags;
1621

1722
public MetricKey(
1823
CharSequence resource,
1924
CharSequence service,
2025
CharSequence operationName,
2126
CharSequence type,
2227
int httpStatusCode,
23-
boolean synthetics) {
28+
boolean synthetics,
29+
boolean isTraceRoot,
30+
CharSequence spanKind,
31+
List<CharSequence> peerTags) {
2432
this.resource = null == resource ? EMPTY : UTF8BytesString.create(resource);
2533
this.service = null == service ? EMPTY : UTF8BytesString.create(service);
2634
this.operationName = null == operationName ? EMPTY : UTF8BytesString.create(operationName);
2735
this.type = null == type ? EMPTY : UTF8BytesString.create(type);
2836
this.httpStatusCode = httpStatusCode;
2937
this.synthetics = synthetics;
30-
// unrolled polynomial hashcode which avoids allocating varargs
31-
// the constants are 31^5, 31^4, 31^3, 31^2, 31^1, 31^0
38+
this.isTraceRoot = isTraceRoot;
39+
this.spanKind = null == spanKind ? EMPTY : UTF8BytesString.create(spanKind);
40+
this.peerTags = new UTF8BytesString[peerTags.size()];
41+
for (int i = 0; i < peerTags.size(); i++) {
42+
this.peerTags[i] = UTF8BytesString.create(peerTags.get(i));
43+
}
44+
45+
// Unrolled polynomial hashcode to avoid varargs allocation
46+
// and eliminate data dependency between iterations as in Arrays.hashCode.
47+
// Coefficient constants are powers of 31, with integer overflow (hence negative numbers).
48+
// See
49+
// * https://richardstartin.github.io/posts/collecting-rocks-and-benchmarks
50+
// * https://richardstartin.github.io/posts/still-true-in-java-9-handwritten-hash-codes-are-faster
3251
this.hash =
33-
28629151 * this.resource.hashCode()
34-
+ 923521 * this.service.hashCode()
52+
-196513505 * Boolean.hashCode(this.isTraceRoot)
53+
+ -1807454463 * this.spanKind.hashCode()
54+
+ 887_503_681 * Arrays.hashCode(this.peerTags)
55+
+ 28_629_151 * this.resource.hashCode()
56+
+ 923_521 * this.service.hashCode()
3557
+ 29791 * this.operationName.hashCode()
3658
+ 961 * this.type.hashCode()
3759
+ 31 * httpStatusCode
@@ -62,6 +84,18 @@ public boolean isSynthetics() {
6284
return synthetics;
6385
}
6486

87+
public boolean isTraceRoot() {
88+
return isTraceRoot;
89+
}
90+
91+
public UTF8BytesString getSpanKind() {
92+
return spanKind;
93+
}
94+
95+
public UTF8BytesString[] getPeerTags() {
96+
return peerTags;
97+
}
98+
6599
@Override
66100
public boolean equals(Object o) {
67101
if (this == o) {
@@ -75,7 +109,10 @@ public boolean equals(Object o) {
75109
&& resource.equals(metricKey.resource)
76110
&& service.equals(metricKey.service)
77111
&& operationName.equals(metricKey.operationName)
78-
&& type.equals(metricKey.type);
112+
&& type.equals(metricKey.type)
113+
&& isTraceRoot == metricKey.isTraceRoot
114+
&& spanKind.equals(metricKey.spanKind)
115+
&& Arrays.equals(peerTags, metricKey.peerTags);
79116
}
80117
return false;
81118
}

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

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ public final class SerializingMetricWriter implements MetricWriter {
3131
private static final byte[] OK_SUMMARY = "OkSummary".getBytes(ISO_8859_1);
3232
private static final byte[] ERROR_SUMMARY = "ErrorSummary".getBytes(ISO_8859_1);
3333
private static final byte[] PROCESS_TAGS = "ProcessTags".getBytes(ISO_8859_1);
34+
private static final byte[] IS_TRACE_ROOT = "IsTraceRoot".getBytes(ISO_8859_1);
35+
private static final byte[] SPAN_KIND = "SpanKind".getBytes(ISO_8859_1);
36+
private static final byte[] PEER_TAGS = "PeerTags".getBytes(ISO_8859_1);
3437

3538
private final WellKnownTags wellKnownTags;
3639
private final WritableFormatter writer;
@@ -93,8 +96,7 @@ public void startBucket(int metricCount, long start, long duration) {
9396

9497
@Override
9598
public void add(MetricKey key, AggregateMetric aggregate) {
96-
97-
writer.startMap(12);
99+
writer.startMap(15);
98100

99101
writer.writeUTF8(NAME);
100102
writer.writeUTF8(key.getOperationName());
@@ -114,6 +116,19 @@ public void add(MetricKey key, AggregateMetric aggregate) {
114116
writer.writeUTF8(SYNTHETICS);
115117
writer.writeBoolean(key.isSynthetics());
116118

119+
writer.writeUTF8(IS_TRACE_ROOT);
120+
writer.writeBoolean(key.isTraceRoot());
121+
122+
writer.writeUTF8(SPAN_KIND);
123+
writer.writeUTF8(key.getSpanKind());
124+
125+
writer.writeUTF8(PEER_TAGS);
126+
UTF8BytesString[] peerTags = key.getPeerTags();
127+
writer.startArray(peerTags.length);
128+
for (UTF8BytesString peerTag : peerTags) {
129+
writer.writeUTF8(peerTag);
130+
}
131+
117132
writer.writeUTF8(HITS);
118133
writer.writeInt(aggregate.getHitCount());
119134

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class AggregateMetricTest extends DDSpecification {
5151
given:
5252
AggregateMetric aggregate = new AggregateMetric().recordDurations(3, new AtomicLongArray(0L, 0L, 0L | ERROR_TAG | TOP_LEVEL_TAG))
5353

54-
Batch batch = new Batch().reset(new MetricKey("foo", "bar", "qux", "type", 0, false))
54+
Batch batch = new Batch().reset(new MetricKey("foo", "bar", "qux", "type", 0, false, true, "corge", ["grault"]))
5555
batch.add(0L, 10)
5656
batch.add(0L, 10)
5757
batch.add(0L, 10)
@@ -126,7 +126,7 @@ class AggregateMetricTest extends DDSpecification {
126126
def "consistent under concurrent attempts to read and write"() {
127127
given:
128128
AggregateMetric aggregate = new AggregateMetric()
129-
MetricKey key = new MetricKey("foo", "bar", "qux", "type", 0, false)
129+
MetricKey key = new MetricKey("foo", "bar", "qux", "type", 0, false, true, "corge", ["grault"])
130130
BlockingDeque<Batch> queue = new LinkedBlockingDeque<>(1000)
131131
ExecutorService reader = Executors.newSingleThreadExecutor()
132132
int writerCount = 10

0 commit comments

Comments
 (0)