Tracing
In the Native SDK we have the following scenarios, showcasing how trace-context data flows:
In Tracing without Performance (TwP) the SDK does not create spans. However, we still want to connect events across boundaries so we use a propagation_context
to store the relevant data (a trace_id
and a span_id
) which gets generated during SDK initialization. This propagation_context
can be updated by calling sentry_set_trace()
, for example from a downstream SDK.
When any traces sampling option is enabled, the SDK can send spans. Just like in TwP, we still use a propagation_context
to store the relevant data (a trace_id
and a span_id
). Now, events and spans can be connected through a common trace_id
and, if a span is scoped, it will additionally be connected hierarchically to the event through its span_id
. By default, both spans and events will inherit the trace_id
from the propagation_context
as generated during SDK initialization.
Independent of whether tracing is used with or without performance, downstream SDKs can use sentry_set_trace()
to continue their traces in the Native SDK. This function updates the propagation_context
with a new trace_id
, span_id
, and parent_span_id
.
Root spans (=transactions) will inherit the trace context from the propagation_context
during the transaction context creation, but introduce a new span layer. If users want to override the SDK-established traces with their external traces, this context can be overwritten by using sentry_transaction_context_update_from_header()
. All of this happens before transaction creation or scoping.
Child spans will then inherit the trace data from their parent. As long as a span is scoped, any event will use that span's trace context. If no spans are scoped, events will use the trace data from the propagation_context
directly.
The flow of the trace context (via the propagation_context
) can be visualized for the following scenarios:
- The SDK initializes
propagation_context
with atrace_id
andspan_id
. The event sent will use this data. - The SDK initializes
propagation_context
with atrace_id
andspan_id
, which gets overwritten bysentry_set_trace()
. The event sent will use this updated data. - The SDK initializes
propagation_context
with atrace_id
andspan_id
, which gets overwritten bysentry_set_trace()
. The event sent will use this updated data.
Now, a transaction context is created, which uses thepropagation_context
data.
Since the transaction is started and scoped, any event sent while it is scoped will use the transaction's data (which has the sametrace_id
as thepropagation_context
, but its ownspan_id
). - The SDK initializes
propagation_context
with atrace_id
andspan_id
, which gets overwritten bysentry_set_trace()
. The event sent will use this updated data.
Now, a transaction context is created, which uses thepropagation_context
data.
Since the transaction is started and not scoped, any event sent will use thepropagation_context
data. The transaction and event will still have the sametrace_id
, but differentspan_id
s. - The SDK initializes
propagation_context
with atrace_id
andspan_id
, which gets overwritten bysentry_set_trace()
. The event sent will use this updated data.
Now, a transaction context is created, which uses thepropagation_context
data. It gets updated bysentry_transaction_context_update_from_header()
before starting the transaction, setting a newtrace_id
.
Since the transaction is started and scoped, any event sent while it is scoped will use the transaction's data, which now differs from thepropagation_context
data.
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").