1
1
package datadog .trace .common .metrics ;
2
2
3
3
import static datadog .communication .ddagent .DDAgentFeaturesDiscovery .V6_METRICS_ENDPOINT ;
4
+ import static datadog .trace .api .DDTags .BASE_SERVICE ;
4
5
import static datadog .trace .api .Functions .UTF8_ENCODE ;
5
6
import static datadog .trace .bootstrap .instrumentation .api .Tags .SPAN_KIND ;
6
7
import static datadog .trace .bootstrap .instrumentation .api .Tags .SPAN_KIND_CLIENT ;
7
8
import static datadog .trace .bootstrap .instrumentation .api .Tags .SPAN_KIND_CONSUMER ;
9
+ import static datadog .trace .bootstrap .instrumentation .api .Tags .SPAN_KIND_INTERNAL ;
8
10
import static datadog .trace .bootstrap .instrumentation .api .Tags .SPAN_KIND_PRODUCER ;
9
11
import static datadog .trace .bootstrap .instrumentation .api .Tags .SPAN_KIND_SERVER ;
10
12
import static datadog .trace .common .metrics .AggregateMetric .ERROR_TAG ;
@@ -75,12 +77,15 @@ public final class ConflatingMetricsAggregator implements MetricsAggregator, Eve
75
77
value -> UTF8BytesString .create (key + ":" + value ));
76
78
private static final CharSequence SYNTHETICS_ORIGIN = "synthetics" ;
77
79
78
- private static final Set <String > ELIGIBLE_SPAN_KINDS =
80
+ private static final Set <String > ELIGIBLE_SPAN_KINDS_FOR_METRICS =
79
81
unmodifiableSet (
80
82
new HashSet <>(
81
83
Arrays .asList (
82
84
SPAN_KIND_SERVER , SPAN_KIND_CLIENT , SPAN_KIND_CONSUMER , SPAN_KIND_PRODUCER )));
83
85
86
+ private static final Set <String > ELIGIBLE_SPAN_KINDS_FOR_PEER_AGGREGATION =
87
+ unmodifiableSet (new HashSet <>(Arrays .asList (SPAN_KIND_CLIENT , SPAN_KIND_PRODUCER )));
88
+
84
89
private final Set <String > ignoredResources ;
85
90
private final Queue <Batch > batchPool ;
86
91
private final NonBlockingHashMap <MetricKey , Batch > pending ;
@@ -269,10 +274,11 @@ private boolean shouldComputeMetric(CoreSpan<?> span) {
269
274
private boolean spanKindEligible (CoreSpan <?> span ) {
270
275
final Object spanKind = span .getTag (SPAN_KIND );
271
276
// use toString since it could be a CharSequence...
272
- return spanKind != null && ELIGIBLE_SPAN_KINDS .contains (spanKind .toString ());
277
+ return spanKind != null && ELIGIBLE_SPAN_KINDS_FOR_METRICS .contains (spanKind .toString ());
273
278
}
274
279
275
280
private boolean publish (CoreSpan <?> span , boolean isTopLevel ) {
281
+ final CharSequence spanKind = span .getTag (SPAN_KIND , "" );
276
282
MetricKey newKey =
277
283
new MetricKey (
278
284
span .getResourceName (),
@@ -282,8 +288,9 @@ private boolean publish(CoreSpan<?> span, boolean isTopLevel) {
282
288
span .getHttpStatusCode (),
283
289
isSynthetic (span ),
284
290
span .isTopLevel (),
285
- SPAN_KINDS .computeIfAbsent (span .getTag (SPAN_KIND , "" ), UTF8BytesString ::create ),
286
- getPeerTags (span ));
291
+ SPAN_KINDS .computeIfAbsent (
292
+ spanKind , UTF8BytesString ::create ), // save repeated utf8 conversions
293
+ getPeerTags (span , spanKind .toString ()));
287
294
boolean isNewKey = false ;
288
295
MetricKey key = keys .putIfAbsent (newKey , newKey );
289
296
if (null == key ) {
@@ -318,17 +325,32 @@ private boolean publish(CoreSpan<?> span, boolean isTopLevel) {
318
325
return isNewKey || span .getError () > 0 ;
319
326
}
320
327
321
- private List <UTF8BytesString > getPeerTags (CoreSpan <?> span ) {
322
- List <UTF8BytesString > peerTags = new ArrayList <>();
323
- for (String peerTag : features .peerTags ()) {
324
- Object value = span .getTag (peerTag );
325
- if (value != null ) {
326
- final Pair <DDCache <String , UTF8BytesString >, Function <String , UTF8BytesString >> pair =
327
- PEER_TAGS_CACHE .computeIfAbsent (peerTag , PEER_TAGS_CACHE_ADDER );
328
- peerTags .add (pair .getLeft ().computeIfAbsent (value .toString (), pair .getRight ()));
328
+ private List <UTF8BytesString > getPeerTags (CoreSpan <?> span , String spanKind ) {
329
+ if (ELIGIBLE_SPAN_KINDS_FOR_PEER_AGGREGATION .contains (spanKind )) {
330
+ List <UTF8BytesString > peerTags = new ArrayList <>();
331
+ for (String peerTag : features .peerTags ()) {
332
+ Object value = span .getTag (peerTag );
333
+ if (value != null ) {
334
+ final Pair <DDCache <String , UTF8BytesString >, Function <String , UTF8BytesString >>
335
+ cacheAndCreator = PEER_TAGS_CACHE .computeIfAbsent (peerTag , PEER_TAGS_CACHE_ADDER );
336
+ peerTags .add (
337
+ cacheAndCreator
338
+ .getLeft ()
339
+ .computeIfAbsent (value .toString (), cacheAndCreator .getRight ()));
340
+ }
341
+ }
342
+ return peerTags ;
343
+ } else if (SPAN_KIND_INTERNAL .equals (spanKind )) {
344
+ // in this case only the base service should be aggregated if present
345
+ final String baseService = span .getTag (BASE_SERVICE );
346
+ if (baseService != null ) {
347
+ final Pair <DDCache <String , UTF8BytesString >, Function <String , UTF8BytesString >>
348
+ cacheAndCreator = PEER_TAGS_CACHE .computeIfAbsent (BASE_SERVICE , PEER_TAGS_CACHE_ADDER );
349
+ return Collections .singletonList (
350
+ cacheAndCreator .getLeft ().computeIfAbsent (baseService , cacheAndCreator .getRight ()));
329
351
}
330
352
}
331
- return peerTags ;
353
+ return Collections . emptyList () ;
332
354
}
333
355
334
356
private static boolean isSynthetic (CoreSpan <?> span ) {
0 commit comments