Skip to content

feat(flutter): Add replay trace ID sync for Android#3744

Merged
buenaflor merged 7 commits into
mainfrom
buenaflor/feat/searchable-trace-replay
Jun 8, 2026
Merged

feat(flutter): Add replay trace ID sync for Android#3744
buenaflor merged 7 commits into
mainfrom
buenaflor/feat/searchable-trace-replay

Conversation

@buenaflor

@buenaflor buenaflor commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

📜 Description

Register Dart transaction and stream segment trace IDs with native Android replay through the new registerTraceId JNI binding. This lets native replay segments collect trace_ids for Flutter app activity so replays can be found by trace ID.

💡 Motivation and Context

Flutter delegates replay recording to the native SDK, but Dart-traceId were not forwarded to native replay for trace ID collection. The SDK now dispatches an internal lifecycle event after Dart transactions are captured and lets replay telemetry register transaction and segment trace IDs with the native binding.

Partly resolves #3729 - only for Android currently

💚 How did you test it?

  • fvm dart test test/sentry_client_sdk_lifecycle_test.dart
  • fvm flutter test test/integrations/replay_telemetry_integration_test.dart
  • fvm flutter test test/integrations/native_trace_sync_integration_test.dart
  • fvm dart analyze lib/src/sdk_lifecycle_hooks.dart lib/src/sentry_client.dart test/sentry_client_sdk_lifecycle_test.dart
  • fvm flutter analyze lib/src/integrations/replay_telemetry_integration.dart lib/src/native/sentry_native_binding.dart lib/src/native/java/sentry_native_java.dart lib/src/native/c/sentry_native.dart lib/src/native/sentry_native_channel.dart lib/src/web/sentry_web.dart test/integrations/replay_telemetry_integration_test.dart test/mocks.mocks.dart
  • Pre-commit hook ran package-level Dart and Flutter analyzers successfully.

📝 Checklist

  • I reviewed submitted code
  • I added tests to verify changes
  • No new PII added or SDK only sends newly added PII if sendDefaultPii is enabled
  • I updated the docs if needed
  • All tests passing
  • No breaking changes

🔮 Next steps

Native Android behavior is covered through the generated JNI binding and existing native SDK implementation; the Dart/Flutter tests cover lifecycle dispatch and adapter forwarding.

Made with Cursor

Register Dart transaction and segment trace IDs with native Android
replay so replay segments can be discovered by trace ID.

Closes #3729
Co-Authored-By: GPT-5.5 <[email protected]>

Co-authored-by: Cursor <[email protected]>
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


Features

  • (flutter) Add replay trace ID sync for Android by buenaflor in #3744

Fixes

  • (flutter) Add replay IDs to span telemetry by buenaflor in #3739

Dependencies

  • chore(deps): update Android SDK to v8.43.1 by github-actions in #3740

Internal Changes

  • Pin macOS runners to macos-15 by buenaflor in #3731

🤖 This preview updates automatically when you update the PR.

@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.00000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 91.93%. Comparing base (1980dca) to head (cc43931).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...ckages/flutter/lib/src/native/c/sentry_native.dart 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3744      +/-   ##
==========================================
+ Coverage   86.98%   91.93%   +4.95%     
==========================================
  Files         336      105     -231     
  Lines       11997     3758    -8239     
==========================================
- Hits        10435     3455    -6980     
+ Misses       1562      303    -1259     
Flag Coverage Δ
sentry ?
sentry_dio ?
sentry_drift ?
sentry_file ?
sentry_firebase_remote_config 100.00% <ø> (ø)
sentry_flutter 91.55% <90.00%> (-0.01%) ⬇️
sentry_hive ?
sentry_isar ?
sentry_link ?
sentry_logging ?
sentry_sqflite ?
sentry_supabase 97.27% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Android Performance metrics 🚀

  Plain With Sentry Diff
Startup time 403.16 ms 404.56 ms 1.40 ms
Size 14.55 MiB 15.87 MiB 1.31 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
f11c8f8 360.00 ms 348.43 ms -11.57 ms
e1ab497 429.30 ms 439.00 ms 9.70 ms
1e46846 419.06 ms 429.65 ms 10.59 ms
2cf9161 454.12 ms 512.67 ms 58.55 ms
396cb30 405.70 ms 427.56 ms 21.86 ms
667e3c4 402.86 ms 394.04 ms -8.82 ms
e8f0fc4 348.40 ms 353.34 ms 4.94 ms
40751bf 421.09 ms 424.82 ms 3.73 ms
eca355d 485.50 ms 569.85 ms 84.35 ms
1f639ee 429.98 ms 476.60 ms 46.62 ms

App size

Revision Plain With Sentry Diff
f11c8f8 14.55 MiB 15.87 MiB 1.31 MiB
e1ab497 13.93 MiB 15.06 MiB 1.13 MiB
1e46846 14.31 MiB 15.56 MiB 1.25 MiB
2cf9161 6.54 MiB 7.70 MiB 1.16 MiB
396cb30 13.93 MiB 15.06 MiB 1.13 MiB
667e3c4 14.55 MiB 15.87 MiB 1.31 MiB
e8f0fc4 14.55 MiB 15.87 MiB 1.31 MiB
40751bf 14.31 MiB 15.49 MiB 1.19 MiB
eca355d 6.54 MiB 7.70 MiB 1.16 MiB
1f639ee 13.93 MiB 15.00 MiB 1.06 MiB

Previous results on branch: buenaflor/feat/searchable-trace-replay

Startup times

Revision Plain With Sentry Diff
51e2c94 374.19 ms 386.85 ms 12.66 ms
e5db8cc 353.67 ms 332.43 ms -21.24 ms

App size

Revision Plain With Sentry Diff
51e2c94 14.55 MiB 15.87 MiB 1.31 MiB
e5db8cc 14.55 MiB 15.87 MiB 1.31 MiB

Register native replay trace IDs when the Dart propagation trace is
created or regenerated. This keeps replay telemetry aligned with the
trace lifecycle even when no span or transaction is captured.

Co-Authored-By: GPT-5.5 <[email protected]>
Co-authored-by: Cursor <[email protected]>
@buenaflor buenaflor changed the title feat(flutter): Add replay trace ID sync feat(flutter): Add replay trace ID sync for Android Jun 8, 2026
buenaflor and others added 2 commits June 8, 2026 13:38
Remove the internal transaction-captured lifecycle callback now that no
integration consumes it. This avoids keeping dead callback surface after
replay trace registration moved to trace generation.

Co-Authored-By: GPT-5.5 <[email protected]>
Co-authored-by: Cursor <[email protected]>
Comment thread packages/dart/lib/src/sentry_client.dart Outdated
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

iOS Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1237.29 ms 1252.15 ms 14.87 ms
Size 5.83 MiB 6.28 MiB 461.61 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
9d516f3 1256.04 ms 1262.70 ms 6.66 ms
eca355d 1238.39 ms 1266.98 ms 28.59 ms
d0aa4b6 1268.23 ms 1268.39 ms 0.15 ms
29e8ebe 1260.46 ms 1262.60 ms 2.14 ms
8bfae64 1237.43 ms 1238.94 ms 1.51 ms
5fc86f6 1245.91 ms 1248.54 ms 2.63 ms
3f47ea3 1263.90 ms 1263.87 ms -0.02 ms
ec78888 1251.37 ms 1269.40 ms 18.04 ms
7cfbbd6 1270.63 ms 1285.36 ms 14.72 ms
75284dc 1254.81 ms 1262.28 ms 7.46 ms

App size

Revision Plain With Sentry Diff
9d516f3 5.73 MiB 6.18 MiB 463.54 KiB
eca355d 7.86 MiB 9.44 MiB 1.58 MiB
d0aa4b6 5.53 MiB 6.02 MiB 502.04 KiB
29e8ebe 5.53 MiB 6.01 MiB 488.12 KiB
8bfae64 5.66 MiB 6.10 MiB 451.85 KiB
5fc86f6 5.83 MiB 6.28 MiB 462.37 KiB
3f47ea3 5.53 MiB 5.96 MiB 444.81 KiB
ec78888 7.86 MiB 9.44 MiB 1.58 MiB
7cfbbd6 7.86 MiB 9.44 MiB 1.58 MiB
75284dc 5.53 MiB 5.97 MiB 453.77 KiB

Previous results on branch: buenaflor/feat/searchable-trace-replay

Startup times

Revision Plain With Sentry Diff
51e2c94 1273.14 ms 1271.37 ms -1.78 ms
e5db8cc 1257.61 ms 1266.47 ms 8.86 ms
fc7b45c 1258.74 ms 1268.50 ms 9.76 ms

App size

Revision Plain With Sentry Diff
51e2c94 5.83 MiB 6.28 MiB 461.61 KiB
e5db8cc 5.83 MiB 6.28 MiB 461.60 KiB
fc7b45c 5.83 MiB 6.28 MiB 461.62 KiB

Restore the lifecycle test fixture to match main while keeping the
transaction-captured callback removed from this branch.

Co-Authored-By: GPT-5.5 <[email protected]>
Co-authored-by: Cursor <[email protected]>
@buenaflor
buenaflor marked this pull request as ready for review June 8, 2026 11:52
@buenaflor
buenaflor requested a review from denrase as a code owner June 8, 2026 11:52
Copilot AI review requested due to automatic review settings June 8, 2026 11:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a Flutter-to-native Android bridge for replay trace ID synchronization by introducing a new registerTraceId binding and wiring it into the replay telemetry integration via SDK lifecycle events, so native replay segments can be associated with Dart/Flutter trace IDs for searchability.

Changes:

  • Adds registerTraceId(SentryId traceId) to SentryNativeBinding and implements it for Android via JNI (SentryNativeJava), with no-op implementations for other platforms.
  • Updates ReplayTelemetryIntegration to register the initial trace ID and newly generated trace IDs (via OnGenerateNewTrace) with the native binding.
  • Extends Flutter tests/mocks to validate forwarding behavior and callback cleanup.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/flutter/lib/src/native/sentry_native_binding.dart Adds the new registerTraceId API to the native binding contract.
packages/flutter/lib/src/native/java/sentry_native_java.dart Implements registerTraceId through the JNI replay integration on Android.
packages/flutter/lib/src/integrations/replay_telemetry_integration.dart Registers initial/new trace IDs with native replay using lifecycle callbacks.
packages/flutter/lib/src/web/sentry_web.dart Adds a no-op registerTraceId implementation for web.
packages/flutter/lib/src/native/sentry_native_channel.dart Adds a no-op registerTraceId implementation for method-channel platforms.
packages/flutter/lib/src/native/c/sentry_native.dart Adds a no-op registerTraceId implementation for the C/FFI binding.
packages/flutter/test/integrations/replay_telemetry_integration_test.dart Adds test coverage for trace ID registration and callback removal.
packages/flutter/test/mocks.mocks.dart Updates generated mock to include registerTraceId.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread packages/flutter/lib/src/integrations/replay_telemetry_integration.dart Outdated
Comment thread packages/flutter/lib/src/integrations/replay_telemetry_integration.dart Outdated
Await native replay trace registration so lifecycle dispatch does not
complete before async native bindings finish syncing the trace ID.

Co-Authored-By: GPT-5.5 <[email protected]>
Co-authored-by: Cursor <[email protected]>
final spanId = SpanId.newId();

await fixture.getSut().call(fixture.hub, fixture.options);
clearInteractions(fixture.nativeBinding);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why do we need to clear interactions here?

@buenaflor buenaflor Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

because when the integration is called we register the trace id, without this we would have two calls because we trigger the callback

@buenaflor
buenaflor merged commit b4f5295 into main Jun 8, 2026
69 checks passed
@buenaflor
buenaflor deleted the buenaflor/feat/searchable-trace-replay branch June 8, 2026 15:35
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.

Populate trace_ids in replay events to enable searching replays by trace ID

3 participants