-
-
Notifications
You must be signed in to change notification settings - Fork 200
feat: manage trace life-cycle #1270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
c06cdd8 to
8542e8d
Compare
|
This change is no longer relevant, since traces can now have arbitrary length. Summary of the quick discussion we had about this: if this ever comes up again, then the right choice parameterization is to define the number of captures until a trace is invalidated. |
|
After a chat with @cleptric , we actually do want Transactions to be the default trace boundary in the native SDK. The idea of having multiple transactions in one trace only holds for platforms where there actually are specific trace-boundaries (e.g. mobile screen load, web page load, unity scene load, ...). This is not the case for Native, hence we reopen this PR to be merged before release + I think we can still keep the manual trace boundary API around for Tracing Without Performance (e.g. for a custom boundary between events/logs/...). Other SDKs solve this by still having pageloads/screenloads/requests/... start a new trace, but in native we don't have a boundary like this. If people want to avoid an unending trace with millions of manual event captures/logs in a TwP setting, they should be using the manual trace boundary API. This page needs an updated graphic; although the behaviour post- |
VisualizationsTo better understand the flow of the trace_id, I created the visualizations below. General Flowgraph TD
A[SDK Init] --> B[trace_managed = true]
B --> C[Create Transaction Context]
C --> D{trace_managed?}
D -->|true| E[Generate Fresh Trace ID]
D -->|false| F
E --> F[Create Transaction]
F --> G[Send Event During Transaction]
G --> H{Transaction Scoped?}
H -->|Yes| I[Event uses Transaction Trace]
H -->|No| J[Event uses Propagation Context]
I --> K[Finish Transaction]
J --> K
K --> L{trace_managed?}
L -->|true| M[Update Propagation Context<br/>with Transaction Trace ID]
L -->|false| N[Keep Propagation Context<br/>as it is]
style E fill:#49516e
style I fill:#256332
style M fill:#c98530
Start(t:a) → Tx_s(t:b) → E(t:a) → Tx_e(t:b) → E(t:b)flowchart TD
A["SDK Init<br/>🏁 Start(t:a)<br/>Propagation Context: trace_id = 'a'"] --> B["Transaction Start<br/>🚀 Tx_s(t:b)<br/>Fresh trace_id = 'b'<br/>(NOT scoped)"]
B --> C{"Transaction<br/>Scoped?"}
C -->|No| D["Event Captured<br/>📧 E(t:a)<br/>Uses Propagation Context<br/>trace_id = 'a'"]
D --> E["Transaction Finish<br/>🏁 Tx_e(t:b)<br/>Updates Propagation Context<br/>trace_id = 'a' → 'b'"]
E --> F["Event Captured<br/>📧 E(t:b)<br/>Uses Updated Propagation Context<br/>trace_id = 'b'"]
C -->|Yes| G["Event would use<br/>Transaction trace 'b'<br/>(Alternative path)"]
style A fill:#2e4e2e,color:#ffffff
style B fill:#4a3728,color:#ffffff
style D fill:#4a2c2c,color:#ffffff
style E fill:#1e3a5f,color:#ffffff
style F fill:#2d4a2d,color:#ffffff
style G fill:#3d2a3d,color:#ffffff,stroke-dasharray: 5 5
classDef traceA fill:#5a2d2d,stroke:#ff6b6b,stroke-width:2px,color:#ffffff
classDef traceB fill:#2d4a2d,stroke:#69db7c,stroke-width:2px,color:#ffffff
class A,D traceA
class B,E,F traceB
|
# Conflicts: # src/sentry_core.c # tests/unit/test_tracing.c
JoshuaMoelans
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM; only needs fixing the one 'alternative' if 0 path.
…regenerates a trace
…ntry_set_trace()` and `sentry_regenerate_trace()`
JoshuaMoelans
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just very minor nit on a typo
Co-authored-by: JoshuaMoelans <[email protected]>
| sentry_value_set_by_key( | ||
| sentry_value_get_by_key(scope->propagation_context, "trace"), | ||
| "trace_id", txn_trace_id); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Trace Context Inconsistency After Transaction
When a transaction finishes and the SDK manages the trace, the propagation context's trace_id is updated to match the finished transaction, but its parent_span_id and span_id are not. This creates an inconsistent trace context where the trace_id is new but the span_id and parent_span_id are from the old context, breaking the trace hierarchy for subsequent events and violating span ID uniqueness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is intentional until further specification counters the decision. From our current POV, only the trace_id should be changed, and the dummy hierarchy created during initialization can survive without compromising the effect of a trace boundary. I raised this topic during development and this resulted in the current decision. We can change this anytime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sentry-native/src/sentry_core.c
Lines 1083 to 1087 in 0788b37
| // TODO: what should we do with the span_id in the | |
| // propagation_context? We can't use the transaction's, because we | |
| // want to be outside the transaction's span hierarchy. Could we | |
| // just keep the initially created dummy or should generate a new | |
| // one? |
This PR adds documentation for the behavior introduced in getsentry/sentry-native#1270. This PR should be merged/deployed after the Native SDK release `0.10.0`. ## IS YOUR CHANGE URGENT? Help us prioritize incoming PRs by letting us know when the change needs to go live. - [ ] Urgent deadline (GA date, etc.): <!-- ENTER DATE HERE --> - [ ] Other deadline: <!-- ENTER DATE HERE --> - [x] None: Not urgent, can wait up to 1 week+ ## SLA - Teamwork makes the dream work, so please add a reviewer to your PRs. - Please give the docs team up to 1 week to review your PR unless you've added an urgent due date to it. Thanks in advance for your help! ## PRE-MERGE CHECKLIST *Make sure you've checked the following before merging your changes:* - [ ] Checked Vercel preview for correctness, including links - [ ] PR was reviewed and approved by any necessary SMEs (subject matter experts) - [ ] PR was reviewed and approved by a member of the [Sentry docs team](https://github.com/orgs/getsentry/teams/docs) ## EXTRA RESOURCES - [Sentry Docs contributor guide](https://docs.sentry.io/contributing/) --------- Co-authored-by: JoshuaMoelans <[email protected]>
With the recently introduced support for traces without performance (
TwP) and how they interact with performance-related traces, we broke with an undocumented assumption: there should be no endless traces.Endless traces would have consequences for the visualization in the web UI as well as sampling decisions, as we'd like to introduce in #1254 (where events/transactions along a single trace should follow the same dice roll, to obtain complete traces).
Since all events inherit their traces from the propagation context, which the SDK initializes with a random trace and dummy span, this trace would be active forever. When
sentry_set_trace()is used (either by the user directly or in a downstream SDK), this also means that the caller assumes the burden of managing the trace life-cycle. However, if this doesn't happen, it is the Native SDK's duty.After a short discussion during last week's sync, we established transactions as a boundary that breaks traces (leaving the question open of what happens without performance, which I tried to address in the comments).
Related docs PR: getsentry/sentry-docs#14586