Skip to content

Commit 323ee96

Browse files
committed
Add tracking metric, nr.pg & error attrs
1 parent 0f9f8f1 commit 323ee96

File tree

4 files changed

+31
-7
lines changed

4 files changed

+31
-7
lines changed

newrelic/core/attribute.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@
125125
"span.kind",
126126
}
127127

128+
SPAN_ERROR_ATTRIBUTES = {
129+
"error.class",
130+
"error.message",
131+
"error.expected",
132+
}
133+
128134

129135
MAX_NUM_USER_ATTRIBUTES = 128
130136
MAX_ATTRIBUTE_LENGTH = 255

newrelic/core/node_mixin.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,13 @@ def span_event(
8484
ct_exit_spans = {}
8585

8686
partial_granularity_type = settings.distributed_tracing.sampler.partial_granularity.type
87-
exit_span_attrs_present = attribute.SPAN_ENTITY_RELATIONSHIP_ATTRIBUTES & set(a_attrs)
87+
a_attrs_set = set(a_attrs)
88+
exit_span_attrs_present = attribute.SPAN_ENTITY_RELATIONSHIP_ATTRIBUTES & a_attrs_set
89+
exit_span_error_attrs_present = attribute.SPAN_ERROR_ATTRIBUTES & a_attrs_set
90+
# If this is an entry span, add `nr.pg` to indicate transaction is partial
91+
# granularity sampled.
92+
if i_attrs.get("nr.entryPoint"):
93+
a_attrs["nr.pg"] = True
8894
# If this is the entry node or an LLM span always return it.
8995
if i_attrs.get("nr.entryPoint") or i_attrs["name"].startswith("Llm/"):
9096
if partial_granularity_type == "reduced":
@@ -99,7 +105,7 @@ def span_event(
99105
if partial_granularity_type == "reduced":
100106
return [i_attrs, u_attrs, a_attrs]
101107
else:
102-
a_minimized_attrs = attr_class({key: a_attrs[key] for key in exit_span_attrs_present})
108+
a_minimized_attrs = attr_class({key: a_attrs[key] for key in (exit_span_attrs_present | exit_span_error_attrs_present)})
103109
# If we are in essential mode return the span with minimized attributes.
104110
if partial_granularity_type == "essential":
105111
return [i_attrs, {}, a_minimized_attrs]
@@ -117,11 +123,17 @@ def span_event(
117123
a_minimized_attrs["nr.durations"] = self.duration
118124
ct_exit_spans[span_attrs] = [i_attrs, a_minimized_attrs]
119125
return [i_attrs, {}, a_minimized_attrs]
120-
# If this is an exit span we've already seen, add it's guid to the list
126+
# If this is an exit span we've already seen, add the error attributes
127+
# (last occurring error takes precedence), add it's guid to the list
121128
# of ids on the seen span, compute the new duration & start time, and
122129
# return None.
123-
ct_exit_spans[span_attrs][1]["nr.ids"].append(self.guid)
130+
ct_exit_spans[span_attrs][1].update(attr_class({key: a_minimized_attrs[key] for key in a_error_attrs}))
124131
# Max size for `nr.ids` = 1024. Max length = 63 (each span id is 16 bytes + 8 bytes for list type).
132+
if len(ct_exit_spans[span_attrs][1]["nr.ids"]) < 63:
133+
ct_exit_spans[span_attrs][1]["nr.ids"].append(self.guid)
134+
else:
135+
ct_exit_spans["dropped_ids"] += 1
136+
125137
ct_exit_spans[span_attrs][1]["nr.ids"] = ct_exit_spans[span_attrs][1]["nr.ids"][:63]
126138
# Compute the new start and end time for all compressed spans and use
127139
# that to set the duration for all compressed spans.

newrelic/core/stats_engine.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,11 +1196,15 @@ def record_transaction(self, transaction):
11961196
[
11971197
(
11981198
f"Supportability/DistributedTrace/PartialGranularity/{partial_gran_type}/Span/Instrumented",
1199-
{"count": transaction.instrumented},
1199+
{"count": getattr(transaction, "instrumented", 0)},
12001200
),
12011201
(
12021202
f"Supportability/DistributedTrace/PartialGranularity/{partial_gran_type}/Span/Kept",
1203-
{"count": transaction.kept},
1203+
{"count": getattr(transaction, "kept", 0)},
1204+
),
1205+
(
1206+
"Supportability/Python/PartialGranularity/NrIds/Dropped",
1207+
{"count": getattr(transaction, "dropped_ids", 0)},
12041208
),
12051209
]
12061210
)

newrelic/core/transaction_node.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ def span_events(self, settings, attr_class=dict):
634634
("priority", self.priority),
635635
)
636636
)
637-
ct_exit_spans = {"instrumented": 0, "kept": 0}
637+
ct_exit_spans = {"instrumented": 0, "kept": 0, "dropped_ids": 0}
638638
yield from self.root.span_events(
639639
settings,
640640
base_attrs,
@@ -646,6 +646,8 @@ def span_events(self, settings, attr_class=dict):
646646
# If this transaction is partial granularity sampled, record the number of spans
647647
# instrumented and the number of spans kept to monitor cost savings of partial
648648
# granularity tracing.
649+
# Also record the number of span ids dropped (fragmentation) in compact mode.
649650
if self.partial_granularity_sampled:
650651
self.instrumented = ct_exit_spans["instrumented"]
651652
self.kept = ct_exit_spans["kept"]
653+
self.dropped_ids = ct_exit_spans["dropped_ids"]

0 commit comments

Comments
 (0)