Skip to content

Commit 251d95a

Browse files
committed
Add recording of metrics for Core Tracing options
1 parent 94e43ec commit 251d95a

File tree

6 files changed

+93
-15
lines changed

6 files changed

+93
-15
lines changed

newrelic/common/streaming_utils.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import collections
1616
import logging
1717
import threading
18+
from newrelic.packages import objsize
1819

1920
try:
2021
from newrelic.core.infinite_tracing_pb2 import AttributeValue, SpanBatch
@@ -32,6 +33,11 @@ def __init__(self, maxlen, batching=False):
3233
self._shutdown = False
3334
self._seen = 0
3435
self._dropped = 0
36+
self._ft_seen = 0
37+
self._ft_dropped = 0
38+
self._bytes = 0
39+
self._ft_bytes = 0
40+
self._ct_bytes = 0
3541
self._settings = None
3642

3743
self.batching = batching
@@ -45,12 +51,30 @@ def shutdown(self):
4551
self._shutdown = True
4652
self._notify.notify_all()
4753

54+
def is_ft(self, sample, entity_relationship_attrs):
55+
# It's a FT span if it's an exit or entry span.
56+
return entity_relationship_attrs or not sample.intrinsics.get("parentId")
57+
4858
def put(self, item):
4959
with self._notify:
5060
if self._shutdown:
5161
return
5262

63+
entity_relationship_attrs = item[1]
64+
item = item[0]
5365
self._seen += 1
66+
# The last index contains the set of entity synthesis attrs in the span.
67+
self._bytes += objsize.get_deep_size([item.intrinsics, item.user_attributes, item.agent_attributes])
68+
if self.is_ft(item, entity_relationship_attrs):
69+
self._ft_seen += 1
70+
# The last index contains the set of entity synthesis attrs in the span.
71+
self._ft_bytes += objsize.get_deep_size([item.intrinsics, item.user_attributes, item.agent_attributes])
72+
73+
i_ct_attrs = {"type", "name", "guid", "parentId", "transaction.name", "traceId", "nr.entryPoint", "transactionId"}
74+
i_attrs = {attr: value for attr, value in item.intrinsics.items() if attr in i_ct_attrs}
75+
u_attrs = {}
76+
a_attrs = {attr: value for attr, value in item.agent_attributes.items() if attr in entity_relationship_attrs}
77+
self._ct_bytes += objsize.get_deep_size([i_attrs, u_attrs, a_attrs])
5478

5579
# NOTE: dropped can be over-counted as the queue approaches
5680
# capacity while data is still being transmitted.
@@ -59,16 +83,23 @@ def put(self, item):
5983
# being measured.
6084
if len(self._queue) >= self._queue.maxlen:
6185
self._dropped += 1
86+
if self.is_ft(item, entity_relationship_attrs):
87+
self._ft_dropped += 1
6288

89+
# Drop last index that contains the entity relationship attrs present on the span.
6390
self._queue.append(item)
6491
self._notify.notify_all()
6592

6693
def stats(self):
6794
with self._notify:
6895
seen, dropped = self._seen, self._dropped
6996
self._seen, self._dropped = 0, 0
97+
ft_seen, ft_dropped = self._ft_seen, self._ft_dropped
98+
self._ft_seen, self._ft_dropped = 0, 0
99+
_bytes, ft_bytes, ct_bytes = self._bytes, self._ft_bytes, self._ct_bytes
100+
self._bytes, self._ft_bytes, self._ct_bytes = 0, 0, 0
70101

71-
return seen, dropped
102+
return seen, dropped, ft_seen, ft_dropped, _bytes, ft_bytes, ct_bytes
72103

73104
def __bool__(self):
74105
return bool(self._queue)

newrelic/core/application.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1353,6 +1353,7 @@ def harvest(self, shutdown=False, flexible=False):
13531353

13541354
# Send span events
13551355

1356+
print(f"\n\r\n\r\n\r{configuration.span_events.enabled} {configuration.collect_span_events} {configuration.distributed_tracing.enabled} {configuration.infinite_tracing.enabled} \n\r\n\r\n\r")
13561357
if (
13571358
configuration.span_events.enabled
13581359
and configuration.collect_span_events
@@ -1362,11 +1363,18 @@ def harvest(self, shutdown=False, flexible=False):
13621363
span_stream = stats.span_stream
13631364
# Only merge stats as part of default harvest
13641365
if span_stream is not None and not flexible:
1365-
spans_seen, spans_dropped = span_stream.stats()
1366+
print("\n\r\n\r\n\rSending Supportability metrics for inifinte tracing\n\r\n\r\n\r")
1367+
spans_seen, spans_dropped, spans_ft_seen, spans_ft_dropped, _bytes, ft_bytes, ct_bytes = span_stream.stats()
13661368
spans_sent = spans_seen - spans_dropped
1369+
spans_ft_sent = spans_ft_seen - spans_ft_dropped
13671370

13681371
internal_count_metric("Supportability/InfiniteTracing/Span/Seen", spans_seen)
13691372
internal_count_metric("Supportability/InfiniteTracing/Span/Sent", spans_sent)
1373+
internal_count_metric("Supportability/FullTracing/Span/Seen", spans_ft_seen)
1374+
internal_count_metric("Supportability/FullTracing/Span/Sent", spans_ft_sent)
1375+
internal_count_metric("Supportability/InfiniteTracing/Bytes/Seen", _bytes)
1376+
internal_count_metric("Supportability/FullTracing/Bytes/Seen", ft_bytes)
1377+
internal_count_metric("Supportability/CoreTracing/Bytes/Seen", ct_bytes)
13701378
else:
13711379
spans = stats.span_events
13721380
if spans:
@@ -1383,6 +1391,11 @@ def harvest(self, shutdown=False, flexible=False):
13831391
spans_sampled = spans.num_samples
13841392
internal_count_metric("Supportability/SpanEvent/TotalEventsSeen", spans_seen)
13851393
internal_count_metric("Supportability/SpanEvent/TotalEventsSent", spans_sampled)
1394+
internal_count_metric("Supportability/SpanEvent/FullTracing/TotalEventsSeen", spans.ft_seen)
1395+
internal_count_metric("Supportability/SpanEvent/FullTracing/TotalEventsSent", spans.ft_sent)
1396+
internal_count_metric("Supportability/DistributedTracing/Bytes/Seen", spans.bytes)
1397+
internal_count_metric("Supportability/FullTracing/Bytes/Seen", spans.ft_bytes)
1398+
internal_count_metric("Supportability/CoreTracing/Bytes/Seen", spans.ct_bytes)
13861399

13871400
stats.reset_span_events()
13881401

newrelic/core/node_mixin.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,11 @@ def span_event(self, settings, base_attrs=None, parent_guid=None, attr_class=dic
7878
exit_span_attrs_present = set_inprocess_attrs & set_a_attrs
7979
if not exit_span_attrs_present:
8080
return None
81-
return [i_attrs, u_attrs, a_attrs]
81+
82+
set_inprocess_attrs = set(attribute.SPAN_ENTITY_RELATIONSHIP_ATTRIBUTES)
83+
set_a_attrs = set(a_attrs)
84+
exit_span_attrs_present = set_inprocess_attrs & set_a_attrs
85+
return [i_attrs, u_attrs, a_attrs, exit_span_attrs_present]
8286

8387
def span_events(self, settings, base_attrs=None, parent_guid=None, attr_class=dict):
8488
if settings.core_tracing.drop_inprocess_spans:
@@ -170,6 +174,11 @@ def span_event(self, *args, **kwargs):
170174
set_inprocess_attrs = set(attribute.SPAN_ENTITY_RELATIONSHIP_ATTRIBUTES)
171175
set_a_attrs = set(a_attrs)
172176
exit_span_attrs_present = set_inprocess_attrs & set_a_attrs
177+
attrs[3] = exit_span_attrs_present
173178
if not exit_span_attrs_present:
174179
return None
180+
set_inprocess_attrs = set(attribute.SPAN_ENTITY_RELATIONSHIP_ATTRIBUTES)
181+
set_a_attrs = set(a_attrs)
182+
exit_span_attrs_present = set_inprocess_attrs & set_a_attrs
183+
attrs[3] = exit_span_attrs_present
175184
return attrs

newrelic/core/stats_engine.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import zlib
3232
from heapq import heapify, heapreplace
3333

34+
from newrelic.packages import objsize
3435
from newrelic.api.settings import STRIP_EXCEPTION_MESSAGE
3536
from newrelic.api.time_trace import get_linking_metadata
3637
from newrelic.common.encoding_utils import json_encode
@@ -446,13 +447,17 @@ def merge(self, other_data_set, priority=None):
446447
self.num_seen += other_data_set.num_seen - other_data_set.num_samples
447448

448449

449-
class SpanSampledDataSet:
450+
class SpanSampledDataSet(SampledDataSet):
450451
def __init__(self, capacity=100):
451452
self.pq = []
452453
self.heap = False
453454
self.capacity = capacity
454455
self.num_seen = 0
455-
self.ft_num_seen = 0
456+
self.ft_seen = 0
457+
self.ft_sent = 0
458+
self.bytes = 0
459+
self.ft_bytes = 0
460+
self.ct_bytes = 0
456461

457462
if capacity <= 0:
458463

@@ -465,29 +470,46 @@ def add(*args, **kwargs):
465470
def ft_samples(self):
466471
return (x[-1] for x in self.pq if is_ft(x[-1]))
467472

468-
def is_ft(sample):
473+
def is_ft(self, sample):
469474
# It's a FT span if it's an exit or entry span.
470475
return (len(sample) > 3 and sample[3]) or not sample[0].get("parentId")
471476

472477
def add(self, sample, priority=None):
473478
self.num_seen += 1
474-
if is_ft(sample):
475-
self.ft_num_seen += 1
479+
self.bytes += objsize.get_deep_size(sample[:-1])
480+
is_ft = self.is_ft(sample)
481+
entity_relationship_attrs = sample[3] if len(sample) > 3 else {}
482+
if is_ft:
483+
self.ft_seen += 1
484+
# The last index contains the set of entity synthesis attrs in the span.
485+
self.ft_bytes += objsize.get_deep_size([sample[0], sample[1], sample[2]])
486+
487+
i_ct_attrs = {"type", "name", "guid", "parentId", "transaction.name", "traceId", "nr.entryPoint", "transactionId"}
488+
i_attrs = {attr: value for attr, value in sample[0].items() if attr in sample[0]}
489+
u_attrs = {}
490+
a_attrs = {attr: value for attr, value in sample[2].items() if attr in entity_relationship_attrs}
491+
self.ct_bytes += objsize.get_deep_size([i_attrs, u_attrs, a_attrs])
476492

477493
if priority is None:
478494
priority = random.random() # noqa: S311
479495

480-
entry = (priority, self.num_seen, sample)
496+
entry = (priority, self.num_seen, sample[:-1])
481497
if self.num_seen == self.capacity:
482498
self.pq.append(entry)
483499
self.heap = self.heap or heapify(self.pq) or True
500+
if is_ft:
501+
self.ft_sent += 1
484502
elif not self.heap:
485503
self.pq.append(entry)
504+
if is_ft:
505+
self.ft_sent += 1
486506
else:
487507
sampled = self.should_sample(priority)
488508
if not sampled:
489509
return
490510
heapreplace(self.pq, entry)
511+
if is_ft:
512+
self.ft_sent -= 1
491513

492514

493515
class LimitedDataSet(list):
@@ -573,7 +595,7 @@ def __init__(self):
573595
self._error_events = SampledDataSet()
574596
self._custom_events = SampledDataSet()
575597
self._ml_events = SampledDataSet()
576-
self._span_events = SampledDataSet()
598+
self._span_events = SpanSampledDataSet()
577599
self._log_events = SampledDataSet()
578600
self._span_stream = None
579601
self.__sql_stats_table = {}
@@ -1785,9 +1807,9 @@ def reset_ml_events(self):
17851807

17861808
def reset_span_events(self):
17871809
if self.__settings is not None:
1788-
self._span_events = SampledDataSet(self.__settings.event_harvest_config.harvest_limits.span_event_data)
1810+
self._span_events = SpanSampledDataSet(self.__settings.event_harvest_config.harvest_limits.span_event_data)
17891811
else:
1790-
self._span_events = SampledDataSet()
1812+
self._span_events = SpanSampledDataSet()
17911813

17921814
def reset_log_events(self):
17931815
if self.__settings is not None:

newrelic/core/transaction_node.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,8 +621,11 @@ def _add_call_count(source, target):
621621
return intrinsics
622622

623623
def span_protos(self, settings):
624-
for i_attrs, u_attrs, a_attrs in self.span_events(settings, attr_class=SpanProtoAttrs):
625-
yield Span(trace_id=self.trace_id, intrinsics=i_attrs, user_attributes=u_attrs, agent_attributes=a_attrs)
624+
for span in self.span_events(settings, attr_class=SpanProtoAttrs):
625+
if len(span) > 3:
626+
yield Span(trace_id=self.trace_id, intrinsics=span[0], user_attributes=span[1], agent_attributes=span[2]), span[3]
627+
else:
628+
yield Span(trace_id=self.trace_id, intrinsics=span[0], user_attributes=span[1], agent_attributes=span[2])
626629

627630
def span_events(self, settings, attr_class=dict):
628631
base_attrs = attr_class(

newrelic/packages/objsize/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import warnings
66
from typing import Any, Iterable, Iterator, Optional
77

8-
from objsize.traverse import (
8+
from newrelic.packages.objsize.traverse import (
99
FilterFunc,
1010
GetReferentsFunc,
1111
MarkedSet,

0 commit comments

Comments
 (0)