Skip to content

feat(core): Add afterEnvelope and flushTraceSpans client hooks - #23136

Open
JPeer264 wants to merge 1 commit into
developfrom
jp/cacheclient-add-hooks
Open

feat(core): Add afterEnvelope and flushTraceSpans client hooks#23136
JPeer264 wants to merge 1 commit into
developfrom
jp/cacheclient-add-hooks

Conversation

@JPeer264

@JPeer264 JPeer264 commented Aug 7, 2026

Copy link
Copy Markdown
Member

This adds hooks that are required for #23083. We need a way to listen to specific events that are happening after responses. The afterEnvelope, gives us the missing hook for envelopes and flushTraceSpans adds the functionality to flush a trace on demand. These hooks are only required for Cloudfare. I tried to make its own spanStreamingIntegration only for the Cloudflare SDK, but it wouldn't have worked without duplicating the entire code, because flushTraceSpans needs access to buffer directly.


Clanker desc:

afterEnvelope fires after the transport has accepted an envelope. Runtimes that flush eagerly (e.g. the Cloudflare SDK's cached client) use it to drain the transport buffer at capture time instead of waiting for an invocation boundary.

flushTraceSpans lets a runtime flush a single trace's span bucket from the span streaming buffer ahead of the regular flush points, without draining the whole buffer mid-invocation and fragmenting concurrent traces.

@JPeer264
JPeer264 requested review from Lms24 and chargome August 7, 2026 08:54
@JPeer264 JPeer264 self-assigned this Aug 7, 2026

@Lms24 Lms24 left a comment

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.

I briefly asked myself, instead of only flushing the span buffer, should we simply call Sentry.flush? Does anything speak against flushing everything in the queue at this point? Just a question. "Yes" is a perfectly fine answer :)


// Lets runtimes flush a single trace eagerly (e.g. the Cloudflare SDK draining
// a trace the moment its segment ends), without exposing the buffer itself.
client.on('flushTraceSpans', traceId => {

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 is fine since browser ships its own spanStreamingIntegration and thus we don't bloat a browser bundle with this logic.

@JPeer264 JPeer264 Aug 7, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Counter question. Is it safe to flush at any point in time?

FWIW I'm currently testing if we can get rid of this option actually.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@Lms24 just tried to move it over to Sentry.flush directly and it seems under load on deployed workers only half of the traces were received.

After putting some thoughts into it, it might be even bad (even if it would work) to run flush for all traces, as the flush is bound per request, which means one request could potentially suffer performance wise.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Path Size % Change Change
@sentry/browser 30.34 kB +0.02% +6 B 🔺
@sentry/browser - with treeshaking flags 28.55 kB +0.04% +11 B 🔺
@sentry/browser - with treeshaking flags tracing without tracing 26.87 kB +0.03% +6 B 🔺
@sentry/browser (incl. Tracing) 47.81 kB +0.02% +6 B 🔺
@sentry/browser (incl. Tracing + Span Streaming) 47.83 kB +0.02% +7 B 🔺
@sentry/browser (incl. Tracing, Profiling) 52.56 kB +0.02% +8 B 🔺
@sentry/browser (incl. Tracing, Replay) 87.19 kB +0.01% +5 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 76.62 kB +0.01% +7 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 91.91 kB +0.01% +5 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 104.56 kB +0.01% +6 B 🔺
@sentry/browser (incl. Feedback) 47.68 kB +0.02% +7 B 🔺
@sentry/browser (incl. sendFeedback) 35.17 kB +0.02% +6 B 🔺
@sentry/browser (incl. FeedbackAsync) 40.34 kB +0.02% +6 B 🔺
@sentry/browser (incl. Metrics) 31.42 kB +0.02% +5 B 🔺
@sentry/browser (incl. Logs) 31.64 kB +0.02% +6 B 🔺
@sentry/browser (incl. Metrics & Logs) 32.32 kB +0.02% +6 B 🔺
@sentry/react 32.15 kB +0.02% +6 B 🔺
@sentry/react (incl. Tracing) 50.07 kB +0.01% +5 B 🔺
@sentry/vue 35.46 kB +0.02% +4 B 🔺
@sentry/vue (incl. Tracing) 49.82 kB +0.02% +6 B 🔺
@sentry/svelte 30.37 kB +0.02% +6 B 🔺
CDN Bundle 32.34 kB +0.03% +8 B 🔺
CDN Bundle (incl. Tracing) 48.13 kB +0.02% +5 B 🔺
CDN Bundle (incl. Logs, Metrics) 33.89 kB +0.02% +6 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 49.46 kB +0.02% +5 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 73.23 kB +0.01% +5 B 🔺
CDN Bundle (incl. Tracing, Replay) 85.74 kB +0.01% +5 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 87.02 kB +0.01% +5 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 91.56 kB +0.01% +4 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.86 kB +0.01% +6 B 🔺
CDN Bundle - uncompressed 95.91 kB +0.05% +39 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 143.62 kB +0.03% +39 B 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 100.53 kB +0.04% +39 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 147.59 kB +0.03% +39 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 225.23 kB +0.02% +39 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 262.87 kB +0.02% +39 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 266.84 kB +0.02% +39 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 276.58 kB +0.02% +39 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 280.53 kB +0.02% +39 B 🔺
@sentry/nextjs (client) 52.63 kB +0.02% +8 B 🔺
@sentry/sveltekit (client) 48.27 kB +0.02% +9 B 🔺
@sentry/core/server 65.77 kB +0.03% +17 B 🔺
@sentry/core/browser 52 kB +0.04% +19 B 🔺
@sentry/node 119.43 kB +0.02% +21 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 0 B added added
@sentry/node - without tracing 83.39 kB +0.02% +10 B 🔺
@sentry/aws-serverless 92.75 kB +0.04% +31 B 🔺
@sentry/cloudflare (withSentry) - minified 214.91 kB +0.04% +77 B 🔺
@sentry/cloudflare (withSentry) 530.83 kB +0.04% +168 B 🔺

View base workflow run

try {
return await this._transport.send(envelope);
const result = await this._transport.send(envelope);
this.emit('afterEnvelope', envelope);

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.

I'm not fully sure why we need this hook yet. Is the idea that we basically do

cloudflareClient.on('afterEnvelope', () => {
  // potentially with a setTimeout for a grace period or something similar
  cloudflareClient.emit('flushTraceSpans', traceId);
})

?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes exactly. No sure if there is a better solution for this

@Lms24

Lms24 commented Aug 7, 2026

Copy link
Copy Markdown
Member

Ah I guess the concern is flushing other concurrent traces at the same time? Actually this is fair because it would unnecessarily strain network traffic. And add more perf overhead if other telemetry gets flushed, too.

`afterEnvelope` fires after the transport has accepted an envelope. Runtimes
that flush eagerly (e.g. the Cloudflare SDK's cached client) use it to drain the
transport buffer at capture time instead of waiting for an invocation boundary.

`flushTraceSpans` lets a runtime flush a single trace's span bucket from the
span streaming buffer ahead of the regular flush points, without draining the
whole buffer mid-invocation and fragmenting concurrent traces.

Both are no-ops for runtimes that never emit them.
@JPeer264
JPeer264 force-pushed the jp/cacheclient-add-hooks branch from 0d559d6 to 0a80fe6 Compare August 7, 2026 11:46

@Lms24 Lms24 left a comment

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.

thx for answering my questions, sounds good to me, let's :shipit:

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.

2 participants