feat(core): Add traceLifecycle option and beforeSendSpan compatibility utilities#19120
Conversation
Adds support for span streaming configuration:
- Add `traceLifecycle` option to ClientOptions ('static' | 'stream')
- Add `BeforeSendSpanCallback` type with optional `_streamed` marker
- Add `withStreamedSpan()` utility to wrap callbacks for streamed spans
- Add `isStreamedBeforeSendSpanCallback()` type guard utility
This is part of the span streaming feature that allows spans to be sent
incrementally rather than waiting for the full trace to complete.
Co-authored-by: Cursor <cursoragent@cursor.com>
Codecov Results 📊Generated by Codecov Action |
size-limit report 📦
|
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.
|
traceLifecycle option and beforeSendSpan compatibility utilities
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.
| * When true, indicates this callback is designed to handle the {@link StreamedSpanJSON} format | ||
| * used with `traceLifecycle: 'stream'`. Set this by wrapping your callback with `withStreamedSpan`. | ||
| */ | ||
| _streamed?: true; |
There was a problem hiding this comment.
M: As only true is allowed here, we might need to set this type to true | undefined in case someone enabled exactOptionalPropertyTypes.
There was a problem hiding this comment.
You're right. However, users shouldn't ever set this but just use the withStreamedSpan helper instead. That being said, it is public API, so we could widen the type enough to make this possible.
Tbh, this withStreamedSpan thing isn't ideal but maybe I could pick your brain a bit for a nicer solution? I was contemplating discrimanted union typing via traceLifecycle but couldn't get it to work without breaking changes for existing users. Maybe you have some ideas how to fix that.
A third option would be to introduce a beforeSendStreamedSpan API for the time span streaming is opt in. Also not ideal because it's again additional API with no great migration path.
Def open for other ideas!
Summary
This PR adds the foundation for span streaming configuration:
traceLifecycleoption: New option inClientOptionsthat controls whether spans are sent statically (when the entire local span tree is complete) or streamed (in batches following interval- and action-based triggers).Because the span JSON will look different for streamed spans vs. static spans (i.e. our current ones, we also need some helpers for
beforeSendSpanwhere users consume and interact withStreamedSpanJSON:withStreamedSpan()utility: Wrapper function that marks abeforeSendSpancallback as compatible with the streamed span format (StreamedSpanJSON)isStreamedBeforeSendSpanCallback()type guard: Internal utility to check if a callback was wrapped withwithStreamedSpanUsage Example
ref #17836