Skip to content

Conversation

denrase
Copy link
Collaborator

@denrase denrase commented Sep 17, 2025

📜 Description

  • Add sentry.replay_id to structured logs
  • Add sentry._internal.replay_is_buffering to structured logs
  • Fixes a bug in test expectations
  • Updates native integrations to get scope and non-scope replay id
    • On iOS we only get scope replay id, so right now we cannot determine buffer mode.

💡 Motivation and Context

Closes #3245

💚 How did you test it?

Unit tests

📝 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

Note

Add ReplayLogIntegration to enrich Flutter structured logs with replay metadata and include it only on replay-supported platforms, with tests and changelog updates.

  • Flutter SDK:
    • Replay log metadata: Introduce ReplayLogIntegration to add sentry.replay_id and sentry._internal.replay_is_buffering to SentryLog via OnBeforeCaptureLog.
    • Default integrations: Add ReplayLogIntegration only when native.supportsReplay is true.
    • Tests:
      • New replay_log_integration_test.dart covering replay id and buffering flag behavior, registration, and cleanup.
      • Update platform integration tests to expect ReplayLogIntegration only on replay-supported platforms.
      • Adjust test/sentry_flutter_util.dart assertion to check by runtimeType for absent integrations.
    • Changelog: Document enhancement under Unreleased.

Written by Cursor Bugbot for commit 02f86c3. This will update automatically on new commits. Configure here.

Copy link

codecov bot commented Sep 17, 2025

Codecov Report

❌ Patch coverage is 93.75000% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 89.58%. Comparing base (2b5e090) to head (7980011).

Files with missing lines Patch % Lines
...ckages/flutter/lib/src/native/c/sentry_native.dart 0.00% 1 Missing ⚠️
.../flutter/lib/src/native/sentry_native_channel.dart 50.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3257      +/-   ##
==========================================
+ Coverage   88.22%   89.58%   +1.36%     
==========================================
  Files         294      100     -194     
  Lines       10209     3553    -6656     
==========================================
- Hits         9007     3183    -5824     
+ Misses       1202      370     -832     

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

Copy link
Contributor

github-actions bot commented Sep 17, 2025

Android Performance metrics 🚀

  Plain With Sentry Diff
Startup time 446.45 ms 422.98 ms -23.47 ms
Size 13.93 MiB 15.06 MiB 1.13 MiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
3615e19 468.38 ms 504.71 ms 36.33 ms
8541716 437.14 ms 443.65 ms 6.51 ms
de377fd 572.35 ms 589.21 ms 16.87 ms
6ba4675 499.80 ms 632.43 ms 132.63 ms
4298701 524.40 ms 633.30 ms 108.90 ms
8825ed8 447.65 ms 456.90 ms 9.25 ms
c8596a6 474.00 ms 492.96 ms 18.96 ms
eca355d 485.50 ms 569.85 ms 84.35 ms
b6c8720 457.41 ms 519.04 ms 61.63 ms
944b773 470.54 ms 480.18 ms 9.64 ms

App size

Revision Plain With Sentry Diff
3615e19 6.54 MiB 7.70 MiB 1.16 MiB
8541716 13.93 MiB 15.00 MiB 1.06 MiB
de377fd 6.54 MiB 7.71 MiB 1.17 MiB
6ba4675 6.54 MiB 7.53 MiB 1015.26 KiB
4298701 6.54 MiB 7.71 MiB 1.17 MiB
8825ed8 13.93 MiB 14.93 MiB 1.00 MiB
c8596a6 6.54 MiB 7.53 MiB 1015.27 KiB
eca355d 6.54 MiB 7.70 MiB 1.16 MiB
b6c8720 6.54 MiB 7.69 MiB 1.15 MiB
944b773 13.93 MiB 15.00 MiB 1.06 MiB

Previous results on branch: enha/logs-replay-id

Startup times

Revision Plain With Sentry Diff
f98c32f 479.02 ms 466.78 ms -12.25 ms
a279e8d 412.42 ms 414.10 ms 1.69 ms
9e888b6 460.09 ms 462.35 ms 2.26 ms
91562e2 464.50 ms 455.70 ms -8.80 ms
1e63021 430.72 ms 453.78 ms 23.06 ms
234bb86 453.89 ms 457.28 ms 3.39 ms
744d429 452.46 ms 460.69 ms 8.23 ms
02f86c3 453.09 ms 454.63 ms 1.55 ms

App size

Revision Plain With Sentry Diff
f98c32f 13.93 MiB 15.00 MiB 1.06 MiB
a279e8d 13.93 MiB 15.06 MiB 1.13 MiB
9e888b6 13.93 MiB 15.00 MiB 1.06 MiB
91562e2 13.93 MiB 15.00 MiB 1.06 MiB
1e63021 13.93 MiB 15.00 MiB 1.06 MiB
234bb86 13.93 MiB 15.00 MiB 1.06 MiB
744d429 13.93 MiB 15.00 MiB 1.06 MiB
02f86c3 13.93 MiB 15.00 MiB 1.06 MiB

Copy link
Contributor

github-actions bot commented Sep 17, 2025

iOS Performance metrics 🚀

  Plain With Sentry Diff
Startup time 1246.08 ms 1262.00 ms 15.92 ms
Size 5.53 MiB 6.00 MiB 487.07 KiB

Baseline results on branch: main

Startup times

Revision Plain With Sentry Diff
827bf09 1261.86 ms 1276.41 ms 14.55 ms
6bcdc99 1257.16 ms 1264.96 ms 7.79 ms
0fb3800 1256.60 ms 1266.28 ms 9.68 ms
cf443d2 1255.79 ms 1248.38 ms -7.40 ms
81f83eb 1259.53 ms 1273.39 ms 13.86 ms
73a3c38 1263.37 ms 1277.90 ms 14.53 ms
54acf91 1257.65 ms 1277.96 ms 20.31 ms
a10aff4 1241.67 ms 1255.02 ms 13.35 ms
32914d8 1275.47 ms 1285.20 ms 9.73 ms
7b21e8b 1256.79 ms 1267.12 ms 10.33 ms

App size

Revision Plain With Sentry Diff
827bf09 7.86 MiB 9.44 MiB 1.58 MiB
6bcdc99 5.53 MiB 6.00 MiB 479.95 KiB
0fb3800 7.86 MiB 9.44 MiB 1.58 MiB
cf443d2 5.53 MiB 6.00 MiB 479.99 KiB
81f83eb 7.86 MiB 9.44 MiB 1.58 MiB
73a3c38 7.86 MiB 9.44 MiB 1.58 MiB
54acf91 20.70 MiB 22.46 MiB 1.75 MiB
a10aff4 5.53 MiB 6.00 MiB 486.71 KiB
32914d8 7.86 MiB 9.44 MiB 1.58 MiB
7b21e8b 5.53 MiB 6.00 MiB 479.96 KiB

Previous results on branch: enha/logs-replay-id

Startup times

Revision Plain With Sentry Diff
1e63021 1244.62 ms 1246.37 ms 1.76 ms
744d429 1254.51 ms 1254.19 ms -0.32 ms
f98c32f 1256.22 ms 1265.67 ms 9.44 ms
9e888b6 1247.65 ms 1245.32 ms -2.33 ms
91562e2 1242.54 ms 1254.08 ms 11.54 ms
234bb86 1241.00 ms 1250.87 ms 9.88 ms
02f86c3 1262.54 ms 1263.67 ms 1.13 ms
a279e8d 1254.24 ms 1251.52 ms -2.72 ms

App size

Revision Plain With Sentry Diff
1e63021 5.53 MiB 6.00 MiB 483.21 KiB
744d429 5.53 MiB 6.00 MiB 483.36 KiB
f98c32f 5.53 MiB 6.00 MiB 483.36 KiB
9e888b6 5.53 MiB 6.00 MiB 483.21 KiB
91562e2 5.53 MiB 6.00 MiB 480.92 KiB
234bb86 5.53 MiB 6.00 MiB 479.96 KiB
02f86c3 5.53 MiB 6.00 MiB 480.79 KiB
a279e8d 5.53 MiB 6.00 MiB 487.08 KiB

@denrase denrase marked this pull request as ready for review September 18, 2025 08:12
@denrase
Copy link
Collaborator Author

denrase commented Sep 22, 2025

@stefanosiano Same here, review pls :)

@stefanosiano
Copy link
Member

looks good, but i'll put it on hold, until the last point has been decided on: https://www.notion.so/sentry/Logs-Replays-Notes-2738b10e4b5d8035b027c6cb0fc57174
TLDR: when replay is in buffering mode, we'd send a replay id even if the replay is not sent. There is a discussion on what to do

@stefanosiano
Copy link
Member

@denrase decision was made
We are going to add a sentry._internal.replay_is_buffering if replay is in buffer mode, and we don't send it if replay is not sampled or in session mode.

Then we keep the sentry.replay_id flag as you already did in this PR 👍

@denrase
Copy link
Collaborator Author

denrase commented Sep 29, 2025

@stefanosiano Pls take a look if i interpreted the flag correctly.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@stefanosiano
Copy link
Member

stefanosiano commented Sep 30, 2025

@denrase
The logic should be this:

  1. Session replay is running -> set sentry.replay_id
  2. Buffer replay is running -> set sentry.replay_id and sentry._internal.replay_is_buffering
  3. No replay is running -> don't set anything

In Android we have this distinction because the replay id is set in the scope when the replay is captured (and it's in session mode), and is only available in the replay integration (and not in the scope) when it's running in buffer mode.
Can we do something similar here?
Also, why are you creating a new integration if you can check it directly in the client in captureLog()?

@denrase
Copy link
Collaborator Author

denrase commented Oct 1, 2025

@stefanosiano Thank you, didn't have access to SentryFlutterOptions in captureLog

@stefanosiano
Copy link
Member

Thank you, didn't have access to SentryFlutterOptions in captureLog

i guess it's fine if you try to cast the options of the scope to SentryFlutterOptions.
At least the logic of enhancing the logs is not scattered in different classes, imho

@denrase
Copy link
Collaborator Author

denrase commented Oct 1, 2025

@stefanosiano AFAIK this only works in the Flutter repo, as the Dart repo does not know about the SentryFlutterOptions class at all.

@stefanosiano
Copy link
Member

@stefanosiano AFAIK this only works in the Flutter repo, as the Dart repo does not know about the SentryFlutterOptions class at all.

yeah right

@denrase
Copy link
Collaborator Author

denrase commented Oct 6, 2025

@stefanosiano Took me a while to debug this and figure out how everything fits together. We have the following issues:

  • On iOS we read the replay ID from the Scope, but do not have access to an internal/integration ID, so we cannot reliably tell if we are in buffer mode. This is called continuously for every screenshot.

  • On Android we get the replay ID from the integration, which we set to the scope, so it's immediately set, even when in buffer mode. This is called once when the recorder is starting.

So the latter is currently incorrect I think. Need to think about how we wan't to tackle this.

\cc @buenaflor

@buenaflor
Copy link
Contributor

@denrase sounds like we need some internal hybrids SDK api from cocoa for this

@buenaflor
Copy link
Contributor

I think it might be good to align with RN here

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@denrase
Copy link
Collaborator Author

denrase commented Oct 8, 2025

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@denrase denrase requested a review from buenaflor October 8, 2025 08:58
@buenaflor
Copy link
Contributor

@buenaflor Checked RN. Right now they are only setting the replay_id without buffering info.

is sentry._internal.replay_is_buffering a strict requirement right now? or should we move forward without it and handle this in another PR?

@denrase
Copy link
Collaborator Author

denrase commented Oct 8, 2025

@buenaflor On Android this works as expected AFAIK, on iOS we can only detect full sessions or onError sessions as soon as they are set to the scope. @stefanosiano Do you know if this would be ok as a step between? RN also only sets replay_id without buffering info, though i did not check if this is already released.

# Conflicts:
#	packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart
Copy link
Contributor

github-actions bot commented Oct 15, 2025

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

Generated by 🚫 dangerJS against 7980011

cursor[bot]

This comment was marked as outdated.

@denrase denrase requested a review from buenaflor October 15, 2025 11:11
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.

Add sentry.replay_id to flutter logs

3 participants