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 ;
@@ -76,12 +78,15 @@ public final class ConflatingMetricsAggregator implements MetricsAggregator, Eve
76
78
value -> UTF8BytesString .create (key + ":" + value ));
77
79
private static final CharSequence SYNTHETICS_ORIGIN = "synthetics" ;
78
80
79
- private static final Set <String > ELIGIBLE_SPAN_KINDS =
81
+ private static final Set <String > ELIGIBLE_SPAN_KINDS_FOR_METRICS =
80
82
unmodifiableSet (
81
83
new HashSet <>(
82
84
Arrays .asList (
83
85
SPAN_KIND_SERVER , SPAN_KIND_CLIENT , SPAN_KIND_CONSUMER , SPAN_KIND_PRODUCER )));
84
86
87
+ private static final Set <String > ELIGIBLE_SPAN_KINDS_FOR_PEER_AGGREGATION =
88
+ unmodifiableSet (new HashSet <>(Arrays .asList (SPAN_KIND_CLIENT , SPAN_KIND_PRODUCER )));
89
+
85
90
private final Set <String > ignoredResources ;
86
91
private final Queue <Batch > batchPool ;
87
92
private final NonBlockingHashMap <MetricKey , Batch > pending ;
@@ -293,10 +298,11 @@ private boolean shouldComputeMetric(CoreSpan<?> span) {
293
298
private boolean spanKindEligible (CoreSpan <?> span ) {
294
299
final Object spanKind = span .getTag (SPAN_KIND );
295
300
// use toString since it could be a CharSequence...
296
- return spanKind != null && ELIGIBLE_SPAN_KINDS .contains (spanKind .toString ());
301
+ return spanKind != null && ELIGIBLE_SPAN_KINDS_FOR_METRICS .contains (spanKind .toString ());
297
302
}
298
303
299
304
private boolean publish (CoreSpan <?> span , boolean isTopLevel ) {
305
+ final CharSequence spanKind = span .getTag (SPAN_KIND , "" );
300
306
MetricKey newKey =
301
307
new MetricKey (
302
308
span .getResourceName (),
@@ -306,8 +312,9 @@ private boolean publish(CoreSpan<?> span, boolean isTopLevel) {
306
312
span .getHttpStatusCode (),
307
313
isSynthetic (span ),
308
314
span .isTopLevel (),
309
- SPAN_KINDS .computeIfAbsent (span .getTag (SPAN_KIND , "" ), UTF8BytesString ::create ),
310
- getPeerTags (span ));
315
+ SPAN_KINDS .computeIfAbsent (
316
+ spanKind , UTF8BytesString ::create ), // save repeated utf8 conversions
317
+ getPeerTags (span , spanKind .toString ()));
311
318
boolean isNewKey = false ;
312
319
MetricKey key = keys .putIfAbsent (newKey , newKey );
313
320
if (null == key ) {
@@ -342,17 +349,32 @@ private boolean publish(CoreSpan<?> span, boolean isTopLevel) {
342
349
return isNewKey || span .getError () > 0 ;
343
350
}
344
351
345
- private List <UTF8BytesString > getPeerTags (CoreSpan <?> span ) {
346
- List <UTF8BytesString > peerTags = new ArrayList <>();
347
- for (String peerTag : features .peerTags ()) {
348
- Object value = span .getTag (peerTag );
349
- if (value != null ) {
350
- final Pair <DDCache <String , UTF8BytesString >, Function <String , UTF8BytesString >> pair =
351
- PEER_TAGS_CACHE .computeIfAbsent (peerTag , PEER_TAGS_CACHE_ADDER );
352
- peerTags .add (pair .getLeft ().computeIfAbsent (value .toString (), pair .getRight ()));
352
+ private List <UTF8BytesString > getPeerTags (CoreSpan <?> span , String spanKind ) {
353
+ if (ELIGIBLE_SPAN_KINDS_FOR_PEER_AGGREGATION .contains (spanKind )) {
354
+ List <UTF8BytesString > peerTags = new ArrayList <>();
355
+ for (String peerTag : features .peerTags ()) {
356
+ Object value = span .getTag (peerTag );
357
+ if (value != null ) {
358
+ final Pair <DDCache <String , UTF8BytesString >, Function <String , UTF8BytesString >>
359
+ cacheAndCreator = PEER_TAGS_CACHE .computeIfAbsent (peerTag , PEER_TAGS_CACHE_ADDER );
360
+ peerTags .add (
361
+ cacheAndCreator
362
+ .getLeft ()
363
+ .computeIfAbsent (value .toString (), cacheAndCreator .getRight ()));
364
+ }
365
+ }
366
+ return peerTags ;
367
+ } else if (SPAN_KIND_INTERNAL .equals (spanKind )) {
368
+ // in this case only the base service should be aggregated if present
369
+ final String baseService = span .getTag (BASE_SERVICE );
370
+ if (baseService != null ) {
371
+ final Pair <DDCache <String , UTF8BytesString >, Function <String , UTF8BytesString >>
372
+ cacheAndCreator = PEER_TAGS_CACHE .computeIfAbsent (BASE_SERVICE , PEER_TAGS_CACHE_ADDER );
373
+ return Collections .singletonList (
374
+ cacheAndCreator .getLeft ().computeIfAbsent (baseService , cacheAndCreator .getRight ()));
353
375
}
354
376
}
355
- return peerTags ;
377
+ return Collections . emptyList () ;
356
378
}
357
379
358
380
private static boolean isSynthetic (CoreSpan <?> span ) {
0 commit comments