Skip to content

Comments

feat(core): Add captureSpan pipeline and helpers#19197

Merged
Lms24 merged 9 commits intolms/feat-span-firstfrom
lms/feat-core-captureSpan
Feb 6, 2026
Merged

feat(core): Add captureSpan pipeline and helpers#19197
Lms24 merged 9 commits intolms/feat-span-firstfrom
lms/feat-core-captureSpan

Conversation

@Lms24
Copy link
Member

@Lms24 Lms24 commented Feb 5, 2026

This PR adds the captureSpan pipeline, which takes a Span instance, processes it and ultimately returns a SerializedStreamedSpan which can then be enqueued into the span buffer.

ref #17836

@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

Codecov Results 📊


Generated by Codecov Action

@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

Codecov Results 📊

25 passed | ⏭️ 5 skipped | Total: 30 | Pass Rate: 83.33% | Execution Time: 13.33s

All tests are passing successfully.


Generated by Codecov Action

@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

size-limit report 📦

Path Size % Change Change
@sentry/browser 25.44 kB added added
@sentry/browser - with treeshaking flags 23.91 kB added added
@sentry/browser (incl. Tracing) 42.39 kB added added
@sentry/browser (incl. Tracing, Profiling) 47.04 kB added added
@sentry/browser (incl. Tracing, Replay) 81.07 kB added added
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 70.64 kB added added
@sentry/browser (incl. Tracing, Replay with Canvas) 85.77 kB added added
@sentry/browser (incl. Tracing, Replay, Feedback) 97.94 kB added added
@sentry/browser (incl. Feedback) 42.16 kB added added
@sentry/browser (incl. sendFeedback) 30.12 kB added added
@sentry/browser (incl. FeedbackAsync) 35.13 kB added added
@sentry/browser (incl. Metrics) 26.55 kB added added
@sentry/browser (incl. Logs) 26.7 kB added added
@sentry/browser (incl. Metrics & Logs) 27.36 kB added added
@sentry/react 27.17 kB added added
@sentry/react (incl. Tracing) 44.64 kB added added
@sentry/vue 30.03 kB added added
@sentry/vue (incl. Tracing) 44.2 kB added added
@sentry/svelte 25.45 kB added added
CDN Bundle 27.97 kB added added
CDN Bundle (incl. Tracing) 43.16 kB added added
CDN Bundle (incl. Logs, Metrics) 28.81 kB added added
CDN Bundle (incl. Tracing, Logs, Metrics) 44.02 kB added added
CDN Bundle (incl. Replay, Logs, Metrics) 67.76 kB added added
CDN Bundle (incl. Tracing, Replay) 79.91 kB added added
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 80.8 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback) 85.38 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 86.27 kB added added
CDN Bundle - uncompressed 81.81 kB added added
CDN Bundle (incl. Tracing) - uncompressed 127.81 kB added added
CDN Bundle (incl. Logs, Metrics) - uncompressed 84.65 kB added added
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 130.65 kB added added
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 208.03 kB added added
CDN Bundle (incl. Tracing, Replay) - uncompressed 244.42 kB added added
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 247.24 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 257.22 kB added added
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 260.03 kB added added
@sentry/nextjs (client) 46.98 kB added added
@sentry/sveltekit (client) 42.77 kB added added
@sentry/node-core 52.18 kB added added
@sentry/node 166.36 kB added added
@sentry/node - without tracing 93.96 kB added added
@sentry/aws-serverless 109.48 kB added added

@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

Scenario Requests/s % of Baseline Prev. Requests/s Change %
GET Baseline 8,976 - - added
GET With Sentry 1,660 18% - added
GET With Sentry (error only) 6,024 67% - added
POST Baseline 1,187 - - added
POST With Sentry 577 49% - added
POST With Sentry (error only) 1,043 88% - added
MYSQL Baseline 3,218 - - added
MYSQL With Sentry 409 13% - added
MYSQL With Sentry (error only) 2,625 82% - added

@Lms24 Lms24 mentioned this pull request Feb 5, 2026
22 tasks
@Lms24 Lms24 marked this pull request as ready for review February 6, 2026 08:12
@Lms24 Lms24 self-assigned this Feb 6, 2026
Copy link

@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.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

Copy link
Member

@s1gr1d s1gr1d left a comment

Choose a reason for hiding this comment

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

Nice!

export { logSpanEnd, logSpanStart } from './logSpans';

// Span Streaming
export { captureSpan } from './spans/captureSpan';
Copy link
Member

Choose a reason for hiding this comment

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

Q: Would it make sense to call this captureStreamingSpan?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yup we can do that. No strong feelings tbh since users shouldn't interact with this at all.

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, if you don't mind, I want to keep this in line with logs and metrics as much as possible. Given we don't use this outside of span first I think it's fine to leave it at "captureSpan"

/**
* Register a callback for when a span JSON is processed, to add some data to the span JSON.
*/
public on(hook: 'processSpan', callback: (streamedSpanJSON: StreamedSpanJSON) => void): () => void;
Copy link
Member

Choose a reason for hiding this comment

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

Q: Also here - would it make sense to call this processStreamingSpan?

Copy link
Member Author

Choose a reason for hiding this comment

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

Given that client hooks are not really deemed for public use and processStreamingSpan is slightly more bundle size (the hook names can't be minified), I'd tend towards keeping it short. There's also processLog and processMetric so we have a consistent pattern for the "new" telemetry items.

@Lms24
Copy link
Member Author

Lms24 commented Feb 6, 2026

hmm I'm starting to wonder if the "StreamedSpan" naming pattern is a mistake to be honest. Prefixing every new API with "streamed" not only makes the names longer and increases bundle size more, but also means it's more annoying to migrate back to "Span" when we completely remove transactions.

status: getSimpleStatusMessage(this._status),
attributes: this._attributes,
// spread to avoid mutating the original object when later processing the span
attributes: { ...this._attributes },
Copy link
Member

Choose a reason for hiding this comment

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

I'm wondering if this comes with big performance impacts. What cases are we protecting against?

Copy link
Member Author

@Lms24 Lms24 Feb 6, 2026

Choose a reason for hiding this comment

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

Basically this case:

const attributes = {'sentry.source': 'route'};

startSpan({name: 'span1', attributes}, () => {});
startSpan({name: 'span2', attributes}, () => {});

If we don't clone the attributes, the second span would be started with all the mutations we applied to the attributes object of the first span during captureSpan. I agree there's for sure a perf impact but I don't see an alternative. Unless Object.keys or similar low level ops are more performant 🤔 (though these come with a bundle size tradeoff).

Copy link
Member

Choose a reason for hiding this comment

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

Right, I wonder if people share attributes like that. Is that not an issue already today?

If it's already like this and we haven't gotten complaints, maybe we can just not clone and do it once someone complains? 😅

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd say it definitely is an issue today for regular spans, but us actively deleting sentry.source makes it a bit worse for span streaming. Actually, let's kill two birds with one stone here and:

  1. remove the deletion. We can just send both, sentry.source and sentry.span.source attributes, I don't care 😅
  2. remove the spread and wait for the complaints

Copy link
Member

Choose a reason for hiding this comment

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

Yea, I like that.

Copy link
Member

@andreiborza andreiborza left a comment

Choose a reason for hiding this comment

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

Nice!

@Lms24 Lms24 merged commit 8bb3b7b into lms/feat-span-first Feb 6, 2026
214 checks passed
@Lms24 Lms24 deleted the lms/feat-core-captureSpan branch February 6, 2026 14:08
Lms24 added a commit that referenced this pull request Feb 13, 2026
This PR adds the `captureSpan` pipeline, which takes a `Span` instance,
processes it and ultimately returns a `SerializedStreamedSpan` which can
then be enqueued into the span buffer.

ref #17836
Lms24 added a commit that referenced this pull request Feb 16, 2026
This PR adds the `captureSpan` pipeline, which takes a `Span` instance,
processes it and ultimately returns a `SerializedStreamedSpan` which can
then be enqueued into the span buffer.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants