Skip to content

fix(replay): Associate trace IDs with replay segments#5473

Open
romtsn wants to merge 3 commits into
mainfrom
claude/slack-session-JTKa0
Open

fix(replay): Associate trace IDs with replay segments#5473
romtsn wants to merge 3 commits into
mainfrom
claude/slack-session-JTKa0

Conversation

@romtsn
Copy link
Copy Markdown
Member

@romtsn romtsn commented May 27, 2026

📜 Description

This change enables associating trace IDs with replay segments, allowing replays to be searched and filtered by the trace IDs of transactions that occurred during recording.

Key Changes:

  • Added registerTraceId() method to ReplayController interface and implementations
  • Modified BaseCaptureStrategy to collect trace IDs in a ConcurrentHashMap and include them in generated replay segments
  • Updated SentryClient.captureTransaction() to register the transaction's trace ID with the replay controller when a transaction is captured
  • Modified ReplayIntegration to forward trace ID registration to the active capture strategy
  • Updated ReplaySegment to include trace IDs in the replay payload
  • Added validation to ignore empty trace IDs

Implementation Details:

  • Trace IDs are collected in currentTraceIds set during a segment's lifetime
  • After a segment is created, the trace IDs are cleared for the next segment
  • Empty trace IDs (SentryId.EMPTY_ID) are filtered out
  • The feature gracefully handles cases where replay is not recording

💡 Motivation and Context

This enables better correlation between replays and transactions. When a transaction occurs while replay is recording, its trace ID is now associated with the replay segment, making it possible to:

  • Search for replays by trace ID
  • Link replays to specific transactions in the UI
  • Improve debugging workflows by connecting performance data with visual recordings

Closes #5346

💚 How did you test it?

Added comprehensive unit tests covering:

  • registerTraceId includes trace IDs in the next segment
  • registerTraceId clears trace IDs after segment creation
  • registerTraceId ignores empty trace IDs
  • registerTraceId does nothing when replay is not started
  • registerTraceId forwards to capture strategy when recording
  • captureTransaction registers trace ID with replay controller

All tests pass and verify the trace ID registration flow end-to-end.

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

https://claude.ai/code/session_012wjHQtsEPzcrxSMCufxrDY

@romtsn romtsn changed the title Associate trace IDs with replay segments fix(replay): Associate trace IDs with replay segments May 27, 2026
When a transaction is captured while replay is recording, the trace ID
is now registered with the replay controller and included in the next
replay segment. This enables searching for replays by trace ID in the
Sentry UI.

Fixes #5346

Slack thread: https://sentry.slack.com/archives/CP4UUUF1S/p1779889727948439?thread_ts=1777385469.860819&cid=CP4UUUF1S

https://claude.ai/code/session_012wjHQtsEPzcrxSMCufxrDY
@romtsn romtsn force-pushed the claude/slack-session-JTKa0 branch from 1cdc97f to 82b3d84 Compare May 27, 2026 20:54
@sentry
Copy link
Copy Markdown

sentry Bot commented May 27, 2026

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.43.0 (1) release

⚙️ sentry-android Build Distribution Settings

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 27, 2026

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 323.80 ms 355.48 ms 31.68 ms
Size 0 B 0 B 0 B

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
ad8da22 365.86 ms 427.00 ms 61.14 ms
abfcc92 337.38 ms 427.39 ms 90.00 ms
b8bd880 314.56 ms 336.50 ms 21.94 ms
44472da 313.96 ms 365.35 ms 51.39 ms
b03edbb 352.20 ms 423.69 ms 71.49 ms
f6cdbf0 314.19 ms 357.59 ms 43.40 ms
f064536 329.00 ms 395.62 ms 66.62 ms
806307f 357.85 ms 424.64 ms 66.79 ms
d15471f 343.13 ms 361.47 ms 18.34 ms
6edfca2 316.43 ms 398.90 ms 82.46 ms

App size

Revision Plain With Sentry Diff
ad8da22 1.58 MiB 2.29 MiB 719.83 KiB
abfcc92 1.58 MiB 2.13 MiB 557.31 KiB
b8bd880 1.58 MiB 2.29 MiB 722.92 KiB
44472da 0 B 0 B 0 B
b03edbb 1.58 MiB 2.13 MiB 557.32 KiB
f6cdbf0 0 B 0 B 0 B
f064536 1.58 MiB 2.20 MiB 633.90 KiB
806307f 1.58 MiB 2.10 MiB 533.42 KiB
d15471f 1.58 MiB 2.13 MiB 559.54 KiB
6edfca2 1.58 MiB 2.13 MiB 559.07 KiB

Previous results on branch: claude/slack-session-JTKa0

Startup times

Revision Plain With Sentry Diff
6ac7673 322.49 ms 370.88 ms 48.39 ms

App size

Revision Plain With Sentry Diff
6ac7673 0 B 0 B 0 B

@romtsn romtsn force-pushed the claude/slack-session-JTKa0 branch 3 times, most recently from 250a9e4 to a948a1a Compare May 27, 2026 21:24
@romtsn romtsn force-pushed the claude/slack-session-JTKa0 branch from eda19a1 to 68edd9a Compare May 27, 2026 21:30
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0058908. Configure here.


protected val currentEvents: Deque<RRWebEvent> = ConcurrentLinkedDeque()
private val traceIdsLock = Any()
protected val currentTraceIds: MutableList<String> = mutableListOf()
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-thread-safe list exposed as protected with private lock

Low Severity

currentTraceIds is declared protected (accessible by subclasses) but uses a non-thread-safe mutableListOf(), while its guarding traceIdsLock is private (inaccessible by subclasses). This is inconsistent with the sibling currentEvents, which is also protected but uses a thread-safe ConcurrentLinkedDeque. A subclass accessing currentTraceIds directly would bypass synchronization, risking a data race. Making currentTraceIds private would match the lock's visibility and prevent unsynchronized access.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0058908. Configure here.

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.

Search by replayID give no results on the Traces view.

3 participants