Skip to content

Commit 540e276

Browse files
authored
Add new APIs for Continuous Profiling v8 (p5) (#3844)
* AndroidContinuousProfiler now retrieve the scopes on start() * removed profilesSampleRate from sample app to enable continuous profiling * added Sentry.startProfiler and Sentry.stopProfiler APIs
1 parent b7e889c commit 540e276

File tree

21 files changed

+238
-15
lines changed

21 files changed

+238
-15
lines changed

sentry-android-core/api/sentry-android-core.api

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ public class io/sentry/android/core/AndroidContinuousProfiler : io/sentry/IConti
4141
public fun close ()V
4242
public fun getProfilerId ()Lio/sentry/protocol/SentryId;
4343
public fun isRunning ()Z
44-
public fun setScopes (Lio/sentry/IScopes;)V
4544
public fun start ()V
4645
public fun stop ()V
4746
}

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
import io.sentry.ILogger;
1010
import io.sentry.IScopes;
1111
import io.sentry.ISentryExecutorService;
12+
import io.sentry.NoOpScopes;
1213
import io.sentry.PerformanceCollectionData;
1314
import io.sentry.ProfileChunk;
15+
import io.sentry.Sentry;
1416
import io.sentry.SentryLevel;
1517
import io.sentry.SentryOptions;
1618
import io.sentry.android.core.internal.util.SentryFrameMetricsCollector;
@@ -88,12 +90,14 @@ private void init() {
8890
logger);
8991
}
9092

91-
public synchronized void setScopes(final @NotNull IScopes scopes) {
92-
this.scopes = scopes;
93-
this.performanceCollector = scopes.getOptions().getCompositePerformanceCollector();
94-
}
95-
9693
public synchronized void start() {
94+
if ((scopes == null || scopes != NoOpScopes.getInstance())
95+
&& Sentry.getCurrentScopes() != NoOpScopes.getInstance()) {
96+
this.scopes = Sentry.getCurrentScopes();
97+
this.performanceCollector =
98+
Sentry.getCurrentScopes().getOptions().getCompositePerformanceCollector();
99+
}
100+
97101
// Debug.startMethodTracingSampling() is only available since Lollipop, but Android Profiler
98102
// causes crashes on api 21 -> https://github.com/getsentry/sentry-java/issues/3392
99103
if (buildInfoProvider.getSdkInfoVersion() < Build.VERSION_CODES.LOLLIPOP_MR1) return;

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import io.sentry.IScopes
1111
import io.sentry.ISentryExecutorService
1212
import io.sentry.MemoryCollectionData
1313
import io.sentry.PerformanceCollectionData
14+
import io.sentry.Sentry
1415
import io.sentry.SentryLevel
1516
import io.sentry.SentryNanotimeDate
1617
import io.sentry.SentryTracer
@@ -80,7 +81,7 @@ class AndroidContinuousProfilerTest {
8081
options.profilingTracesDirPath,
8182
options.profilingTracesHz,
8283
options.executorService
83-
).also { it.setScopes(scopes) }
84+
)
8485
}
8586
}
8687

@@ -118,6 +119,8 @@ class AndroidContinuousProfilerTest {
118119
// Profiler doesn't start if the folder doesn't exists.
119120
// Usually it's generated when calling Sentry.init, but for tests we can create it manually.
120121
File(fixture.options.profilingTracesDirPath!!).mkdirs()
122+
123+
Sentry.setCurrentScopes(fixture.scopes)
121124
}
122125

123126
@AfterTest

sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@
110110
<meta-data android:name="io.sentry.traces.sample-rate" android:value="1.0" />
111111

112112
<!-- how to enable profiling when starting transactions -->
113-
<meta-data android:name="io.sentry.traces.profiling.sample-rate" android:value="1" />
113+
<!-- <meta-data android:name="io.sentry.traces.profiling.sample-rate" android:value="1.0" />-->
114114

115115
<!-- how to enable app start profiling -->
116116
<meta-data android:name="io.sentry.traces.profiling.enable-app-start" android:value="true" />

sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/MyApplication.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
import android.app.Application;
44
import android.os.StrictMode;
5+
import io.sentry.Sentry;
56

67
/** Apps. main Application. */
78
public class MyApplication extends Application {
89

910
@Override
1011
public void onCreate() {
12+
Sentry.startProfiler();
1113
strictMode();
1214
super.onCreate();
1315

sentry/api/sentry.api

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -619,8 +619,10 @@ public final class io/sentry/HubAdapter : io/sentry/IHub {
619619
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
620620
public fun setTransaction (Ljava/lang/String;)V
621621
public fun setUser (Lio/sentry/protocol/User;)V
622+
public fun startProfiler ()V
622623
public fun startSession ()V
623624
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
625+
public fun stopProfiler ()V
624626
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
625627
public fun withScope (Lio/sentry/ScopeCallback;)V
626628
}
@@ -684,8 +686,10 @@ public final class io/sentry/HubScopesWrapper : io/sentry/IHub {
684686
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
685687
public fun setTransaction (Ljava/lang/String;)V
686688
public fun setUser (Lio/sentry/protocol/User;)V
689+
public fun startProfiler ()V
687690
public fun startSession ()V
688691
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
692+
public fun stopProfiler ()V
689693
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
690694
public fun withScope (Lio/sentry/ScopeCallback;)V
691695
}
@@ -714,7 +718,6 @@ public abstract interface class io/sentry/IContinuousProfiler {
714718
public abstract fun close ()V
715719
public abstract fun getProfilerId ()Lio/sentry/protocol/SentryId;
716720
public abstract fun isRunning ()Z
717-
public abstract fun setScopes (Lio/sentry/IScopes;)V
718721
public abstract fun start ()V
719722
public abstract fun stop ()V
720723
}
@@ -921,11 +924,13 @@ public abstract interface class io/sentry/IScopes {
921924
public abstract fun setTag (Ljava/lang/String;Ljava/lang/String;)V
922925
public abstract fun setTransaction (Ljava/lang/String;)V
923926
public abstract fun setUser (Lio/sentry/protocol/User;)V
927+
public abstract fun startProfiler ()V
924928
public abstract fun startSession ()V
925929
public fun startTransaction (Lio/sentry/TransactionContext;)Lio/sentry/ITransaction;
926930
public abstract fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
927931
public fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ITransaction;
928932
public fun startTransaction (Ljava/lang/String;Ljava/lang/String;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
933+
public abstract fun stopProfiler ()V
929934
public abstract fun withIsolationScope (Lio/sentry/ScopeCallback;)V
930935
public abstract fun withScope (Lio/sentry/ScopeCallback;)V
931936
}
@@ -1395,7 +1400,6 @@ public final class io/sentry/NoOpContinuousProfiler : io/sentry/IContinuousProfi
13951400
public static fun getInstance ()Lio/sentry/NoOpContinuousProfiler;
13961401
public fun getProfilerId ()Lio/sentry/protocol/SentryId;
13971402
public fun isRunning ()Z
1398-
public fun setScopes (Lio/sentry/IScopes;)V
13991403
public fun start ()V
14001404
public fun stop ()V
14011405
}
@@ -1465,8 +1469,10 @@ public final class io/sentry/NoOpHub : io/sentry/IHub {
14651469
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
14661470
public fun setTransaction (Ljava/lang/String;)V
14671471
public fun setUser (Lio/sentry/protocol/User;)V
1472+
public fun startProfiler ()V
14681473
public fun startSession ()V
14691474
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
1475+
public fun stopProfiler ()V
14701476
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
14711477
public fun withScope (Lio/sentry/ScopeCallback;)V
14721478
}
@@ -1625,8 +1631,10 @@ public final class io/sentry/NoOpScopes : io/sentry/IScopes {
16251631
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
16261632
public fun setTransaction (Ljava/lang/String;)V
16271633
public fun setUser (Lio/sentry/protocol/User;)V
1634+
public fun startProfiler ()V
16281635
public fun startSession ()V
16291636
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
1637+
public fun stopProfiler ()V
16301638
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
16311639
public fun withScope (Lio/sentry/ScopeCallback;)V
16321640
}
@@ -2278,8 +2286,10 @@ public final class io/sentry/Scopes : io/sentry/IScopes {
22782286
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
22792287
public fun setTransaction (Ljava/lang/String;)V
22802288
public fun setUser (Lio/sentry/protocol/User;)V
2289+
public fun startProfiler ()V
22812290
public fun startSession ()V
22822291
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
2292+
public fun stopProfiler ()V
22832293
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
22842294
public fun withScope (Lio/sentry/ScopeCallback;)V
22852295
}
@@ -2343,8 +2353,10 @@ public final class io/sentry/ScopesAdapter : io/sentry/IScopes {
23432353
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
23442354
public fun setTransaction (Ljava/lang/String;)V
23452355
public fun setUser (Lio/sentry/protocol/User;)V
2356+
public fun startProfiler ()V
23462357
public fun startSession ()V
23472358
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
2359+
public fun stopProfiler ()V
23482360
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
23492361
public fun withScope (Lio/sentry/ScopeCallback;)V
23502362
}
@@ -2447,12 +2459,14 @@ public final class io/sentry/Sentry {
24472459
public static fun setTag (Ljava/lang/String;Ljava/lang/String;)V
24482460
public static fun setTransaction (Ljava/lang/String;)V
24492461
public static fun setUser (Lio/sentry/protocol/User;)V
2462+
public static fun startProfiler ()V
24502463
public static fun startSession ()V
24512464
public static fun startTransaction (Lio/sentry/TransactionContext;)Lio/sentry/ITransaction;
24522465
public static fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
24532466
public static fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ITransaction;
24542467
public static fun startTransaction (Ljava/lang/String;Ljava/lang/String;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
24552468
public static fun startTransaction (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
2469+
public static fun stopProfiler ()V
24562470
public static fun withIsolationScope (Lio/sentry/ScopeCallback;)V
24572471
public static fun withScope (Lio/sentry/ScopeCallback;)V
24582472
}

sentry/src/main/java/io/sentry/HubAdapter.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,16 @@ public boolean isAncestorOf(final @Nullable IScopes otherScopes) {
277277
return Sentry.startTransaction(transactionContext, transactionOptions);
278278
}
279279

280+
@Override
281+
public void startProfiler() {
282+
Sentry.startProfiler();
283+
}
284+
285+
@Override
286+
public void stopProfiler() {
287+
Sentry.stopProfiler();
288+
}
289+
280290
@Override
281291
public @NotNull SentryId captureProfileChunk(
282292
final @NotNull ProfileChunk profilingContinuousData) {

sentry/src/main/java/io/sentry/HubScopesWrapper.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,16 @@ public boolean isAncestorOf(final @Nullable IScopes otherScopes) {
277277
return scopes.startTransaction(transactionContext, transactionOptions);
278278
}
279279

280+
@Override
281+
public void startProfiler() {
282+
scopes.startProfiler();
283+
}
284+
285+
@Override
286+
public void stopProfiler() {
287+
scopes.stopProfiler();
288+
}
289+
280290
@ApiStatus.Internal
281291
@Override
282292
public void setSpanContext(

sentry/src/main/java/io/sentry/IContinuousProfiler.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ public interface IContinuousProfiler {
1313

1414
void stop();
1515

16-
void setScopes(final @NotNull IScopes scopes);
17-
1816
/** Cancel the profiler and stops it. Used on SDK close. */
1917
void close();
2018

sentry/src/main/java/io/sentry/IScopes.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,10 @@ ITransaction startTransaction(
592592
final @NotNull TransactionContext transactionContext,
593593
final @NotNull TransactionOptions transactionOptions);
594594

595+
void startProfiler();
596+
597+
void stopProfiler();
598+
595599
/**
596600
* Associates {@link ISpan} and the transaction name with the {@link Throwable}. Used to determine
597601
* in which trace the exception has been thrown in framework integrations.

sentry/src/main/java/io/sentry/NoOpContinuousProfiler.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ public void start() {}
1919
@Override
2020
public void stop() {}
2121

22-
@Override
23-
public void setScopes(@NotNull IScopes scopes) {}
24-
2522
@Override
2623
public boolean isRunning() {
2724
return false;

sentry/src/main/java/io/sentry/NoOpHub.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,12 @@ public boolean isAncestorOf(@Nullable IScopes otherScopes) {
243243
return NoOpTransaction.getInstance();
244244
}
245245

246+
@Override
247+
public void startProfiler() {}
248+
249+
@Override
250+
public void stopProfiler() {}
251+
246252
@Override
247253
public void setSpanContext(
248254
final @NotNull Throwable throwable,

sentry/src/main/java/io/sentry/NoOpScopes.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,12 @@ public boolean isAncestorOf(@Nullable IScopes otherScopes) {
238238
return NoOpTransaction.getInstance();
239239
}
240240

241+
@Override
242+
public void startProfiler() {}
243+
244+
@Override
245+
public void stopProfiler() {}
246+
241247
@Override
242248
public void setSpanContext(
243249
final @NotNull Throwable throwable,

sentry/src/main/java/io/sentry/Scopes.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,34 @@ public void flush(long timeoutMillis) {
923923
return transaction;
924924
}
925925

926+
@Override
927+
public void startProfiler() {
928+
if (getOptions().isContinuousProfilingEnabled()) {
929+
getOptions().getLogger().log(SentryLevel.DEBUG, "Started continuous Profiling.");
930+
getOptions().getContinuousProfiler().start();
931+
} else {
932+
getOptions()
933+
.getLogger()
934+
.log(
935+
SentryLevel.WARNING,
936+
"Continuous Profiling is not enabled. Set profilesSampleRate and profilesSampler to null to enable it.");
937+
}
938+
}
939+
940+
@Override
941+
public void stopProfiler() {
942+
if (getOptions().isContinuousProfilingEnabled()) {
943+
getOptions().getLogger().log(SentryLevel.DEBUG, "Stopped continuous Profiling.");
944+
getOptions().getContinuousProfiler().stop();
945+
} else {
946+
getOptions()
947+
.getLogger()
948+
.log(
949+
SentryLevel.WARNING,
950+
"Continuous Profiling is not enabled. Set profilesSampleRate and profilesSampler to null to enable it.");
951+
}
952+
}
953+
926954
@Override
927955
@ApiStatus.Internal
928956
public void setSpanContext(

sentry/src/main/java/io/sentry/ScopesAdapter.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,16 @@ public boolean isAncestorOf(final @Nullable IScopes otherScopes) {
280280
return Sentry.startTransaction(transactionContext, transactionOptions);
281281
}
282282

283+
@Override
284+
public void startProfiler() {
285+
Sentry.startProfiler();
286+
}
287+
288+
@Override
289+
public void stopProfiler() {
290+
Sentry.stopProfiler();
291+
}
292+
283293
@ApiStatus.Internal
284294
@Override
285295
public void setSpanContext(

sentry/src/main/java/io/sentry/Sentry.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,16 @@ public static void endSession() {
10491049
return getCurrentScopes().startTransaction(transactionContext, transactionOptions);
10501050
}
10511051

1052+
/** Starts the continuous profiler, if enabled. */
1053+
public static void startProfiler() {
1054+
getCurrentScopes().startProfiler();
1055+
}
1056+
1057+
/** Starts the continuous profiler, if enabled. */
1058+
public static void stopProfiler() {
1059+
getCurrentScopes().stopProfiler();
1060+
}
1061+
10521062
/**
10531063
* Gets the current active transaction or span.
10541064
*

sentry/src/test/java/io/sentry/HubAdapterTest.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,4 +265,14 @@ class HubAdapterTest {
265265
HubAdapter.getInstance().reportFullyDisplayed()
266266
verify(scopes).reportFullyDisplayed()
267267
}
268+
269+
@Test fun `startProfiler calls Hub`() {
270+
HubAdapter.getInstance().startProfiler()
271+
verify(scopes).startProfiler()
272+
}
273+
274+
@Test fun `stopProfiler calls Hub`() {
275+
HubAdapter.getInstance().stopProfiler()
276+
verify(scopes).stopProfiler()
277+
}
268278
}

sentry/src/test/java/io/sentry/NoOpHubTest.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,10 @@ class NoOpHubTest {
115115
sut.withScope(scopeCallback)
116116
verify(scopeCallback).run(NoOpScope.getInstance())
117117
}
118+
119+
@Test
120+
fun `startProfiler doesnt throw`() = sut.startProfiler()
121+
122+
@Test
123+
fun `stopProfiler doesnt throw`() = sut.stopProfiler()
118124
}

sentry/src/test/java/io/sentry/ScopesAdapterTest.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,4 +265,14 @@ class ScopesAdapterTest {
265265
ScopesAdapter.getInstance().reportFullyDisplayed()
266266
verify(scopes).reportFullyDisplayed()
267267
}
268+
269+
@Test fun `startProfiler calls Scopes`() {
270+
ScopesAdapter.getInstance().startProfiler()
271+
verify(scopes).startProfiler()
272+
}
273+
274+
@Test fun `stopProfiler calls Scopes`() {
275+
ScopesAdapter.getInstance().stopProfiler()
276+
verify(scopes).stopProfiler()
277+
}
268278
}

0 commit comments

Comments
 (0)