Skip to content

Commit 91474b9

Browse files
stefanosianoromtsn
andauthored
Create onCreate and onStart spans for all Activities (#4025)
* ActivityLifecycleIntegration creates activity spans for all Activities, not only for appStart ones * updated changelog * Fix test * Changelog --------- Co-authored-by: Roman Zavarnitsyn <[email protected]>
1 parent 5202700 commit 91474b9

File tree

4 files changed

+54
-12
lines changed

4 files changed

+54
-12
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
- The Kotlin Language version is now set to 1.6 ([#3936](https://github.com/getsentry/sentry-java/pull/3936))
88

9+
### Features
10+
11+
- Create onCreate and onStart spans for all Activities ([#4025](https://github.com/getsentry/sentry-java/pull/4025))
12+
913
### Fixes
1014

1115
- Do not log if `OtelContextScopesStorage` cannot be found ([#4127](https://github.com/getsentry/sentry-java/pull/4127))

sentry-android-core/src/main/java/io/sentry/android/core/ActivityLifecycleIntegration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,8 @@ public void onActivityPostCreated(
430430
final @NotNull Activity activity, final @Nullable Bundle savedInstanceState) {
431431
final ActivityLifecycleSpanHelper helper = activitySpanHelpers.get(activity);
432432
if (helper != null) {
433-
helper.createAndStopOnCreateSpan(appStartSpan);
433+
helper.createAndStopOnCreateSpan(
434+
appStartSpan != null ? appStartSpan : activitiesWithOngoingTransactions.get(activity));
434435
}
435436
}
436437

@@ -468,7 +469,8 @@ public void onActivityStarted(final @NotNull Activity activity) {
468469
public void onActivityPostStarted(final @NotNull Activity activity) {
469470
final ActivityLifecycleSpanHelper helper = activitySpanHelpers.get(activity);
470471
if (helper != null) {
471-
helper.createAndStopOnStartSpan(appStartSpan);
472+
helper.createAndStopOnStartSpan(
473+
appStartSpan != null ? appStartSpan : activitiesWithOngoingTransactions.get(activity));
472474
// Needed to handle hybrid SDKs
473475
helper.saveSpanToAppStartMetrics();
474476
}

sentry-android-core/src/main/java/io/sentry/android/core/performance/ActivityLifecycleSpanHelper.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,18 @@ public void setOnStartStartTimestamp(final @NotNull SentryDate onStartStartTimes
3636
this.onStartStartTimestamp = onStartStartTimestamp;
3737
}
3838

39-
public void createAndStopOnCreateSpan(final @Nullable ISpan appStartSpan) {
40-
if (onCreateStartTimestamp != null && appStartSpan != null) {
39+
public void createAndStopOnCreateSpan(final @Nullable ISpan parentSpan) {
40+
if (onCreateStartTimestamp != null && parentSpan != null) {
4141
onCreateSpan =
42-
createLifecycleSpan(appStartSpan, activityName + ".onCreate", onCreateStartTimestamp);
42+
createLifecycleSpan(parentSpan, activityName + ".onCreate", onCreateStartTimestamp);
4343
onCreateSpan.finish();
4444
}
4545
}
4646

47-
public void createAndStopOnStartSpan(final @Nullable ISpan appStartSpan) {
48-
if (onStartStartTimestamp != null && appStartSpan != null) {
47+
public void createAndStopOnStartSpan(final @Nullable ISpan parentSpan) {
48+
if (onStartStartTimestamp != null && parentSpan != null) {
4949
onStartSpan =
50-
createLifecycleSpan(appStartSpan, activityName + ".onStart", onStartStartTimestamp);
50+
createLifecycleSpan(parentSpan, activityName + ".onStart", onStartStartTimestamp);
5151
onStartSpan.finish();
5252
}
5353
}
@@ -106,19 +106,18 @@ public void saveSpanToAppStartMetrics() {
106106
}
107107

108108
private @NotNull ISpan createLifecycleSpan(
109-
final @NotNull ISpan appStartSpan,
109+
final @NotNull ISpan parentSpan,
110110
final @NotNull String description,
111111
final @NotNull SentryDate startTimestamp) {
112112
final @NotNull ISpan span =
113-
appStartSpan.startChild(
113+
parentSpan.startChild(
114114
APP_METRICS_ACTIVITIES_OP, description, startTimestamp, Instrumenter.SENTRY);
115115
setDefaultStartSpanData(span);
116116
return span;
117117
}
118118

119119
public void clear() {
120-
// in case the appStartSpan isn't completed yet, we finish it as cancelled to avoid
121-
// memory leak
120+
// in case the parentSpan isn't completed yet, we finish it as cancelled to avoid memory leak
122121
if (onCreateSpan != null && !onCreateSpan.isFinished()) {
123122
onCreateSpan.finish(SpanStatus.CANCELLED);
124123
}

sentry-android-core/src/test/java/io/sentry/android/core/ActivityLifecycleIntegrationTest.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,43 @@ class ActivityLifecycleIntegrationTest {
15611561
assertFalse(appStartMetrics.activityLifecycleTimeSpans.isEmpty())
15621562
}
15631563

1564+
@Test
1565+
fun `Creates activity lifecycle spans even when no app start span is available`() {
1566+
val sut = fixture.getSut()
1567+
fixture.options.tracesSampleRate = 1.0
1568+
val startDate = SentryNanotimeDate(Date(2), 0)
1569+
val appStartMetrics = AppStartMetrics.getInstance()
1570+
val activity = mock<Activity>()
1571+
fixture.options.dateProvider = SentryDateProvider { startDate }
1572+
// Don't set app start time, so there's no app start span
1573+
// setAppStartTime(appStartDate)
1574+
1575+
sut.register(fixture.scopes, fixture.options)
1576+
assertTrue(sut.activitySpanHelpers.isEmpty())
1577+
1578+
sut.onActivityPreCreated(activity, null)
1579+
1580+
assertFalse(sut.activitySpanHelpers.isEmpty())
1581+
val helper = sut.activitySpanHelpers.values.first()
1582+
assertNotNull(helper.onCreateStartTimestamp)
1583+
1584+
sut.onActivityCreated(activity, null)
1585+
assertNull(sut.appStartSpan)
1586+
1587+
sut.onActivityPostCreated(activity, null)
1588+
assertTrue(helper.onCreateSpan!!.isFinished)
1589+
1590+
sut.onActivityPreStarted(activity)
1591+
assertNotNull(helper.onStartStartTimestamp)
1592+
1593+
sut.onActivityStarted(activity)
1594+
assertTrue(appStartMetrics.activityLifecycleTimeSpans.isEmpty())
1595+
1596+
sut.onActivityPostStarted(activity)
1597+
assertTrue(helper.onStartSpan!!.isFinished)
1598+
assertFalse(appStartMetrics.activityLifecycleTimeSpans.isEmpty())
1599+
}
1600+
15641601
@Test
15651602
fun `Save activity lifecycle spans in AppStartMetrics onPostSarted`() {
15661603
val sut = fixture.getSut()

0 commit comments

Comments
 (0)