Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
5ad308b
commit
buenaflor Apr 18, 2024
7bc756b
Merge branch 'main' into feat/app-start-improve
buenaflor Apr 23, 2024
3e0790a
Update
buenaflor Apr 23, 2024
d0eb540
Remove print
buenaflor Apr 23, 2024
05c208c
Remove comments
buenaflor Apr 23, 2024
c796b71
Update
buenaflor Apr 24, 2024
da8297e
Merge branch 'main' into feat/app-start-improve
buenaflor Apr 24, 2024
bdc8588
Add linting
buenaflor Apr 24, 2024
d1b37cd
Update CHANGELOG
buenaflor Apr 24, 2024
6f44478
Update CHANGELOG.md
buenaflor Apr 24, 2024
8051972
Update naming
buenaflor Apr 24, 2024
29671ff
Merge branch 'main' into feat/app-start-improve
buenaflor Apr 24, 2024
b401ed0
Update naming
buenaflor Apr 24, 2024
c06973c
Update naming
buenaflor Apr 24, 2024
2bb3887
Update description from first frame render to initial frame render
buenaflor Apr 24, 2024
3aadc19
Initial
buenaflor Apr 25, 2024
86bc3bf
Merge branch 'feat/app-start-improve' into feat/app-start-native-spans
buenaflor Apr 25, 2024
801483e
update
buenaflor Apr 26, 2024
d28af71
dart format
buenaflor Apr 26, 2024
21c61a6
Update comments
buenaflor Apr 26, 2024
88a8819
Update
buenaflor Apr 26, 2024
0d73052
Update
buenaflor Apr 26, 2024
1e05ae5
Update
buenaflor Apr 26, 2024
73d830a
Update
buenaflor Apr 26, 2024
62cb2be
Update
buenaflor Apr 26, 2024
111125c
Fix tests
buenaflor Apr 29, 2024
04ad023
Fix test
buenaflor Apr 29, 2024
e9e95c4
Add unused import
buenaflor Apr 29, 2024
bb785b6
Merge branch 'feat/app-start-improve' into feat/app-start-native-spans
buenaflor Apr 29, 2024
d0ce3a4
Fix tests
buenaflor Apr 29, 2024
b22a9c0
Update
buenaflor May 2, 2024
d4c6b1a
Updaet
buenaflor May 2, 2024
06325a2
Update
buenaflor May 3, 2024
bc7ba9e
Update
buenaflor May 3, 2024
4367089
Merge branch 'main' into feat/app-start-native-spans
buenaflor May 6, 2024
a847325
Update CHANGELOG
buenaflor May 6, 2024
7703c4e
Update CHANGELOG
buenaflor May 6, 2024
4ae3212
Update formatting of kotlin file
buenaflor May 6, 2024
342b518
Update
buenaflor May 6, 2024
7a1084f
Update test
buenaflor May 6, 2024
16303bd
format
buenaflor May 6, 2024
20e595f
Update SentryFlutterPlugin.kt
buenaflor May 6, 2024
0cf5d12
Update SentryFlutterPlugin.kt
buenaflor May 6, 2024
2820fc8
Update
buenaflor May 6, 2024
c122240
Update main.dart
buenaflor May 6, 2024
939ed17
Merge branch 'main' into feat/app-start-native-spans
buenaflor May 8, 2024
cdad9a8
Update
buenaflor May 8, 2024
ffb3695
Update
buenaflor May 8, 2024
e3197a7
Update
buenaflor May 8, 2024
427d516
Updaet
buenaflor May 8, 2024
ab63c3b
Format
buenaflor May 8, 2024
93b4516
Update flutter/lib/src/sentry_flutter.dart
buenaflor May 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Initial
  • Loading branch information
buenaflor committed Apr 25, 2024
commit 3aadc19db053af1c30297acae2df50eae8029de2
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,25 @@ class SentryFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
return
}

val appStartTime = AppStartMetrics.getInstance().appStartTimeSpan.startTimestamp
val appStartMetrics = AppStartMetrics.getInstance()

val applicationOnCreateStartTime = appStartMetrics.applicationOnCreateTimeSpan.startTimestamp
println("ok?: ${appStartMetrics.appStartTimeSpan.startUptimeMs}")

val classInitUptimeMs = appStartMetrics.classLoadedUptimeMs
val appStartUptimeMs = appStartMetrics.appStartTimeSpan.startUptimeMs
val appStartTime = appStartMetrics.appStartTimeSpan.startTimestamp
val contentProviderOnCreates = appStartMetrics.contentProviderOnCreateTimeSpans
println(contentProviderOnCreates.isEmpty())
println("haha");
contentProviderOnCreates.forEach {
println("contentProviderOnCreates: ${it.startTimestamp}")
println("contentProviderOnCreates: ${it.projectedStopTimestamp}")
println("")
}
val appl = appStartMetrics.applicationOnCreateTimeSpan
// AppStartMetrics.onApplicationPostCreate()
print("appl: ${appl.startTimestamp} ${appl.startTimestampMs} ${appl.hasStopped()}")
val isColdStart =
AppStartMetrics.getInstance().appStartType == AppStartMetrics.AppStartType.COLD

Expand All @@ -136,10 +154,23 @@ class SentryFlutterPlugin : FlutterPlugin, MethodCallHandler, ActivityAware {
result.success(null)
} else {
val appStartTimeMillis = DateUtils.nanosToMillis(appStartTime.nanoTimestamp().toDouble())
val item = mapOf<String, Any?>(
val item = mutableMapOf<String, Any?>(
"appStartTime" to appStartTimeMillis,
"isColdStart" to isColdStart,
)
println("ok?: ${classInitUptimeMs - appStartMetrics.appStartTimeSpan.startUptimeMs}");
// if (applicationOnCreateStartTime != null) {
// println("is not null");
// val applicationOnCreateTimeMillis =
// DateUtils.nanosToMillis(applicationOnCreateStartTime.nanoTimestamp().toDouble())
// item["applicationOnCreateTime"] = mapOf("test" to "test")
// }
item["nativeSpanTimes"] = mapOf<String, Any?>(
"classInitUptimeMs" to classInitUptimeMs,
"appStartUptimeMs" to appStartUptimeMs,
)


result.success(item)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1430"
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand Down
2 changes: 1 addition & 1 deletion flutter/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ Future<void> setupSentry(
// configuration issues, e.g. finding out why your events are not uploaded.
options.debug = true;
options.spotlight = Spotlight(enabled: true);
options.enableTimeToFullDisplayTracing = true;
// options.enableTimeToFullDisplayTracing = true;
options.enableMetrics = true;

options.maxRequestBodySize = MaxRequestBodySize.always;
Expand Down
15 changes: 14 additions & 1 deletion flutter/ios/Classes/SentryFlutterPluginApple.swift
Original file line number Diff line number Diff line change
Expand Up @@ -382,13 +382,26 @@ public class SentryFlutterPluginApple: NSObject, FlutterPlugin {
result(nil)
return
}

let runtimeInitTimestamp = appStartMeasurement.runtimeInitTimestamp.timeIntervalSince1970 * 1000
let moduleInitTimestamp = appStartMeasurement.moduleInitializationTimestamp.timeIntervalSince1970 * 1000
let sdkStartTimestamp = appStartMeasurement.sdkStartTimestamp.timeIntervalSince1970 * 1000
let didFinishLaunchingTimestamp = appStartMeasurement.didFinishLaunchingTimestamp.timeIntervalSince1970 * 1000

let nativeSpanTimes: [String: Any] = [
"runtimeInitTimestamp": runtimeInitTimestamp,
"moduleInitTimestamp": moduleInitTimestamp,
"sdkStartTimestamp": sdkStartTimestamp,
"didFinishLaunchingTimestamp": didFinishLaunchingTimestamp
]

let appStartTime = appStartMeasurement.appStartTimestamp.timeIntervalSince1970 * 1000
let isColdStart = appStartMeasurement.type == .cold

let item: [String: Any] = [
"appStartTime": appStartTime,
"isColdStart": isColdStart
"isColdStart": isColdStart,
"nativeSpanTimes": nativeSpanTimes
]

result(item)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@ import 'package:sentry/sentry.dart';
import '../integrations/integrations.dart';
import '../native/sentry_native.dart';

// ignore: implementation_imports
import 'package:sentry/src/sentry_tracer.dart';

/// EventProcessor that enriches [SentryTransaction] objects with app start
/// measurement.
class NativeAppStartEventProcessor implements EventProcessor {
final SentryNative _native;
final Hub _hub;

NativeAppStartEventProcessor(this._native);
NativeAppStartEventProcessor(
this._native, {
Hub? hub,
}) : _hub = hub ?? HubAdapter();

@override
Future<SentryEvent?> apply(SentryEvent event, Hint hint) async {
Expand All @@ -25,6 +32,117 @@ class NativeAppStartEventProcessor implements EventProcessor {
event.measurements[measurement.name] = measurement;
_native.didAddAppStartMeasurement = true;
}

final transaction = event.tracer;

if (appStartInfo == null) {
return event;
}

final classInitUptimeMs =
appStartInfo.nativeSpanTimes['classInitUptimeMs'] as int?;
final appStartUptimeMs =
appStartInfo.nativeSpanTimes['appStartUptimeMs'] as int?;
final runTimeInitTimestamp =
appStartInfo.nativeSpanTimes['runtimeInitTimestamp'] as double?;
final moduleInitTimestamp =
appStartInfo.nativeSpanTimes['moduleInitTimestamp'] as double?;
final sdkStartTimestamp = appStartInfo.nativeSpanTimes['sdkStartTimestamp'] as double?;
final didFinishLaunchingTimestamp = appStartInfo.nativeSpanTimes['didFinishLaunchingTimestamp'] as double?;

if (runTimeInitTimestamp != null && moduleInitTimestamp != null && sdkStartTimestamp != null && didFinishLaunchingTimestamp != null) {
final aa = DateTime.fromMillisecondsSinceEpoch(runTimeInitTimestamp.toInt());
final bb = DateTime.fromMillisecondsSinceEpoch(moduleInitTimestamp.toInt());
final sdkStart = DateTime.fromMillisecondsSinceEpoch(sdkStartTimestamp.toInt());
// final didFinishLaunching = DateTime.fromMillisecondsSinceEpoch(didFinishLaunchingTimestamp.toInt());

final preRuntimeInitSpan = await _createAndFinishSpan(
tracer: transaction,
operation: 'ui.load',
description: 'Pre runtime init',
parentSpanId: transaction.context.spanId,
traceId: transaction.context.traceId,
startTimestamp: appStartInfo.start,
endTimestamp: aa);

final runtimeInitSpan = await _createAndFinishSpan(
tracer: transaction,
operation: 'ui.load',
description: 'Runtime init',
parentSpanId: transaction.context.spanId,
traceId: transaction.context.traceId,
startTimestamp: aa,
endTimestamp: bb);

final appInitSpan = await _createAndFinishSpan(
tracer: transaction,
operation: 'ui.load',
description: 'UIKit init',
parentSpanId: transaction.context.spanId,
traceId: transaction.context.traceId,
startTimestamp: bb,
endTimestamp: sdkStart);

final didFinishLaunchingSpan = await _createAndFinishSpan(
tracer: transaction,
operation: 'ui.load',
description: 'Application init',
parentSpanId: transaction.context.spanId,
traceId: transaction.context.traceId,
startTimestamp: sdkStart,
endTimestamp: appStartInfo.end);

transaction.children.addAll([
preRuntimeInitSpan,
runtimeInitSpan,
appInitSpan,
didFinishLaunchingSpan,
]);
}

print('classInitUptimeMs: $classInitUptimeMs');

if (classInitUptimeMs != null && appStartUptimeMs != null) {
final duration = classInitUptimeMs - appStartUptimeMs;

final classInitSpan = await _createAndFinishSpan(
tracer: transaction,
operation: 'ui.load',
description: 'Class init',
parentSpanId: transaction.context.spanId,
traceId: transaction.context.traceId,
startTimestamp: appStartInfo.start,
endTimestamp:
appStartInfo.start.add(Duration(milliseconds: duration)));

transaction.children.addAll([
classInitSpan,
]);
}

return event;
}

Future<SentrySpan> _createAndFinishSpan({
required SentryTracer tracer,
required String operation,
required String description,
required SpanId? parentSpanId,
required SentryId? traceId,
required DateTime startTimestamp,
required DateTime endTimestamp,
}) async {
final span = SentrySpan(
tracer,
SentrySpanContext(
operation: operation,
description: description,
parentSpanId: parentSpanId,
traceId: traceId,
),
_hub,
startTimestamp: startTimestamp);
await span.finish(endTimestamp: endTimestamp);
return span;
}
}
11 changes: 8 additions & 3 deletions flutter/lib/src/integrations/native_app_start_integration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ class NativeAppStartIntegration extends Integration<SentryFlutterOptions> {
if (isIntegrationTest) {
final appStartInfo = AppStartInfo(AppStartType.cold,
start: DateTime.now(),
end: DateTime.now().add(const Duration(milliseconds: 100)));
end: DateTime.now().add(const Duration(milliseconds: 100)),
nativeSpanTimes: {});
setAppStartInfo(appStartInfo);
return;
}
Expand Down Expand Up @@ -95,7 +96,8 @@ class NativeAppStartIntegration extends Integration<SentryFlutterOptions> {
nativeAppStart.isColdStart ? AppStartType.cold : AppStartType.warm,
start: DateTime.fromMillisecondsSinceEpoch(
nativeAppStart.appStartTime.toInt()),
end: appStartEnd);
end: appStartEnd,
nativeSpanTimes: nativeAppStart.nativeSpanTimes);
setAppStartInfo(appStartInfo);
});
}
Expand All @@ -109,11 +111,14 @@ class NativeAppStartIntegration extends Integration<SentryFlutterOptions> {
enum AppStartType { cold, warm }

class AppStartInfo {
AppStartInfo(this.type, {required this.start, required this.end});
AppStartInfo(this.type,
{required this.start, required this.end, required this.nativeSpanTimes});

final AppStartType type;
final DateTime start;
final DateTime end;
final Map<dynamic, dynamic> nativeSpanTimes;

Duration get duration => end.difference(start);

SentryMeasurement toMeasurement() {
Expand Down
4 changes: 3 additions & 1 deletion flutter/lib/src/native/sentry_native.dart
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,17 @@ class SentryNative {
}

class NativeAppStart {
NativeAppStart(this.appStartTime, this.isColdStart);
NativeAppStart(this.appStartTime, this.isColdStart, this.nativeSpanTimes);

double appStartTime;
bool isColdStart;
Map<dynamic, dynamic> nativeSpanTimes;

factory NativeAppStart.fromJson(Map<String, dynamic> json) {
return NativeAppStart(
json['appStartTime'] as double,
json['isColdStart'] as bool,
json['nativeSpanTimes'] as Map<dynamic, dynamic>,
);
}
}
Expand Down