feat(span-first): Support before_send_span#6239
Conversation
before_send_span
Codecov Results 📊✅ 13 passed | Total: 13 | Pass Rate: 100% | Execution Time: 3.95s All tests are passing successfully. ❌ Patch coverage is 15.22%. Project has 16331 uncovered lines. Files with missing lines (6)
Generated by Codecov Action |
Codecov Results 📊✅ 44 passed | ❌ 13 failed | Total: 57 | Pass Rate: 77.19% | Execution Time: 9.62s ❌ Failed Tests
|
| File | Patch % | Lines |
|---|---|---|
utils.py |
54.32% | |
client.py |
61.82% | |
consts.py |
99.22% |
Generated by Codecov Action
| if serialized is None: | ||
| return | ||
|
|
||
| elif ty == "span" and isinstance(telemetry, StreamedSpan): |
There was a problem hiding this comment.
The isinstance(telemetry, StreamedSpan) part of the condition is only there because mypy was complaining :( It can't deal with dispatchers/generics very well in general.
| class fake_record_sql_queries: # noqa: N801 | ||
| def __init__(self, *args, **kwargs): | ||
| with record_sql_queries_supporting_streaming( | ||
| self._ctx_mgr = record_sql_queries_supporting_streaming( |
There was a problem hiding this comment.
Had to change this test because it was failing -- it was closing the span too early.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit e65b1c2. Configure here.
alexander-alderman-webb
left a comment
There was a problem hiding this comment.
Looks good!
ericapisani
left a comment
There was a problem hiding this comment.
LGTM to me overall, just saw a few polishing opportunities. Approving so as not to block ![]()
| # estimate the attributes separately. | ||
| estimate = 210 | ||
| for value in item._attributes.values(): | ||
| for value in (item.get("attributes") or {}).values(): |
There was a problem hiding this comment.
This can be made slightly more concise by doing the following:
| for value in (item.get("attributes") or {}).values(): | |
| for value in (item.get("attributes", {})).values(): |
| # Spans can't be dropped in before_send_span by design. They can | ||
| # be altered though (e.g. to sanitize). Only allow changes to | ||
| # name and attributes. | ||
| if isinstance(serialized, dict) and serialized and "name" in serialized: |
There was a problem hiding this comment.
The and serialized part is unnecessary because if the isinstance(serialized, dict) is truthy, then you can perform the "name" in serialized check without worrying about an exception being raised.
| if isinstance(serialized, dict) and serialized and "name" in serialized: | |
| if isinstance(serialized, dict) and "name" in serialized: |
| if isinstance(serialized, dict) and serialized and "name" in serialized: | ||
| telemetry.name = serialized["name"] # type: ignore[typeddict-item] | ||
| telemetry._attributes = {} | ||
| for k, v in (serialized.get("attributes") or {}).items(): |
There was a problem hiding this comment.
Similar to my comment above, you can remove the or by adding the {} as the fallback on the get:
| for k, v in (serialized.get("attributes") or {}).items(): | |
| for k, v in (serialized.get("attributes", {})).items(): |
|
|
||
| elif ty == "span": | ||
| # We need a reference to the segment span in the batcher to populate | ||
| # the DSC |
There was a problem hiding this comment.
I'd avoid using acronyms for comments that are explaining behaviour or are intended to provide context - it makes it difficult for those not familiar with Sentry's features/terminology to follow along
| # the DSC | |
| # the dynamic sampling context |

Description
Add support for
before_send_spanin span streaming mode.before_send_spanis different frombefore_send_metricandbefore_send_login that:None)To that end, we're now serializing the span earlier, and exposing the serialized dictionary in the
before_sendcallback. This is consistent with metrics and logs. It also means we're now queuing dictionaries instead ofStreamedSpaninstances in the span batcher, which should also decrease our memory footprint.This aligns our implementation with JS.
See https://develop.sentry.dev/sdk/telemetry/spans/scrubbing-data/ for spec.
Issues
before_send_span#5388