Skip to content

feat(sanic): Support span streaming#6319

Open
sl0thentr0py wants to merge 1 commit into
masterfrom
neel/span-first/sanic
Open

feat(sanic): Support span streaming#6319
sl0thentr0py wants to merge 1 commit into
masterfrom
neel/span-first/sanic

Conversation

@sl0thentr0py
Copy link
Copy Markdown
Member

@sl0thentr0py sl0thentr0py commented May 21, 2026

The _unsampled_statuses option is not respected for span streaming since we currently don't allow tail-based sampling in the new system.

Issues

@sl0thentr0py sl0thentr0py requested a review from a team as a code owner May 21, 2026 12:56
@linear-code
Copy link
Copy Markdown

linear-code Bot commented May 21, 2026

PY-2357

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

Codecov Results 📊

282 passed | Total: 282 | Pass Rate: 100% | Execution Time: 40.11s

All tests are passing successfully.

❌ Patch coverage is 9.52%. Project has 15310 uncovered lines.

Files with missing lines (1)
File Patch % Lines
sanic.py 9.35% ⚠️ 194 Missing

Generated by Codecov Action

@sl0thentr0py sl0thentr0py force-pushed the neel/span-first/sanic branch from d266281 to 950a311 Compare May 21, 2026 13:00
Comment thread tests/integrations/sanic/test_sanic.py
Comment thread sentry_sdk/integrations/sanic.py Outdated
@sl0thentr0py sl0thentr0py force-pushed the neel/span-first/sanic branch 2 times, most recently from ca346f8 to d10461b Compare May 21, 2026 13:27
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d10461b. Configure here.

Comment thread sentry_sdk/integrations/sanic.py Outdated
@sl0thentr0py sl0thentr0py force-pushed the neel/span-first/sanic branch from d10461b to 9e8d40b Compare May 21, 2026 13:48
Comment thread sentry_sdk/traces.py Outdated
@sl0thentr0py sl0thentr0py force-pushed the neel/span-first/sanic branch from 9e8d40b to e9d3bf6 Compare May 21, 2026 14:14
The `_unsampled_statuses` option is not respected for span streaming
since we currently don't allow tail-based sampling in the new system.
@sl0thentr0py sl0thentr0py force-pushed the neel/span-first/sanic branch from e9d3bf6 to 0f32453 Compare May 21, 2026 14:16
Copy link
Copy Markdown
Member

@ericapisani ericapisani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some small things but otherwise LGTM. Approving so as not to block it from merging

span.set_attribute(SPANDATA.HTTP_STATUS_CODE, response_status)
span.status = "error" if response_status >= 400 else "ok"

span._end()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a public end method that we can use here instead of the private _end (and the public method calls _end under the hood giving us the same outcome)

if urlparts.query:
attributes[SPANDATA.HTTP_QUERY] = urlparts.query

attributes[SPANDATA.URL_FULL] = request.url
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to now be treated as PII, so would need to also be gated behind should_send_default_pii()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the PII designation in conventions is enforced in Relay and not the SDK

i.payload
for i in items
if i.type == "span"
and i.payload["attributes"].get("sentry.origin") == "auto.http.sanic"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because this is specifically looking for segments, this filter may be too broad since any child span originating from the integration would be returned. To be safe, it might be worth adding a check on the _is_segment property and confirming that it's True

span.set_attribute(SPANDATA.HTTP_STATUS_CODE, response_status)
span.status = "error" if response_status >= 400 else "ok"

span._end()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
span._end()
span.end()

Copy link
Copy Markdown
Contributor

@sentrivana sentrivana left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, couple small things _end -> end and TransactionSource -> SegmentSource

with capture_internal_exceptions():
scope = sentry_sdk.get_current_scope()
route_name = route.name.replace(request.app.name, "").strip(".")
scope.set_transaction_name(route_name, source=TransactionSource.COMPONENT)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a SegmentSource too for the streaming path. Would be good to use that if span streaming is enabled

sanic_route = sanic_route[len(sanic_app_name) + 1 :]

scope.set_transaction_name(
sanic_route, source=TransactionSource.COMPONENT
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here too we should do SegmentSource if streaming

)
else:
scope.set_transaction_name(
rv[0].__name__, source=TransactionSource.COMPONENT
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here

Comment on lines +454 to +455
if i.type == "span"
and i.payload["attributes"].get("sentry.origin") == "auto.http.sanic"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you do capture_items("span"), there won't be anything but spans in the list, so no need to check explicitly

Suggested change
if i.type == "span"
and i.payload["attributes"].get("sentry.origin") == "auto.http.sanic"
if i.payload["attributes"].get("sentry.origin") == "auto.http.sanic"

Comment on lines +538 to +539
if i.type == "span"
and i.payload["attributes"].get("sentry.origin") == "auto.http.sanic"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if i.type == "span"
and i.payload["attributes"].get("sentry.origin") == "auto.http.sanic"
if i.payload["attributes"].get("sentry.origin") == "auto.http.sanic"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Migrate sanic to span first

4 participants