Skip to content

Commit af1a5cb

Browse files
markushiclaude
andcommitted
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) <noreply@anthropic.com>
1 parent 88a2b38 commit af1a5cb

4 files changed

Lines changed: 86 additions & 10 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
- Session Replay: Fix error-to-replay linkage in `buffer` mode ([#5754](https://github.com/getsentry/sentry-java/pull/5754))
3535
- Prevent logs and metrics from remaining queued after a flush scheduling race ([#5756](https://github.com/getsentry/sentry-java/pull/5756))
3636
- Fix main thread identification for tombstone (native crash) events ([#5742](https://github.com/getsentry/sentry-java/pull/5742))
37+
- Setting `enableLegacyProfiling` to `false` now also disables transaction-based profiling (`profilesSampleRate`/`profilesSampler`) ([#5763](https://github.com/getsentry/sentry-java/pull/5763))
38+
- Transaction-based profiling always relies on the legacy profiler and is not supported by the ProfilingManager (Perfetto) backend. Use `profileSessionSampleRate` for continuous profiling instead.
3739

3840
### Dependencies
3941

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,28 @@ private static void setupProfiler(
305305
final @NotNull CompositePerformanceCollector performanceCollector) {
306306
if (options.isProfilingEnabled() || options.getProfilesSampleRate() != null) {
307307
options.setContinuousProfiler(NoOpContinuousProfiler.getInstance());
308+
// Transaction-based profiling always relies on the legacy Debug-based profiler, so it is
309+
// disabled together with legacy profiling. Perfetto profiling only supports continuous
310+
// profiling.
311+
if (!options.isEnableLegacyProfiling()) {
312+
options
313+
.getLogger()
314+
.log(
315+
SentryLevel.WARNING,
316+
"Transaction-based profiling (profilesSampleRate/profilesSampler) is disabled "
317+
+ "because enableLegacyProfiling is false. Transaction-based profiling always "
318+
+ "uses the legacy profiler and is not supported by Perfetto. No profiling "
319+
+ "data will be collected. Use profileSessionSampleRate for continuous "
320+
+ "profiling instead.");
321+
options.setTransactionProfiler(NoOpTransactionProfiler.getInstance());
322+
if (appStartTransactionProfiler != null) {
323+
appStartTransactionProfiler.close();
324+
}
325+
if (appStartContinuousProfiler != null) {
326+
appStartContinuousProfiler.close(true);
327+
}
328+
return;
329+
}
308330
// This is a safeguard, but it should never happen, as the app start profiler should be the
309331
// continuous one.
310332
if (appStartContinuousProfiler != null) {

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,51 @@ class AndroidOptionsInitializerTest {
424424
assertEquals(fixture.sentryOptions.continuousProfiler, NoOpContinuousProfiler.getInstance())
425425
}
426426

427+
@Test
428+
fun `init with profilesSampleRate and enableLegacyProfiling false noops both profilers`() {
429+
fixture.initSut(
430+
configureOptions = {
431+
profilesSampleRate = 1.0
432+
isEnableLegacyProfiling = false
433+
}
434+
)
435+
436+
assertEquals(NoOpTransactionProfiler.getInstance(), fixture.sentryOptions.transactionProfiler)
437+
assertEquals(NoOpContinuousProfiler.getInstance(), fixture.sentryOptions.continuousProfiler)
438+
}
439+
440+
@Test
441+
fun `init with profilesSampler and enableLegacyProfiling false noops both profilers`() {
442+
fixture.initSut(
443+
configureOptions = {
444+
profilesSampler = mock()
445+
isEnableLegacyProfiling = false
446+
}
447+
)
448+
449+
assertEquals(NoOpTransactionProfiler.getInstance(), fixture.sentryOptions.transactionProfiler)
450+
assertEquals(NoOpContinuousProfiler.getInstance(), fixture.sentryOptions.continuousProfiler)
451+
}
452+
453+
@Test
454+
fun `init with profilesSampleRate and enableLegacyProfiling false closes app start profiler`() {
455+
val appStartProfiler = mock<ITransactionProfiler>()
456+
AppStartMetrics.getInstance().appStartProfiler = appStartProfiler
457+
fixture.initSut(
458+
configureOptions = {
459+
profilesSampleRate = 1.0
460+
isEnableLegacyProfiling = false
461+
}
462+
)
463+
464+
assertEquals(NoOpTransactionProfiler.getInstance(), fixture.sentryOptions.transactionProfiler)
465+
verify(appStartProfiler).close()
466+
467+
// AppStartMetrics should be cleared
468+
assertNull(AppStartMetrics.getInstance().appStartProfiler)
469+
assertNull(AppStartMetrics.getInstance().appStartContinuousProfiler)
470+
}
471+
427472
@Test
428473
fun `init reuses transaction profiler of appStartMetrics, if exists`() {
429474
val appStartProfiler = mock<ITransactionProfiler>()

sentry/src/main/java/io/sentry/SentryOptions.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -649,8 +649,8 @@ public class SentryOptions {
649649
private boolean startProfilerOnAppStart = false;
650650

651651
/**
652-
* When false, the legacy {@code Debug}-based profiler is disabled on API &lt; 35 devices. On API 35+
653-
* devices, Android's {@code ProfilingManager} (Perfetto-based stack sampling) is always used
652+
* When false, the legacy {@code Debug}-based profiler is disabled on API &lt; 35 devices. On API
653+
* 35+ devices, Android's {@code ProfilingManager} (Perfetto-based stack sampling) is always used
654654
* regardless of this setting. This option will be deprecated in the next major release and
655655
* removed in the one after.
656656
*/
@@ -2247,9 +2247,13 @@ public void setStartProfilerOnAppStart(final boolean startProfilerOnAppStart) {
22472247
}
22482248

22492249
/**
2250-
* Whether the legacy {@code Debug}-based profiler is enabled on API &lt; 35 devices. On API 35+,
2251-
* Android's {@code ProfilingManager} (Perfetto) is always used regardless of this setting. This
2252-
* option will be deprecated in the next major release and removed in the one after.
2250+
* Whether the legacy {@code Debug}-based profiler is enabled. This controls continuous profiling
2251+
* on API &lt; 35 devices (on API 35+, Android's {@code ProfilingManager} / Perfetto is always
2252+
* used for continuous profiling regardless of this setting) as well as transaction-based
2253+
* profiling ({@code profilesSampleRate}/{@code profilesSampler}) on all devices, since
2254+
* transaction-based profiling always relies on the legacy profiler and is not supported by
2255+
* Perfetto. This option will be deprecated in the next major release and removed in the one
2256+
* after.
22532257
*
22542258
* @return true if legacy profiling is enabled (default).
22552259
*/
@@ -2258,12 +2262,15 @@ public boolean isEnableLegacyProfiling() {
22582262
}
22592263

22602264
/**
2261-
* Set whether the legacy {@code Debug}-based profiler is enabled on API &lt; 35 devices. Set to
2262-
* {@code false} to disable profiling on devices below API 35. On API 35+ devices, Android's
2263-
* {@code ProfilingManager} (Perfetto) is always used and this setting has no effect. This option
2264-
* will be deprecated in the next major release and removed in the one after.
2265+
* Set whether the legacy {@code Debug}-based profiler is enabled. Set to {@code false} to disable
2266+
* continuous profiling on devices below API 35 (on API 35+ devices, Android's {@code
2267+
* ProfilingManager} / Perfetto is always used for continuous profiling and this setting has no
2268+
* effect) as well as transaction-based profiling ({@code profilesSampleRate}/{@code
2269+
* profilesSampler}) on all devices, since transaction-based profiling always relies on the legacy
2270+
* profiler and is not supported by Perfetto. This option will be deprecated in the next major
2271+
* release and removed in the one after.
22652272
*
2266-
* @param enableLegacyProfiling false to disable legacy profiling on API &lt; 35.
2273+
* @param enableLegacyProfiling false to disable legacy profiling.
22672274
*/
22682275
public void setEnableLegacyProfiling(final boolean enableLegacyProfiling) {
22692276
this.enableLegacyProfiling = enableLegacyProfiling;

0 commit comments

Comments
 (0)