-
-
Notifications
You must be signed in to change notification settings - Fork 276
Add sentry.replay_id
to flutter logs
#3257
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
base: main
Are you sure you want to change the base?
Changes from 19 commits
234bb86
c365316
006a60d
f0030f0
91562e2
1fafd0c
0c6d307
02f86c3
8488d63
9e888b6
1e63021
ccd6a45
b892b55
8b1e81e
506f5cb
f98c32f
744d429
56579e7
a279e8d
34436c7
2b5369f
7980011
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// ignore_for_file: invalid_use_of_internal_member | ||
|
||
import 'package:sentry/sentry.dart'; | ||
import '../sentry_flutter_options.dart'; | ||
import '../native/sentry_native_binding.dart'; | ||
|
||
/// Integration that adds replay-related information to logs using lifecycle callbacks | ||
class ReplayLogIntegration implements Integration<SentryFlutterOptions> { | ||
static const String integrationName = 'ReplayLog'; | ||
|
||
final SentryNativeBinding? _native; | ||
ReplayLogIntegration(this._native); | ||
|
||
SentryFlutterOptions? _options; | ||
SdkLifecycleCallback<OnBeforeCaptureLog>? _addReplayInformation; | ||
|
||
@override | ||
Future<void> call(Hub hub, SentryFlutterOptions options) async { | ||
if (!options.replay.isEnabled) { | ||
return; | ||
} | ||
final sessionSampleRate = options.replay.sessionSampleRate ?? 0; | ||
final onErrorSampleRate = options.replay.onErrorSampleRate ?? 0; | ||
|
||
_options = options; | ||
_addReplayInformation = (OnBeforeCaptureLog event) { | ||
final scopeReplayId = hub.scope.replayId; | ||
final replayId = scopeReplayId ?? _native?.replayId; | ||
final replayIsBuffering = replayId != null && scopeReplayId == null; | ||
|
||
if (sessionSampleRate > 0 && replayId != null && !replayIsBuffering) { | ||
event.log.attributes['sentry.replay_id'] = SentryLogAttribute.string( | ||
scopeReplayId.toString(), | ||
); | ||
} else if (onErrorSampleRate > 0 && | ||
replayId != null && | ||
replayIsBuffering) { | ||
event.log.attributes['sentry.replay_id'] = SentryLogAttribute.string( | ||
replayId.toString(), | ||
); | ||
event.log.attributes['sentry._internal.replay_is_buffering'] = | ||
SentryLogAttribute.bool(true); | ||
} | ||
denrase marked this conversation as resolved.
Show resolved
Hide resolved
denrase marked this conversation as resolved.
Show resolved
Hide resolved
Comment on lines
+26
to
+43
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we add a little note that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. or at least we can create a new issue for it here |
||
}; | ||
options.lifecycleRegistry | ||
.registerCallback<OnBeforeCaptureLog>(_addReplayInformation!); | ||
options.sdk.addIntegration(integrationName); | ||
} | ||
|
||
@override | ||
Future<void> close() async { | ||
final options = _options; | ||
final addReplayInformation = _addReplayInformation; | ||
|
||
if (options != null && addReplayInformation != null) { | ||
options.lifecycleRegistry | ||
.removeCallback<OnBeforeCaptureLog>(addReplayInformation); | ||
} | ||
|
||
_options = null; | ||
_addReplayInformation = null; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,6 +22,9 @@ | |
@override | ||
bool get supportsReplay => options.platform.isIOS; | ||
|
||
@override | ||
SentryId? get replayId => _replayId; | ||
|
||
@override | ||
Future<void> init(Hub hub) async { | ||
// We only need these when replay is enabled (session or error capture) | ||
|
@@ -32,15 +35,20 @@ | |
case 'captureReplayScreenshot': | ||
_replayRecorder ??= CocoaReplayRecorder(options); | ||
|
||
final replayId = call.arguments['replayId'] == null | ||
final replayIdArg = call.arguments['replayId']; | ||
final replayIsBuffering = | ||
call.arguments['replayIsBuffering'] as bool? ?? false; | ||
|
||
final replayId = replayIdArg == null | ||
? null | ||
: SentryId.fromId(call.arguments['replayId'] as String); | ||
: SentryId.fromId(replayIdArg as String); | ||
|
||
if (_replayId != replayId) { | ||
_replayId = replayId; | ||
hub.configureScope((s) { | ||
// Only set replay ID on scope if not buffering (active session mode) | ||
// ignore: invalid_use_of_internal_member | ||
s.replayId = replayId; | ||
s.replayId = !replayIsBuffering ? replayId : null; | ||
}); | ||
} | ||
|
||
|
@@ -58,7 +66,13 @@ | |
} | ||
|
||
@override | ||
FutureOr<SentryId> captureReplay() async { | ||
final replayId = await super.captureReplay(); | ||
_replayId = replayId; | ||
return replayId; | ||
} | ||
|
||
Future<void> close() async { | ||
Check notice on line 75 in packages/flutter/lib/src/native/cocoa/sentry_native_cocoa.dart
|
||
await _envelopeSender?.close(); | ||
return super.close(); | ||
} | ||
|
Uh oh!
There was an error while loading. Please reload this page.