Skip to content

Commit 401c5ea

Browse files
committed
ActivityLifecycleIntegration creates activity spans for all Activities, not only for appStart ones
1 parent eb7afff commit 401c5ea

File tree

3 files changed

+50
-12
lines changed

3 files changed

+50
-12
lines changed

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
@@ -417,7 +417,8 @@ public void onActivityPostCreated(
417417
final @NotNull Activity activity, final @Nullable Bundle savedInstanceState) {
418418
final ActivityLifecycleSpanHelper helper = activitySpanHelpers.get(activity);
419419
if (helper != null) {
420-
helper.createAndStopOnCreateSpan(appStartSpan);
420+
helper.createAndStopOnCreateSpan(
421+
appStartSpan != null ? appStartSpan : activitiesWithOngoingTransactions.get(activity));
421422
}
422423
}
423424

@@ -453,7 +454,8 @@ public synchronized void onActivityStarted(final @NotNull Activity activity) {
453454
public void onActivityPostStarted(final @NotNull Activity activity) {
454455
final ActivityLifecycleSpanHelper helper = activitySpanHelpers.get(activity);
455456
if (helper != null) {
456-
helper.createAndStopOnStartSpan(appStartSpan);
457+
helper.createAndStopOnStartSpan(
458+
appStartSpan != null ? appStartSpan : activitiesWithOngoingTransactions.get(activity));
457459
// Needed to handle hybrid SDKs
458460
helper.saveSpanToAppStartMetrics();
459461
}

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
@@ -1484,6 +1484,43 @@ class ActivityLifecycleIntegrationTest {
14841484
assertFalse(appStartMetrics.activityLifecycleTimeSpans.isEmpty())
14851485
}
14861486

1487+
@Test
1488+
fun `Creates activity lifecycle spans even when no app start span is available`() {
1489+
val sut = fixture.getSut()
1490+
fixture.options.tracesSampleRate = 1.0
1491+
val startDate = SentryNanotimeDate(Date(2), 0)
1492+
val appStartMetrics = AppStartMetrics.getInstance()
1493+
val activity = mock<Activity>()
1494+
fixture.options.dateProvider = SentryDateProvider { startDate }
1495+
// Don't set app start time, so there's no app start span
1496+
// setAppStartTime(appStartDate)
1497+
1498+
sut.register(fixture.hub, fixture.options)
1499+
assertTrue(sut.activitySpanHelpers.isEmpty())
1500+
1501+
sut.onActivityPreCreated(activity, null)
1502+
1503+
assertFalse(sut.activitySpanHelpers.isEmpty())
1504+
val helper = sut.activitySpanHelpers.values.first()
1505+
assertNotNull(helper.onCreateStartTimestamp)
1506+
1507+
sut.onActivityCreated(activity, null)
1508+
assertNull(sut.appStartSpan)
1509+
1510+
sut.onActivityPostCreated(activity, null)
1511+
assertTrue(helper.onCreateSpan!!.isFinished)
1512+
1513+
sut.onActivityPreStarted(activity)
1514+
assertNotNull(helper.onStartStartTimestamp)
1515+
1516+
sut.onActivityStarted(activity)
1517+
assertTrue(appStartMetrics.activityLifecycleTimeSpans.isEmpty())
1518+
1519+
sut.onActivityPostStarted(activity)
1520+
assertTrue(helper.onStartSpan!!.isFinished)
1521+
assertFalse(appStartMetrics.activityLifecycleTimeSpans.isEmpty())
1522+
}
1523+
14871524
@Test
14881525
fun `Save activity lifecycle spans in AppStartMetrics onPostSarted`() {
14891526
val sut = fixture.getSut()

0 commit comments

Comments
 (0)