[experiment] ref!: Remove transactions and the static trace lifecycle - #23240
[experiment] ref!: Remove transactions and the static trace lifecycle#23240Lms24 wants to merge 2 commits into
Conversation
Span streaming is now the only trace lifecycle. The SDK no longer sends transaction events, so every code path that only existed to build, scrub, filter or ship them is gone. Removed from core: the `traceLifecycle` option, `_convertSpanToTransaction`, the segment-span capture strategy and its deferred-capture queue, standalone spans, `beforeSendTransaction`, `ignoreTransactions`, `withStaticSpan` / `withStreamedSpan`, gen_ai span extraction, the v1<->v2 span converters, `hasSpanStreamingEnabled`, the `TransactionEvent` type and the `spans`, `measurements` and `transaction_info` fields on `Event`. Also removed the downstream hooks that no longer see any traffic: the transaction branches of `eventFilters`, `prepareEvent` span normalization, `scopeData` transaction naming, the vercel-ai transaction processor and its token-accumulation utils, and the legacy `preprocessEvent` paths in Next.js and SvelteKit (both already had `processSpan` counterparts). Legacy browser profiling goes too: it attached profiles to transaction envelope items and was therefore unreachable. UI Profiling (v2) is untouched. Web vitals simplify as well, since CLS/LCP/INP now always stream as their own spans. Three options had no streaming equivalent and are dropped rather than reimplemented, because `processSpan`/`processSegmentSpan` cannot drop a span: `httpIntegration`'s `dropSpansForIncomingRequestStatusCodes`, and the low-quality-transaction filters in Nuxt and SolidStart. Shipping this needs either a droppable streaming hook or `ignoreSpans`-based replacements. Tests are intentionally not updated; this branch measures bundle size impact. BREAKING CHANGE: The SDK no longer sends transaction events. `traceLifecycle`, `beforeSendTransaction`, `ignoreTransactions`, `withStaticSpan`, `withStreamedSpan`, `dropSpansForIncomingRequestStatusCodes` and legacy browser profiling (`profilesSampleRate`) are removed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit cf88354. Configure here.
|
|
||
| const traceData = event.contexts.trace.data; | ||
|
|
||
| // Get the route from trace data |
There was a problem hiding this comment.
Next.js URL backfill never runs
High Severity
setUrlProcessingMetadata now runs on afterSegmentSpanEnd against the live span, but http.server and many route attributes are only applied later in processSegmentSpan on the streamed span JSON. On the Node server path the live span never gets sentry.op, so the op !== 'http.server' guard always returns early and request URL backfill never happens. Route values only set during enhancement, such as from sentry.route_backfill, are also invisible here.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit cf88354. Configure here.
size-limit report 📦
|
|
well ... this is less than expected |
Second sweep over what the transaction removal left behind. All of this was reachable-but-dead: written by the SDK and read by nothing. `setMeasurement()` was the biggest find. It stores timed events on the root span, but the only reader was `timedEventsToMeasurements`, which fed the transaction event's `measurements` field. Under span streaming `getStreamedSpanJSON()` never looks at `_events`, so every call was a silent no-op that only accumulated memory. Removed the function, the conversion helper, `SentrySpan._events` and the `TimedEvent` type; `addEvent()` stays as a no-op because the OpenTelemetry Span interface requires the method. `@sentry/bundler-plugins` was the only internal caller and now sets plain span attributes instead. Also removed: `profile_id`, `exclusive_time`, `measurements` and `segment_id` from `SpanJSON` (all write-only — nothing reads them off a `spanToJSON()` result), the `transaction`/`transactions` fields on the v1 `Profile` type, `capturedSpanScope` / `capturedSpanIsolationScope` / `spanCountBeforeProcessing` from `SdkProcessingMetadata` plus the scope re-routing they drove in `captureEvent`, the orphaned `SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_*` and `SEMANTIC_ATTRIBUTE_PROFILE_ID` constants, the browser-only `profilesSampleRate` option left over from legacy profiling, and the `sentry.transaction` breadcrumb category (nothing emits it anymore). `spanToJSON`, `SpanJSON`, `getSpanDescendants` and `forceTransaction` are deliberately kept: they are read APIs used across 15 packages, back idle spans, and still mean "make this span a segment" respectively. BREAKING CHANGE: `setMeasurement()` is removed; use span attributes instead. `Span.addEvent()` no longer records anything. `profilesSampleRate` is removed from the browser SDK options. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>


Experiment — not for merge. Opened to get size-limit numbers for removing transactions in v12.
Span streaming becomes the only trace lifecycle: no transaction events, no
staticlifecycle, no standalone spans. Every code path that only existed to build, filter or ship transactions is deleted, including legacy browser profiling (it attached profiles to transaction envelope items) and the transaction branches of event processors in core, vercel-ai, Next.js and SvelteKit.A second commit removes what that left behind — code that was reachable but dead. The notable one:
setMeasurement()was a silent no-op, since the only reader of its timed events was the transactionmeasurementsfield. That's gone along withTimedEvent, the write-onlyprofile_id/exclusive_time/measurements/segment_idfields onSpanJSON, and thecapturedSpanScopescope-rerouting incaptureEvent.Three options had no streaming equivalent and are dropped rather than reimplemented, since
processSpan/processSegmentSpancannot drop a span:httpIntegration'sdropSpansForIncomingRequestStatusCodes, and the low-quality-transaction filters in Nuxt and SolidStart. Tests are intentionally not updated.