@@ -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.
0 commit comments