Skip to content

feat(celery): Support span streaming#6074

Draft
sentrivana wants to merge 13 commits intomasterfrom
ivana/migrate-celery-to-span-first
Draft

feat(celery): Support span streaming#6074
sentrivana wants to merge 13 commits intomasterfrom
ivana/migrate-celery-to-span-first

Conversation

@sentrivana
Copy link
Copy Markdown
Contributor

@sentrivana sentrivana commented Apr 14, 2026

Description

Support streaming mode in the Celery integration.

This is the first integration that contains explicit guards against creating certain spans as segments, mirroring how start_span works currently -- it won't create a span if there's no transaction. In Celery, there were multiple spots that, if we just replaced all legacy start_spans with the new traces.start_span, would've created new segment spans, leading to a change in behavior.

  • replace APIs
  • map data to attributes from conventions
  • run tests in streaming mode

Best viewed with Hide whitespace 😎

Issues

@linear-code
Copy link
Copy Markdown

linear-code bot commented Apr 14, 2026

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 14, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


This PR will not appear in the changelog.


🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 14, 2026

Codecov Results 📊

12 passed | Total: 12 | Pass Rate: 100% | Execution Time: 1.52s

All tests are passing successfully.

❌ Patch coverage is 1.41%. Project has 14901 uncovered lines.

Files with missing lines (4)
File Patch % Lines
scope.py 68.58% ⚠️ 274 Missing and 68 partials
__init__.py 3.27% ⚠️ 266 Missing
traces.py 35.71% ⚠️ 198 Missing
_span_batcher.py 26.51% ⚠️ 61 Missing

Generated by Codecov Action

kwargs_headers = {}

task_name = kwargs_headers.get("task")
task_name = kwargs_headers.get("task") or "<unknown Celery task>"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is used for naming the span and spans v2 must always have a name, name=None is not supported.

"trace_id": item.trace_id,
"span_id": item.span_id,
"name": item._name,
"name": item._name if item._name is not None else "<unknown>",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Guarding against sending null span names also here, directly in the batcher, since it'd be a protocol violation

With the fix for task_name above, there are no known cases where this would happen, but better to be safe

self._active: bool = active
self._attributes: "Attributes" = {}
self._attributes: "Attributes" = {
"sentry.origin": "manual",
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This was an oversight in the core logic -- we were never setting sentry.origin for custom instrumentation

Comment on lines +905 to +906
self._transaction_info["source"] = str(
span._attributes["sentry.span.source"]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

If you're wondering what the str() is doing here, the answer is mypy 😎 😭

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 celery to span first

1 participant