Skip to content

feat(cloudflare): propagate tracing context through Queue messages - #25306

Open
arthurfiorette wants to merge 7 commits into
getsentry:developfrom
arthurfiorette:arthurfiorette/queue-links
Open

arthurfiorette wants to merge 7 commits into
getsentry:developfrom
arthurfiorette:arthurfiorette/queue-links

Conversation

@arthurfiorette

@arthurfiorette arthurfiorette commented Oct 13, 2026 •

Copy link
Copy Markdown

This extends #22303, which was auto-closed for inactivity after its review comments slipped through my GitHub inbox. It is now synced with develop and addresses that review.


Adds opt-in trace propagation from Cloudflare Queue producers to consumers.

  • When a producer binding matches queueTracePropagationBindings, plain-object message bodies carry the producer's sentry-trace under __sentry_queue_trace__.
  • Arrays, binary payloads and other non-plain values are sent unchanged.
  • Consumers remove that field before invoking the application handler.
  • queue.process remains a root span and links to every distinct producer in the batch.

Span links are used instead of continuing a producer trace because a Queue batch can contain messages from unrelated traces. Picking one producer as the parent would create false causal relationships for the other messages.

Propagation is opt-in per binding because Cloudflare Queues has no message-header API. The SDK has to modify the message body, so consumers without Sentry would see the extra field.

Changes since #22303:

  • enableQueueTracePropagation: boolean became queueTracePropagationBindings, mirroring rpcTracePropagationBindings (feat(cloudflare)!: Replace enableRpcTracePropagation with rpcTracePropagationBindings #23486). Only the producer opts in, since it is the side that changes the payload. Consumers always strip and link, the same way RPC receivers handle __sentry_rpc_meta__.
  • Links no longer set sentry.link.type: previous_trace. A batch fans in producers rather than forming a previous/next chain.

Fixes #22309

arthurfiorette and others added 6 commits July 15, 2026 15:25
- Replace `enableQueueTracePropagation` with `queueTracePropagationBindings`, matching
  `rpcTracePropagationBindings`: producers opt in per binding, consumers always strip and link.
- Drop the `previous_trace` link type, a batch fans in producers rather than chaining traces.
- Strip the carrier with `Reflect.deleteProperty` on the shared key so frozen bodies cannot throw.
- Compute the publish body size once when propagation is enabled.
- Move the queue integration assertions to span streaming.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the external PR from an external contributor label Oct 13, 2026
@arthurfiorette
arthurfiorette marked this pull request as ready for review October 13, 2026 03:47
@arthurfiorette
arthurfiorette requested a review from a team as a code owner October 13, 2026 03:47
@arthurfiorette
arthurfiorette requested review from JPeer264 and mydea and removed request for a team October 13, 2026 03:47
@Lms24

Lms24 commented Oct 13, 2026

Copy link
Copy Markdown
Member

HI @arthurfiorette thanks for opening another PR for this! I'll leave the review up to @JPeer264 who has more context on the cloudflare specific details.

Good idea to use span links. I think we should still set the sentry.link.type link attribute, but probably with the message_origin value as proposed here https://github.com/getsentry/sentry-javascript/pull/21777/changes#r4227878655. Unfortunately, that PR is not yet merged so we have to wait a bit for the final link type value. Shouldn't stop the rest of the review though :)

@JPeer264

Copy link
Copy Markdown
Member

I'll wait on reviewing that PR until #21777 is finished. In that PR is an open point on how we deal with span links for queues. This might be then also relevant for this PR. I think by mid next week I can start reviewing this. Hope the timeline is ok for you.

@github-actions

Copy link
Copy Markdown
Contributor

👋 @mydea, @JPeer264 — Please review this PR when you get a chance!

@JPeer264
JPeer264 removed the request for review from mydea October 20, 2026 10:23

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

Adding a comment here, so the bot isn't creating a false positive.

I'm still working on #21777 to finalize (it is soon ready, just need to polish some things) - then I can review this PR properly

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

Sorry that it took a while, but I was finally able to finish of the remaining work of the other PR, that blocked this PR.

It is good that we add a new queueTracePropagationBindings option, since the current one is only focusing on rpc (I originally thought of having a one size fits all option, but I don't think that would have been a good idea).

I added some comments, so please take a look at them. The rest of the code looks good, great work - thank you.

Comment thread CHANGELOG.md

### Other Changes

- feat(cloudflare): Add `queueTracePropagationBindings` to link Queue producer and consumer traces ([#25306](https://github.com/getsentry/sentry-javascript/pull/25306))

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.

You can remove this, we auto generate it based on the PR title, then you won't have merge conflicts like now

traceId: producerContext.traceId,
spanId: producerContext.spanId,
traceFlags: producerContext.sampled ? TraceFlags.SAMPLED : TraceFlags.NONE,
isRemote: true,

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 think we can remove the isRemote: true. Was there a specific point, why this has been added?

Suggested change
isRemote: true,

Comment on lines +37 to +38
links.push({
context: {

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.

The main reason why I held back reviewing this PR. Please add the link type attribute message_origin (https://develop.sentry.dev/sdk/telemetry/traces/span-links/#message_origin):

Suggested change
links.push({
context: {
links.push({
attributes: {
[SENTRY_LINK_TYPE]: 'message_origin'
},
context: {

Please also make sure this is reflected in the tests.

return undefined;
}

return {

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.

There is a limit of 128kb in Cloudflare for messages: https://developers.cloudflare.com/queues/platform/limits/

We might need to document this in the code that this could be a caveat. It's not a lot of extra bytes, but may be causing issues in some cases (it's definitely going to be added in our docs then)

return item;
}

if (isQueue(item)) {

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 don't think we would need this new logic - it could stay as it was before if I'm not mistaken. We also shouldn't optimize for a changing config.

With the logic before we're caching per binding object, and each binding (queue) would have its own flag if it has trace propagation enabled or not. So I guess the following would work as well:

if (isQueue(item)) {
  const bindingName = typeof prop === 'string' ? prop : String(prop);
  const instrumented = instrumentQueueProducer(item, bindingName, shouldPropagateQueueTrace(bindingName));
  instrumentedBindings.set(item, instrumented);
  return instrumented;
}

* );
* ```
*/
queueTracePropagationBindings?: TracePropagationTargets;

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.

note to myself. We might need to extend this in our Vite plugin to automatically add these in case they're in the same deployment

@@ -1,18 +1,14 @@
import { matchesTracePropagationTargets } from '@sentry/core';
import { matchesTracePropagationTargets, type TracePropagationTargets } from '@sentry/core';

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.

Super low priority. Technically this file is doing more now than just rpcPropagation , so we could rename it to something more generic, but not a must. You can decide as you see fit.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external PR from an external contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cloudflare Queue context propagation and trace links

3 participants