From daf954efdb82c51c3f7861327dde12f4df0acabf Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 6 Aug 2026 11:43:32 +0200 Subject: [PATCH 1/5] feat(android): Add trace markers to SentryAndroid.init (JAVA-685) Wrap SentryAndroid.init and the user OptionsConfiguration callback in android.os.Trace sections so SDK startup cost shows up as named slices in a Perfetto trace or a CI TraceSectionMetric. Sections use constant names and allocate nothing when no trace is recording. Kept intentionally minimal as the SDK's first shipped Trace instrumentation. Co-Authored-By: Claude Opus 4.8 --- .../main/java/io/sentry/android/core/SentryAndroid.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java b/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java index f27259fd635..8cea38b62bd 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java @@ -5,6 +5,7 @@ import android.content.Context; import android.os.Process; import android.os.SystemClock; +import android.os.Trace; import io.sentry.ILogger; import io.sentry.IScopes; import io.sentry.ISentryLifecycleToken; @@ -96,6 +97,7 @@ public static void init( @NotNull ILogger logger, @NotNull Sentry.OptionsConfiguration configuration) { try (final @NotNull ISentryLifecycleToken ignored = staticLock.acquire()) { + Trace.beginSection("SentryAndroid.init"); Sentry.init( new SentryAndroidOptionsContainer(), options -> { @@ -138,6 +140,7 @@ public static void init( isReplayAvailable, isDistributionAvailable); + Trace.beginSection("SentryAndroid.init.configure"); try { configuration.configure(options); } catch (Throwable t) { @@ -148,6 +151,8 @@ public static void init( SentryLevel.ERROR, "Error in the 'OptionsConfiguration.configure' callback.", t); + } finally { + Trace.endSection(); } // if SentryPerformanceProvider was disabled or removed, @@ -219,6 +224,8 @@ public static void init( logger.log(SentryLevel.FATAL, "Fatal error during SentryAndroid.init(...)", e); throw new RuntimeException("Failed to initialize Sentry's SDK", e); + } finally { + Trace.endSection(); } } From c99379d1434416f207d887bda788a510ba0401b0 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 6 Aug 2026 11:44:40 +0200 Subject: [PATCH 2/5] changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a200976b614..56b5cd89f49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Features + +- Add systrace sections to `SentryAndroid.init` for startup profiling ([#5901](https://github.com/getsentry/sentry-java/pull/5901)) + ## 8.52.0 ### Fixes From 3c039560709d774c4ac9931c24f6020ab9901505 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 6 Aug 2026 12:34:07 +0200 Subject: [PATCH 3/5] feat(android): Keep only the SentryAndroid.init trace section (JAVA-685) Drop the SentryAndroid.init.configure section to keep the SDK's first shipped android.os.Trace instrumentation minimal and easy to review. Co-Authored-By: Claude Opus 4.8 --- CHANGELOG.md | 2 +- .../src/main/java/io/sentry/android/core/SentryAndroid.java | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56b5cd89f49..d98dc1458b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ ### Features -- Add systrace sections to `SentryAndroid.init` for startup profiling ([#5901](https://github.com/getsentry/sentry-java/pull/5901)) +- Add a systrace section to `SentryAndroid.init` for startup profiling ([#5901](https://github.com/getsentry/sentry-java/pull/5901)) ## 8.52.0 diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java b/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java index 8cea38b62bd..47b96346798 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java @@ -140,7 +140,6 @@ public static void init( isReplayAvailable, isDistributionAvailable); - Trace.beginSection("SentryAndroid.init.configure"); try { configuration.configure(options); } catch (Throwable t) { @@ -151,8 +150,6 @@ public static void init( SentryLevel.ERROR, "Error in the 'OptionsConfiguration.configure' callback.", t); - } finally { - Trace.endSection(); } // if SentryPerformanceProvider was disabled or removed, From ef5eeeab152faa5ce5a635930c61332b8d9121eb Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 6 Aug 2026 12:44:51 +0200 Subject: [PATCH 4/5] Remove changelog entry in favor of #skip-changelog --- CHANGELOG.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d98dc1458b4..a200976b614 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,5 @@ # Changelog -## Unreleased - -### Features - -- Add a systrace section to `SentryAndroid.init` for startup profiling ([#5901](https://github.com/getsentry/sentry-java/pull/5901)) - ## 8.52.0 ### Fixes From de19349beeb5cd9806355398df77aea5670f4a75 Mon Sep 17 00:00:00 2001 From: Nelson Osacky Date: Thu, 6 Aug 2026 15:57:24 +0200 Subject: [PATCH 5/5] fix(android): Balance init trace section on lock failure (JAVA-685) Move Trace.beginSection above the try-with-resources so it always pairs with the endSection() in the finally. If staticLock.acquire() threw (e.g. OOM allocating the lock), the body was skipped but the finally still ran, popping an unrelated systrace section. Co-Authored-By: Claude Opus 4.8 --- .../src/main/java/io/sentry/android/core/SentryAndroid.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java b/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java index 47b96346798..ab18a5827b9 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/SentryAndroid.java @@ -96,8 +96,10 @@ public static void init( @NotNull final Context context, @NotNull ILogger logger, @NotNull Sentry.OptionsConfiguration configuration) { + // Started before acquiring the lock so it stays balanced with the endSection() in the finally + // even if acquire() throws. + Trace.beginSection("SentryAndroid.init"); try (final @NotNull ISentryLifecycleToken ignored = staticLock.acquire()) { - Trace.beginSection("SentryAndroid.init"); Sentry.init( new SentryAndroidOptionsContainer(), options -> {