From 88a2b38b241c46f71d0619d42de45285f5fb1eee Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Wed, 15 Jul 2026 13:09:32 +0200 Subject: [PATCH 1/3] Fix javadoc errors --- sentry/src/main/java/io/sentry/SentryOptions.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sentry/src/main/java/io/sentry/SentryOptions.java b/sentry/src/main/java/io/sentry/SentryOptions.java index 5340e20c6e..ac6769e2f2 100644 --- a/sentry/src/main/java/io/sentry/SentryOptions.java +++ b/sentry/src/main/java/io/sentry/SentryOptions.java @@ -649,7 +649,7 @@ public class SentryOptions { private boolean startProfilerOnAppStart = false; /** - * When false, the legacy {@code Debug}-based profiler is disabled on API < 35 devices. On API 35+ + * When false, the legacy {@code Debug}-based profiler is disabled on API < 35 devices. On API 35+ * devices, Android's {@code ProfilingManager} (Perfetto-based stack sampling) is always used * regardless of this setting. This option will be deprecated in the next major release and * removed in the one after. @@ -2247,7 +2247,7 @@ public void setStartProfilerOnAppStart(final boolean startProfilerOnAppStart) { } /** - * Whether the legacy {@code Debug}-based profiler is enabled on API < 35 devices. On API 35+, + * Whether the legacy {@code Debug}-based profiler is enabled on API < 35 devices. On API 35+, * Android's {@code ProfilingManager} (Perfetto) is always used regardless of this setting. This * option will be deprecated in the next major release and removed in the one after. * @@ -2258,12 +2258,12 @@ public boolean isEnableLegacyProfiling() { } /** - * Set whether the legacy {@code Debug}-based profiler is enabled on API < 35 devices. Set to + * Set whether the legacy {@code Debug}-based profiler is enabled on API < 35 devices. Set to * {@code false} to disable profiling on devices below API 35. On API 35+ devices, Android's * {@code ProfilingManager} (Perfetto) is always used and this setting has no effect. This option * will be deprecated in the next major release and removed in the one after. * - * @param enableLegacyProfiling false to disable legacy profiling on API < 35. + * @param enableLegacyProfiling false to disable legacy profiling on API < 35. */ public void setEnableLegacyProfiling(final boolean enableLegacyProfiling) { this.enableLegacyProfiling = enableLegacyProfiling; From 201d37314faac3f068a5a05fa54f4418b1df5172 Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Wed, 15 Jul 2026 13:20:21 +0200 Subject: [PATCH 2/3] fix(profiling): Disable transaction-based profiling when enableLegacyProfiling is false Transaction-based profiling (profilesSampleRate/profilesSampler) always relies on the legacy Debug-based profiler and is not supported by the ProfilingManager (Perfetto) backend. Previously enableLegacyProfiling only controlled continuous profiling, so profilesSampleRate + enableLegacyProfiling=false would still run the legacy transaction profiler. Now setting enableLegacyProfiling to false also disables transaction-based profiling on all devices, logging a warning to guide users towards profileSessionSampleRate for continuous profiling. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 2 + .../core/AndroidOptionsInitializer.java | 22 +++++++++ .../core/AndroidOptionsInitializerTest.kt | 45 +++++++++++++++++++ .../main/java/io/sentry/SentryOptions.java | 27 ++++++----- 4 files changed, 86 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index af29b22ccb..a6874d271e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,8 @@ - Session Replay: Fix error-to-replay linkage in `buffer` mode ([#5754](https://github.com/getsentry/sentry-java/pull/5754)) - Prevent logs and metrics from remaining queued after a flush scheduling race ([#5756](https://github.com/getsentry/sentry-java/pull/5756)) - Fix main thread identification for tombstone (native crash) events ([#5742](https://github.com/getsentry/sentry-java/pull/5742)) +- Setting `enableLegacyProfiling` to `false` now also disables transaction-based profiling (`profilesSampleRate`/`profilesSampler`) ([#5765](https://github.com/getsentry/sentry-java/pull/5765)) + - Transaction-based profiling always relies on the legacy profiler and is not supported by the ProfilingManager (Perfetto) backend. Use `profileSessionSampleRate` for continuous profiling instead. ### Dependencies diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java index 7817b5d6c6..5ce2746649 100644 --- a/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java +++ b/sentry-android-core/src/main/java/io/sentry/android/core/AndroidOptionsInitializer.java @@ -305,6 +305,28 @@ private static void setupProfiler( final @NotNull CompositePerformanceCollector performanceCollector) { if (options.isProfilingEnabled() || options.getProfilesSampleRate() != null) { options.setContinuousProfiler(NoOpContinuousProfiler.getInstance()); + // Transaction-based profiling always relies on the legacy Debug-based profiler, so it is + // disabled together with legacy profiling. Perfetto profiling only supports continuous + // profiling. + if (!options.isEnableLegacyProfiling()) { + options + .getLogger() + .log( + SentryLevel.WARNING, + "Transaction-based profiling (profilesSampleRate/profilesSampler) is disabled " + + "because enableLegacyProfiling is false. Transaction-based profiling always " + + "uses the legacy profiler and is not supported by Perfetto. No profiling " + + "data will be collected. Use profileSessionSampleRate for continuous " + + "profiling instead."); + options.setTransactionProfiler(NoOpTransactionProfiler.getInstance()); + if (appStartTransactionProfiler != null) { + appStartTransactionProfiler.close(); + } + if (appStartContinuousProfiler != null) { + appStartContinuousProfiler.close(true); + } + return; + } // This is a safeguard, but it should never happen, as the app start profiler should be the // continuous one. if (appStartContinuousProfiler != null) { diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidOptionsInitializerTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidOptionsInitializerTest.kt index 229d7ac2b6..855ee03267 100644 --- a/sentry-android-core/src/test/java/io/sentry/android/core/AndroidOptionsInitializerTest.kt +++ b/sentry-android-core/src/test/java/io/sentry/android/core/AndroidOptionsInitializerTest.kt @@ -424,6 +424,51 @@ class AndroidOptionsInitializerTest { assertEquals(fixture.sentryOptions.continuousProfiler, NoOpContinuousProfiler.getInstance()) } + @Test + fun `init with profilesSampleRate and enableLegacyProfiling false noops both profilers`() { + fixture.initSut( + configureOptions = { + profilesSampleRate = 1.0 + isEnableLegacyProfiling = false + } + ) + + assertEquals(NoOpTransactionProfiler.getInstance(), fixture.sentryOptions.transactionProfiler) + assertEquals(NoOpContinuousProfiler.getInstance(), fixture.sentryOptions.continuousProfiler) + } + + @Test + fun `init with profilesSampler and enableLegacyProfiling false noops both profilers`() { + fixture.initSut( + configureOptions = { + profilesSampler = mock() + isEnableLegacyProfiling = false + } + ) + + assertEquals(NoOpTransactionProfiler.getInstance(), fixture.sentryOptions.transactionProfiler) + assertEquals(NoOpContinuousProfiler.getInstance(), fixture.sentryOptions.continuousProfiler) + } + + @Test + fun `init with profilesSampleRate and enableLegacyProfiling false closes app start profiler`() { + val appStartProfiler = mock() + AppStartMetrics.getInstance().appStartProfiler = appStartProfiler + fixture.initSut( + configureOptions = { + profilesSampleRate = 1.0 + isEnableLegacyProfiling = false + } + ) + + assertEquals(NoOpTransactionProfiler.getInstance(), fixture.sentryOptions.transactionProfiler) + verify(appStartProfiler).close() + + // AppStartMetrics should be cleared + assertNull(AppStartMetrics.getInstance().appStartProfiler) + assertNull(AppStartMetrics.getInstance().appStartContinuousProfiler) + } + @Test fun `init reuses transaction profiler of appStartMetrics, if exists`() { val appStartProfiler = mock() diff --git a/sentry/src/main/java/io/sentry/SentryOptions.java b/sentry/src/main/java/io/sentry/SentryOptions.java index ac6769e2f2..db10830c05 100644 --- a/sentry/src/main/java/io/sentry/SentryOptions.java +++ b/sentry/src/main/java/io/sentry/SentryOptions.java @@ -649,8 +649,8 @@ public class SentryOptions { private boolean startProfilerOnAppStart = false; /** - * When false, the legacy {@code Debug}-based profiler is disabled on API < 35 devices. On API 35+ - * devices, Android's {@code ProfilingManager} (Perfetto-based stack sampling) is always used + * When false, the legacy {@code Debug}-based profiler is disabled on API < 35 devices. On API + * 35+ devices, Android's {@code ProfilingManager} (Perfetto-based stack sampling) is always used * regardless of this setting. This option will be deprecated in the next major release and * removed in the one after. */ @@ -2247,9 +2247,13 @@ public void setStartProfilerOnAppStart(final boolean startProfilerOnAppStart) { } /** - * Whether the legacy {@code Debug}-based profiler is enabled on API < 35 devices. On API 35+, - * Android's {@code ProfilingManager} (Perfetto) is always used regardless of this setting. This - * option will be deprecated in the next major release and removed in the one after. + * Whether the legacy {@code Debug}-based profiler is enabled. This controls continuous profiling + * on API < 35 devices (on API 35+, Android's {@code ProfilingManager} / Perfetto is always + * used for continuous profiling regardless of this setting) as well as transaction-based + * profiling ({@code profilesSampleRate}/{@code profilesSampler}) on all devices, since + * transaction-based profiling always relies on the legacy profiler and is not supported by + * Perfetto. This option will be deprecated in the next major release and removed in the one + * after. * * @return true if legacy profiling is enabled (default). */ @@ -2258,12 +2262,15 @@ public boolean isEnableLegacyProfiling() { } /** - * Set whether the legacy {@code Debug}-based profiler is enabled on API < 35 devices. Set to - * {@code false} to disable profiling on devices below API 35. On API 35+ devices, Android's - * {@code ProfilingManager} (Perfetto) is always used and this setting has no effect. This option - * will be deprecated in the next major release and removed in the one after. + * Set whether the legacy {@code Debug}-based profiler is enabled. Set to {@code false} to disable + * continuous profiling on devices below API 35 (on API 35+ devices, Android's {@code + * ProfilingManager} / Perfetto is always used for continuous profiling and this setting has no + * effect) as well as transaction-based profiling ({@code profilesSampleRate}/{@code + * profilesSampler}) on all devices, since transaction-based profiling always relies on the legacy + * profiler and is not supported by Perfetto. This option will be deprecated in the next major + * release and removed in the one after. * - * @param enableLegacyProfiling false to disable legacy profiling on API < 35. + * @param enableLegacyProfiling false to disable legacy profiling. */ public void setEnableLegacyProfiling(final boolean enableLegacyProfiling) { this.enableLegacyProfiling = enableLegacyProfiling; From 28f563754323cd497aae0067a8cc5490aa651b9c Mon Sep 17 00:00:00 2001 From: Markus Hintersteiner Date: Thu, 16 Jul 2026 13:40:34 +0200 Subject: [PATCH 3/3] Remove changelog entry --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6874d271e..af29b22ccb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,8 +34,6 @@ - Session Replay: Fix error-to-replay linkage in `buffer` mode ([#5754](https://github.com/getsentry/sentry-java/pull/5754)) - Prevent logs and metrics from remaining queued after a flush scheduling race ([#5756](https://github.com/getsentry/sentry-java/pull/5756)) - Fix main thread identification for tombstone (native crash) events ([#5742](https://github.com/getsentry/sentry-java/pull/5742)) -- Setting `enableLegacyProfiling` to `false` now also disables transaction-based profiling (`profilesSampleRate`/`profilesSampler`) ([#5765](https://github.com/getsentry/sentry-java/pull/5765)) - - Transaction-based profiling always relies on the legacy profiler and is not supported by the ProfilingManager (Perfetto) backend. Use `profileSessionSampleRate` for continuous profiling instead. ### Dependencies