diff --git a/CHANGELOG.md b/CHANGELOG.md index 7687fdc7f5b..9fc094baf82 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Fixes + +- Filter out app starts with more than 60s ([#2127](https://github.com/getsentry/sentry-java/pull/2127)) + ## 6.1.3 ### Fixes diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AppStartState.java b/sentry-android-core/src/main/java/io/sentry/android/core/AppStartState.java index 54f563146f2..7ad96f9ea08 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AppStartState.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AppStartState.java @@ -13,6 +13,9 @@ public final class AppStartState { private static @NotNull AppStartState instance = new AppStartState(); + /** We filter out App starts more than 60s */ + private static final int MAX_APP_START_MILLIS = 60000; + private @Nullable Long appStartMillis; private @Nullable Long appStartEndMillis; @@ -48,7 +51,21 @@ public synchronized Long getAppStartInterval() { if (appStartMillis == null || appStartEndMillis == null || coldStart == null) { return null; } - return appStartEndMillis - appStartMillis; + final long appStart = appStartEndMillis - appStartMillis; + + // We filter out app start more than 60s. + // This could be due to many different reasons. + // If you do the manual init and init the SDK too late and it does not compute the app start end + // in the very first Activity. + // If the process starts but the App isn't in the foreground. + // If the system forked the zygote earlier to accelerate the app start. + // And some unknown reasons that could not be reproduced. + // We've seen app starts with hours, days and even months. + if (appStart >= MAX_APP_START_MILLIS) { + return null; + } + + return appStart; } public @Nullable Boolean isColdStart() { diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SentryPerformanceProvider.java b/sentry-android-core/src/main/java/io/sentry/android/core/SentryPerformanceProvider.java index 929706f7848..850464d20a5 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SentryPerformanceProvider.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SentryPerformanceProvider.java @@ -20,7 +20,8 @@ /** * SentryPerformanceProvider is responsible for collecting data (eg appStart) as early as possible * as ContentProvider is the only reliable hook for libraries that works across all the supported - * SDK versions. When minSDK is >= 24, we could use Process.getStartUptimeMillis() + * SDK versions. When minSDK is >= 24, we could use Process.getStartUptimeMillis() We could also use + * AppComponentFactory but it depends on androidx.core.app.AppComponentFactory */ @ApiStatus.Internal public final class SentryPerformanceProvider extends ContentProvider diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AppStartStateTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AppStartStateTest.kt index 2ec7dde1627..4500c38117c 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AppStartStateTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AppStartStateTest.kt @@ -77,4 +77,16 @@ class AppStartStateTest { assertEquals(400, sut.appStartInterval) } + + @Test + fun `getAppStartInterval returns null if more than 60s`() { + val sut = AppStartState.getInstance() + + val date = Date() + sut.setAppStartTime(100, date) + sut.setAppStartEnd(60100) + sut.setColdStart(true) + + assertNull(sut.appStartInterval) + } }