Skip to content

Commit

Permalink
poc
Browse files Browse the repository at this point in the history
  • Loading branch information
buenaflor committed Feb 6, 2024
1 parent 1dbc007 commit f2668bb
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 14 deletions.
4 changes: 3 additions & 1 deletion flutter/example/lib/auto_close_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ class AutoCloseScreenState extends State<AutoCloseScreen> {
final childSpan = activeSpan?.startChild('complex operation',
description: 'running a $delayInSeconds seconds operation');
await Future.delayed(const Duration(seconds: delayInSeconds));
childSpan?.finish();
await childSpan?.finish();
await Future.delayed(const Duration(seconds: 2));
SentryFlutter.reportFullDisplay();
// ignore: use_build_context_synchronously
Navigator.of(context).pop();
}
Expand Down
1 change: 1 addition & 0 deletions flutter/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ Future<void> setupSentry(AppRunner appRunner, String dsn,
options.attachScreenshot = true;
options.screenshotQuality = SentryScreenshotQuality.low;
options.attachViewHierarchy = true;
options.enableTimeToFullDisplayTracing = true;
// We can enable Sentry debug logging during development. This is likely
// going to log too much for your app, but can be useful when figuring out
// configuration issues, e.g. finding out why your events are not uploaded.
Expand Down
30 changes: 18 additions & 12 deletions flutter/lib/src/navigation/sentry_navigator_observer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ class SentryNavigatorObserver extends RouteObserver<PageRoute<dynamic>> {
static String? get currentRouteName => _currentRouteName;
static var startTime = DateTime.now();
static ISentrySpan? ttidSpan;
static ISentrySpan? ttfdSpan;
static var ttfdStartTime = DateTime.now();
static Stopwatch? ttfdStopwatch;

@override
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
Expand All @@ -114,26 +117,27 @@ class SentryNavigatorObserver extends RouteObserver<PageRoute<dynamic>> {
);

_finishTransaction();

var routeName = route.settings.name ?? 'Unknown';

_startTransaction(route);

// Start timing
DateTime? approximationEndTimestamp;
int? approximationDurationMillis;
final routeName = _getRouteName(route);

SchedulerBinding.instance.addPostFrameCallback((timeStamp) {
approximationEndTimestamp = DateTime.now();
approximationDurationMillis =
approximationEndTimestamp!.millisecond - startTime.millisecond;
});

SentryDisplayTracker().startTimeout(routeName, () {
SentryDisplayTracker().startTimeout(routeName ?? 'Unknown', () {
if (routeName == '/') {
// TODO: Does TTID have to be completely in line with app start?
// If yes, how do we access the appstart metrics
}
_transaction2?.setMeasurement(
'time_to_initial_display', approximationDurationMillis!,
unit: DurationSentryMeasurementUnit.milliSecond);
ttidSpan?.setTag('measurement', 'approximation');
ttidSpan?.finish(endTimestamp: approximationEndTimestamp!);
});
}
Expand Down Expand Up @@ -244,8 +248,6 @@ class SentryNavigatorObserver extends RouteObserver<PageRoute<dynamic>> {
origin: SentryTraceOrigins.autoNavigationRouteObserver,
);

// IMPORTANT -> we need to wait for ttid/ttfd children to finish AND wait [autoFinishAfter] afterwards so the user can add additional spans
// right now it auto finishes when ttid/ttfd finishes but that doesn't allow the user to add spans within the idle timeout
_transaction2 = _hub.startTransactionWithContext(
transactionContext2,
waitForChildren: true,
Expand Down Expand Up @@ -275,13 +277,17 @@ class SentryNavigatorObserver extends RouteObserver<PageRoute<dynamic>> {
}

startTime = DateTime.now();
ttidSpan = _transaction2?.startChild('ui.load.initial_display');
ttidSpan = _transaction2?.startChild('ui.load.initial_display', description: '$name initial display');
ttidSpan?.origin = 'auto.ui.time_to_display';
ttidSpan?.setData('test', 'cachea');

// Needs to finish after 30 seconds
// If not then it will finish with status deadline exceeded
// final ttfdSpan = _transaction2?.startChild('ui.load.full_display');
// TODO: Needs to finish max within 30 seconds
// If timeout exceeds then it will finish with status deadline exceeded
// What to do if root also has TTFD but it's not finished yet and we start navigating to another?
// How to track the time that 30 sec have passed?
if ((_hub.options as SentryFlutterOptions).enableTimeToFullDisplayTracing && name != 'root ("/")') {
ttfdStopwatch = Stopwatch()..start();
ttfdSpan = _transaction2?.startChild('ui.load.full_display', description: '$name full display');
}

if (arguments != null) {
_transaction2?.setData('route_settings_arguments', arguments);
Expand Down
13 changes: 12 additions & 1 deletion flutter/lib/src/sentry_flutter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,18 @@ mixin SentryFlutter {
}
}

static void reportFullDisplay() {}
/// Reports the time it took for the screen to be fully displayed.
static void reportFullDisplay() {
if (SentryNavigatorObserver.ttfdStopwatch?.elapsedMilliseconds != null) {
SentryNavigatorObserver.ttfdStopwatch?.stop();
SentryNavigatorObserver.ttfdSpan?.setMeasurement(
'time_to_full_display',
SentryNavigatorObserver.ttfdStopwatch!.elapsedMilliseconds,
unit: DurationSentryMeasurementUnit.milliSecond);
SentryNavigatorObserver.ttfdStopwatch?.reset();
}
SentryNavigatorObserver.ttfdSpan?.finish();
}

@internal
static SentryNative? get native => _native;
Expand Down
4 changes: 4 additions & 0 deletions flutter/lib/src/sentry_flutter_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,10 @@ class SentryFlutterOptions extends SentryOptions {
/// Read timeout. This will only be synced to the Android native SDK.
Duration readTimeout = Duration(seconds: 5);

/// Enable or disable the tracing of time to full display.
/// This feature requires using the [Routing Instrumentation](https://docs.sentry.io/platforms/flutter/integrations/routing-instrumentation/).
bool enableTimeToFullDisplayTracing = false;

/// By using this, you are disabling native [Breadcrumb] tracking and instead
/// you are just tracking [Breadcrumb]s which result from events available
/// in the current Flutter environment.
Expand Down

0 comments on commit f2668bb

Please sign in to comment.