Skip to content

feat: Associate replays with errors and traces on Android #4133

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

Draft
wants to merge 17 commits into
base: main
Choose a base branch
from

Conversation

jamescrosswell
Copy link
Collaborator

@jamescrosswell jamescrosswell commented Apr 23, 2025

Part of #2136

Associate Errors and Traces with the active Session Replay (if one exists) on Android.

Protocol

Although there is a new Replay context, I found that just setting the replay_id on that context (e.g. for an event) did not result in the event showing in the errors pane for session replays.

What was recommended, and work better, is to store the replay_id on the DSC (which will accompany all events) and let Relay unpack it from there. The DSC specification mentions replay_id as an optional property on the dynamic sampling context.

Getting the Replay ID

There are three ways the DSC can be created:

  1. From the currently active transaction
  2. From the propagation context
  3. From a BaggageHeader (in distributed tracing scenarios)

From the Transaction

When starting a new transaction, we check first to see if there's a replay_id on the DSC (in distributed transactions - probably won't hit this in a MAUI app). If it's present, we use that. Otherwise we try to get the replay_id from the Java SDK:

transaction.Contexts.Replay.ReplayId = dynamicSamplingContext?.Items.TryGetValue("replay_id", out var replayId) == true
? SentryId.Parse(replayId)
: ReplayHelper.GetReplayId();

This then gets stored in the DSC when creating the DSC for the transaction (if it doesn't already exist):

// Use the provided DSC, or create one based on this transaction.
// DSC creation must be done AFTER the sampling decision has been made.
transaction.DynamicSamplingContext =
dynamicSamplingContext ?? transaction.CreateDynamicSamplingContext(_options);

From the propagation context

When continuing a trace in a distributed transaction when performance is disabled, a propagation context is created from the baggage headers and then stored on the scope:

var propagationContext = SentryPropagationContext.CreateFromHeaders(_options.DiagnosticLogger, traceHeader, baggageHeader);
ConfigureScope(scope => scope.SetPropagationContext(propagationContext));

If there is no DSC (no baggage headers) then a new DSC is created for the PropagationContext:

public DynamicSamplingContext GetOrCreateDynamicSamplingContext(SentryOptions options)
{
if (_dynamicSamplingContext is null)
{
options.LogDebug("Creating the Dynamic Sampling Context from the Propagation Context");
_dynamicSamplingContext = this.CreateDynamicSamplingContext(options);
}
return _dynamicSamplingContext;
}

In that case, we populate the replay_id from the Java SDK:

var replayId = ReplayHelper.GetReplayId();

On the other hand, if there are baggage headers and the PropagationContext does have a DSC, the ContinueTrace method returns a TransactionContext after storing the PropagationContext on the scope:

return new TransactionContext(
name: name ?? string.Empty,
operation: operation ?? string.Empty,
spanId: propagationContext.SpanId,
parentSpanId: propagationContext.ParentSpanId,
traceId: propagationContext.TraceId,
isSampled: traceHeader?.IsSampled,
isParentSampled: traceHeader?.IsSampled);

This gets used when creating a new TransactionTracer.

// If there is a ReplayId on the PropagationContext, set this in the Contexts
hub.ConfigureScope(s => Contexts.Replay.ReplayId = s.PropagationContext.GetReplayId());

Part of #2136

Associate Errors and Traces with the active Session Replay (if one exists) on Android.
Copy link
Contributor

github-actions bot commented Apr 23, 2025

Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against 6d770cb

@jamescrosswell jamescrosswell marked this pull request as ready for review April 28, 2025 08:42
@jamescrosswell jamescrosswell marked this pull request as draft April 29, 2025 06:16
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