Repository navigation
Migrate all integrations to span first #5386
Description
As long as an integration interacts with tracing in some way (either creates spans on its own, or enriches existing spans with data), it needs to be migrated.
If an integration doesn't do anything tracing-related, e.g. because it's errors-only, feel free to just close the related issue.
Goal
- The integration sends transactions without breaking anything in non-streaming (legacy) mode
- In streaming mode, the integration uses the new v2 format and streams spans
- The data on the spans is comparable in both modes
- Any span attributes set by the integration follow our semantic conventions
- Tests test the integration in both legacy and streaming mode and pass in both modes
How to migrate
- As the core logic is now merged, open a feature branch against
master. - You can check whether you're currently in legacy or streaming mode via
has_span_streaming_enabledfromtracing_utils. - All
start_spancalls have to be duplicated. In legacy mode, preserve old functionality. In streaming mode, usesentry_sdk.traces.start_spanwith the new signature. Make sure to migrate starting data likeop,originto starting attributes (sentry.op).start_transactioncalls need to migrated in a similar fashion. When migratingstart_transactioncalls, usesentry_sdk.traces.start_spanwithparent_span=Noneto explicitly force a segment.
- Keep existing
continue_traceusage for legacy mode. In streaming mode, use the newsentry_sdk.traces.continue_tracethat's not a context manager. - Migrate
custom_sampling_context. It should useScope.set_custom_sampling_contextin streaming mode.- Make sure it's set before the span is created as that's when it'll be sampled (and when custom sampling context needs to be available in the traces sampler).
- Make sure it's set after
continue_trace, as that wipes the propagation context that we use to store the custom sampling context.
- Keep any event processors as they are, as they're still needed for event-based telemetry like errors. In streaming mode, make sure equivalent data is set on the span directly.
- Avoid setting integration-level attributes on the scope via
scope.set_attribute, as it'd then also be applied to metrics and logs as well as any children of the current span. See https://develop.sentry.dev/sdk/telemetry/spans/span-protocol/#common-attribute-keys for what attributes should be set on all spans. Other attributes should NOT be set on all spans. For instance, request related attributes should only be set on the segment span.
- Avoid setting integration-level attributes on the scope via
- When translating old contexts, data, tags etc. to span attributes, follow Sentry conventions. If anything is unclear or there's an attribute missing, raise on Slack in
#proj-span-first-sentryas product folks also need to be aligned on attribute changes.- Keep track of removed data/tags to call out later in the changelog.
- Parametrize all tests that deal with tracing to execute both in legacy and in span streaming mode. Add equivalent assertions in streaming mode. You can use the
capture_itemsfixture for unwrapping envelope item items automatically. - Some integrations (HTTP clients and DB) attach source information and they do it after a span has finished. In streaming mode, we can't set anything on a span after it's finished since it'll already be queued up for sending. So in that case, we need to do any sort of time measurements (to see if the span meets the length threshold to attach source data) as well as data attaching while the span is still alive.
There is also a comprehensive migration guide: https://sentry-docs-git-ivana-span-first-migration-guide.sentry.dev/platforms/python/migration/span-first/
Prototypes
- Look at ASGI, WSGI, or Celery
- The original span first branch (unused now) has a few quick ports that are probably not 100% there but can be used as a reference: https://github.com/getsentry/sentry-python/pull/5551/changes
List of integrations
Prioritize
These appear to be used in Seer. Let's start with them to be able to dogfood Seer again soon.
- Migrate argv to span first #5998
- Migrate asgi to span first #6001
- Migrate atexit to span first #6004
- Migrate celery to span first #6009
- Migrate dedupe to span first #6014
- Migrate excepthook to span first #6017
- Migrate fastapi to span first #6020
- Migrate httpx to span first #6028
- Migrate huggingface_hub to span first #6030
- Migrate logging to span first #6036
- Migrate mcp to span first #6038
- Migrate modules to span first #6039
- Migrate redis to span first #6052
- Migrate sqlalchemy to span first #6059
- Migrate starlette to span first #6060
- Migrate stdlib to span first #6066
- Migrate threading to span first #6065
The rest
- Migrate aiohttp to span first #5996
- Migrate anthropic to span first #5997
- Migrate ariadne to span first #5999
- Migrate arq to span first #6000
- Migrate asyncio to span first #6002
- Migrate asyncpg to span first #6003
- Migrate aws_lambda to span first #6005
- Migrate beam to span first #6006
- Migrate boto3 to span first #6007
- Migrate bottle to span first #6008
- Migrate chalice to span first #6010
- Migrate clickhouse_driver to span first #6011
- Migrate cloud_resource_context to span first #6012
- Migrate cohere to span first #6013
- Migrate django to span first #6015
- Migrate dramatiq to span first #6016
- Migrate excepthook to span first #6017
- Migrate executing to span first #6018
- Migrate falcon to span first #6019
- Migrate flask to span first #6021
- Migrate gcp to span first #6022
- Migrate gnu_backtrace to span first #6023
- Migrate google_genai to span first #6024
- Migrate gql to span first #6025
- Migrate graphene to span first #6026
- Migrate grpc to span first #6027
- Migrate huey to span first #6029
- Migrate langchain to span first #6031
- Migrate langgraph to span first #6032
- Migrate launchdarkly to span first #6033
- Migrate litellm to span first #6034
- Migrate litestar to span first #6035
- Migrate loguru to span first #6037
- Migrate openai to span first #6040
- Migrate openai_agents to span first #6041
- Migrate openfeature to span first #6042
- Migrate opentelemetry to span first #6043
- Migrate otlp to span first #6044
- Migrate pure_eval to span first #6045
- Migrate pydantic_ai to span first #6046
- Migrate pymongo to span first #6047
- Migrate pyramid to span first #6048
- Migrate pyreqwest to span first #6049
- Migrate quart to span first #6050
- Migrate ray to span first #6051
- Migrate rq to span first #6053
- Migrate rust_tracing to span first #6054
- Migrate sanic to span first #6055
- Migrate serverless to span first #6056
- Migrate socket to span first #6057
- Migrate spark to span first #6058
- Migrate starlite to span first #6061
- Migrate statsig to span first #6062
- Migrate strawberry to span first #6063
- Migrate sys_exit to span first #6064
- Migrate tornado to span first #6067
- Migrate trytond to span first #6068
- Migrate typer to span first #6069
- Migrate unleash to span first #6070
- Migrate unraisablehook to span first #6071
- Migrate wsgi to span first #6072
Activity
linear commentedon Jan 29, 2026
PY-2055
60 remaining items
alexander-alderman-webb commentedon May 4, 2026
Would be great to wait on AI integrations until we have more clarity on what happens with sending
gen_ai.*spans as V2 envelope items in #6079. Otherwise there will be a lot of conflicts in the test files.And for now there's enough other integrations to port 😄.
Let me know if we need to prioritize porting AI integrations though.
cc @sentrivana @ericapisani
sentrivana commentedon May 4, 2026
Makes sense to me. I'll adjust the prio of the individual issues.
feat(dramatiq): Support span streaming
feat(dramatiq): Support span streaming
feat(dramatiq): Support span streaming