Skip to content

Commit fb9bfdc

Browse files
committed
fix(traces): walk every hook attribute again, and record the new callback alias
Skipping values the hook left as the same object let a container grown in place ship past max_attribute_value_length. The public API snapshot gains BeforeSpanSendCallback.
1 parent 8132e1c commit fb9bfdc

4 files changed

Lines changed: 11 additions & 21 deletions

File tree

‎posthog/test/tracing/test_limits.py‎

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -186,20 +186,12 @@ def test_stops_walking_a_mapping_at_the_encoders_item_cap(self):
186186

187187

188188
class TestApplySpanLimits:
189-
def test_walks_only_values_the_hook_changed(self):
190-
untouched = ["already", "bounded"]
191-
record = SpanRecord(
192-
"t", "s", "n", 1, 2, attributes={"same": untouched, "new": "x" * 9}
193-
)
194-
with mock.patch.object(
195-
limits_module, "truncate_attribute_value", wraps=truncate_attribute_value
196-
) as walk:
197-
apply_span_limits(
198-
record, frozenset(), 128, 128, 128, 8, (), {"same": untouched}
199-
)
200-
assert walk.call_args_list == [mock.call("x" * 9, 8)]
201-
assert record.attributes["same"] is untouched
202-
assert record.attributes["new"] == "x" * 8
189+
def test_rebounds_a_container_the_hook_grew_in_place(self):
190+
grown = ["x" * 3]
191+
record = SpanRecord("t", "s", "n", 1, 2, attributes={"k": grown})
192+
grown.append("y" * 20)
193+
apply_span_limits(record, frozenset(), 128, 128, 128, 8)
194+
assert record.attributes["k"] == ["xxx", "y" * 8]
203195

204196
def test_an_empty_key_spends_no_slot(self):
205197
record = SpanRecord("t", "s", "n", 1, 2, attributes={"": 1, "a": 2, "b": 3})

‎posthog/tracing/_before_span_send.py‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ def run_before_span_send(
7474
MAX_ATTRIBUTES_PER_EVENT,
7575
config.max_attribute_value_length,
7676
keys_before_hook,
77-
record.attributes,
7877
)
7978
return rebuilt
8079
except Exception:

‎posthog/tracing/_limits.py‎

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,12 @@ def apply_span_limits(
163163
max_attributes_per_event: int,
164164
max_length: int,
165165
keys_before_hook: Sequence[str] = (),
166-
bounded_before_hook: Mapping[str, Any] = {},
167166
) -> None:
168167
"""Re-apply the per-span caps after a ``before_span_send`` hook, which
169168
bypasses the span's own writer. Counts add to what the span already dropped.
170-
A value still the object the span bounded at write time is not walked again."""
169+
170+
Every container is walked again: the hook holds the same nested objects
171+
the span stored, so one it grew in place has the same identity."""
171172
attributes: Dict[str, Any] = {}
172173
kept = 0
173174
dropped_attributes = 0
@@ -180,10 +181,7 @@ def apply_span_limits(
180181
dropped_attributes += 1
181182
continue
182183
kept += 1
183-
if bounded_before_hook.get(key) is value:
184-
attributes[key] = value
185-
else:
186-
attributes[key] = truncate_attribute_value(value, max_length)
184+
attributes[key] = truncate_attribute_value(value, max_length)
187185
record.attributes = attributes
188186
if dropped_attributes:
189187
record.dropped_attributes_count = (

‎references/public_api_snapshot.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -888,6 +888,7 @@ attribute posthog.send = True
888888
attribute posthog.super_properties = None
889889
attribute posthog.sync_mode = False
890890
attribute posthog.types.BeforeSendCallback = Callable[[dict[str, Any]], Optional[dict[str, Any]]]
891+
attribute posthog.types.BeforeSpanSendCallback = Callable[[dict[str, Any]], Optional[dict[str, Any]]]
891892
attribute posthog.types.FeatureFlag.enabled: bool
892893
attribute posthog.types.FeatureFlag.key: str
893894
attribute posthog.types.FeatureFlag.metadata: Union[FlagMetadata, LegacyFlagMetadata]

0 commit comments

Comments
 (0)