Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new APIs for Continuous Profiling v8 (p5) #3844

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion sentry-android-core/api/sentry-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ public class io/sentry/android/core/AndroidContinuousProfiler : io/sentry/IConti
public fun close ()V
public fun getProfilerId ()Lio/sentry/protocol/SentryId;
public fun isRunning ()Z
public fun setScopes (Lio/sentry/IScopes;)V
public fun start ()V
public fun stop ()V
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
import io.sentry.ILogger;
import io.sentry.IScopes;
import io.sentry.ISentryExecutorService;
import io.sentry.NoOpScopes;
import io.sentry.PerformanceCollectionData;
import io.sentry.ProfileChunk;
import io.sentry.Sentry;
import io.sentry.SentryLevel;
import io.sentry.SentryOptions;
import io.sentry.android.core.internal.util.SentryFrameMetricsCollector;
Expand Down Expand Up @@ -88,12 +90,14 @@ private void init() {
logger);
}

public synchronized void setScopes(final @NotNull IScopes scopes) {
this.scopes = scopes;
this.performanceCollector = scopes.getOptions().getCompositePerformanceCollector();
}

public synchronized void start() {
if ((scopes == null || scopes != NoOpScopes.getInstance())
&& Sentry.getCurrentScopes() != NoOpScopes.getInstance()) {
this.scopes = Sentry.getCurrentScopes();
stefanosiano marked this conversation as resolved.
Show resolved Hide resolved
this.performanceCollector =
Sentry.getCurrentScopes().getOptions().getCompositePerformanceCollector();
}

// Debug.startMethodTracingSampling() is only available since Lollipop, but Android Profiler
// causes crashes on api 21 -> https://github.com/getsentry/sentry-java/issues/3392
if (buildInfoProvider.getSdkInfoVersion() < Build.VERSION_CODES.LOLLIPOP_MR1) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import io.sentry.IScopes
import io.sentry.ISentryExecutorService
import io.sentry.MemoryCollectionData
import io.sentry.PerformanceCollectionData
import io.sentry.Sentry
import io.sentry.SentryLevel
import io.sentry.SentryNanotimeDate
import io.sentry.SentryTracer
Expand Down Expand Up @@ -80,7 +81,7 @@ class AndroidContinuousProfilerTest {
options.profilingTracesDirPath,
options.profilingTracesHz,
options.executorService
).also { it.setScopes(scopes) }
)
}
}

Expand Down Expand Up @@ -118,6 +119,8 @@ class AndroidContinuousProfilerTest {
// Profiler doesn't start if the folder doesn't exists.
// Usually it's generated when calling Sentry.init, but for tests we can create it manually.
File(fixture.options.profilingTracesDirPath!!).mkdirs()

Sentry.setCurrentScopes(fixture.scopes)
}

@AfterTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
<meta-data android:name="io.sentry.traces.sample-rate" android:value="1.0" />

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

<!-- how to enable app start profiling -->
<meta-data android:name="io.sentry.traces.profiling.enable-app-start" android:value="true" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import android.app.Application;
import android.os.StrictMode;
import io.sentry.Sentry;

/** Apps. main Application. */
public class MyApplication extends Application {

@Override
public void onCreate() {
Sentry.startProfiler();
strictMode();
super.onCreate();

Expand Down
18 changes: 16 additions & 2 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -619,8 +619,10 @@ public final class io/sentry/HubAdapter : io/sentry/IHub {
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public fun setTransaction (Ljava/lang/String;)V
public fun setUser (Lio/sentry/protocol/User;)V
public fun startProfiler ()V
public fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public fun stopProfiler ()V
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public fun withScope (Lio/sentry/ScopeCallback;)V
}
Expand Down Expand Up @@ -684,8 +686,10 @@ public final class io/sentry/HubScopesWrapper : io/sentry/IHub {
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public fun setTransaction (Ljava/lang/String;)V
public fun setUser (Lio/sentry/protocol/User;)V
public fun startProfiler ()V
public fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public fun stopProfiler ()V
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public fun withScope (Lio/sentry/ScopeCallback;)V
}
Expand Down Expand Up @@ -714,7 +718,6 @@ public abstract interface class io/sentry/IContinuousProfiler {
public abstract fun close ()V
public abstract fun getProfilerId ()Lio/sentry/protocol/SentryId;
public abstract fun isRunning ()Z
public abstract fun setScopes (Lio/sentry/IScopes;)V
public abstract fun start ()V
public abstract fun stop ()V
}
Expand Down Expand Up @@ -921,11 +924,13 @@ public abstract interface class io/sentry/IScopes {
public abstract fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public abstract fun setTransaction (Ljava/lang/String;)V
public abstract fun setUser (Lio/sentry/protocol/User;)V
public abstract fun startProfiler ()V
public abstract fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;)Lio/sentry/ITransaction;
public abstract fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ITransaction;
public fun startTransaction (Ljava/lang/String;Ljava/lang/String;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public abstract fun stopProfiler ()V
public abstract fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public abstract fun withScope (Lio/sentry/ScopeCallback;)V
}
Expand Down Expand Up @@ -1395,7 +1400,6 @@ public final class io/sentry/NoOpContinuousProfiler : io/sentry/IContinuousProfi
public static fun getInstance ()Lio/sentry/NoOpContinuousProfiler;
public fun getProfilerId ()Lio/sentry/protocol/SentryId;
public fun isRunning ()Z
public fun setScopes (Lio/sentry/IScopes;)V
public fun start ()V
public fun stop ()V
}
Expand Down Expand Up @@ -1465,8 +1469,10 @@ public final class io/sentry/NoOpHub : io/sentry/IHub {
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public fun setTransaction (Ljava/lang/String;)V
public fun setUser (Lio/sentry/protocol/User;)V
public fun startProfiler ()V
public fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public fun stopProfiler ()V
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public fun withScope (Lio/sentry/ScopeCallback;)V
}
Expand Down Expand Up @@ -1625,8 +1631,10 @@ public final class io/sentry/NoOpScopes : io/sentry/IScopes {
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public fun setTransaction (Ljava/lang/String;)V
public fun setUser (Lio/sentry/protocol/User;)V
public fun startProfiler ()V
public fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public fun stopProfiler ()V
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public fun withScope (Lio/sentry/ScopeCallback;)V
}
Expand Down Expand Up @@ -2278,8 +2286,10 @@ public final class io/sentry/Scopes : io/sentry/IScopes {
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public fun setTransaction (Ljava/lang/String;)V
public fun setUser (Lio/sentry/protocol/User;)V
public fun startProfiler ()V
public fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public fun stopProfiler ()V
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public fun withScope (Lio/sentry/ScopeCallback;)V
}
Expand Down Expand Up @@ -2343,8 +2353,10 @@ public final class io/sentry/ScopesAdapter : io/sentry/IScopes {
public fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public fun setTransaction (Ljava/lang/String;)V
public fun setUser (Lio/sentry/protocol/User;)V
public fun startProfiler ()V
public fun startSession ()V
public fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public fun stopProfiler ()V
public fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public fun withScope (Lio/sentry/ScopeCallback;)V
}
Expand Down Expand Up @@ -2447,12 +2459,14 @@ public final class io/sentry/Sentry {
public static fun setTag (Ljava/lang/String;Ljava/lang/String;)V
public static fun setTransaction (Ljava/lang/String;)V
public static fun setUser (Lio/sentry/protocol/User;)V
public static fun startProfiler ()V
public static fun startSession ()V
public static fun startTransaction (Lio/sentry/TransactionContext;)Lio/sentry/ITransaction;
public static fun startTransaction (Lio/sentry/TransactionContext;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public static fun startTransaction (Ljava/lang/String;Ljava/lang/String;)Lio/sentry/ITransaction;
public static fun startTransaction (Ljava/lang/String;Ljava/lang/String;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public static fun startTransaction (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/sentry/TransactionOptions;)Lio/sentry/ITransaction;
public static fun stopProfiler ()V
public static fun withIsolationScope (Lio/sentry/ScopeCallback;)V
public static fun withScope (Lio/sentry/ScopeCallback;)V
}
Expand Down
10 changes: 10 additions & 0 deletions sentry/src/main/java/io/sentry/HubAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,16 @@ public boolean isAncestorOf(final @Nullable IScopes otherScopes) {
return Sentry.startTransaction(transactionContext, transactionOptions);
}

@Override
public void startProfiler() {
Sentry.startProfiler();
}

@Override
public void stopProfiler() {
Sentry.stopProfiler();
}

@Override
public @NotNull SentryId captureProfileChunk(
final @NotNull ProfileChunk profilingContinuousData) {
Expand Down
10 changes: 10 additions & 0 deletions sentry/src/main/java/io/sentry/HubScopesWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,16 @@ public boolean isAncestorOf(final @Nullable IScopes otherScopes) {
return scopes.startTransaction(transactionContext, transactionOptions);
}

@Override
public void startProfiler() {
scopes.startProfiler();
}

@Override
public void stopProfiler() {
scopes.stopProfiler();
}

@ApiStatus.Internal
@Override
public void setSpanContext(
Expand Down
2 changes: 0 additions & 2 deletions sentry/src/main/java/io/sentry/IContinuousProfiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ public interface IContinuousProfiler {

void stop();

void setScopes(final @NotNull IScopes scopes);

/** Cancel the profiler and stops it. Used on SDK close. */
void close();

Expand Down
4 changes: 4 additions & 0 deletions sentry/src/main/java/io/sentry/IScopes.java
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,10 @@ ITransaction startTransaction(
final @NotNull TransactionContext transactionContext,
final @NotNull TransactionOptions transactionOptions);

void startProfiler();

void stopProfiler();

/**
* Associates {@link ISpan} and the transaction name with the {@link Throwable}. Used to determine
* in which trace the exception has been thrown in framework integrations.
Expand Down
3 changes: 0 additions & 3 deletions sentry/src/main/java/io/sentry/NoOpContinuousProfiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ public void start() {}
@Override
public void stop() {}

@Override
public void setScopes(@NotNull IScopes scopes) {}

@Override
public boolean isRunning() {
return false;
Expand Down
6 changes: 6 additions & 0 deletions sentry/src/main/java/io/sentry/NoOpHub.java
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,12 @@ public boolean isAncestorOf(@Nullable IScopes otherScopes) {
return NoOpTransaction.getInstance();
}

@Override
public void startProfiler() {}

@Override
public void stopProfiler() {}

@Override
public void setSpanContext(
final @NotNull Throwable throwable,
Expand Down
6 changes: 6 additions & 0 deletions sentry/src/main/java/io/sentry/NoOpScopes.java
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,12 @@ public boolean isAncestorOf(@Nullable IScopes otherScopes) {
return NoOpTransaction.getInstance();
}

@Override
public void startProfiler() {}

@Override
public void stopProfiler() {}

@Override
public void setSpanContext(
final @NotNull Throwable throwable,
Expand Down
28 changes: 28 additions & 0 deletions sentry/src/main/java/io/sentry/Scopes.java
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,34 @@ public void flush(long timeoutMillis) {
return transaction;
}

@Override
public void startProfiler() {
if (getOptions().isContinuousProfilingEnabled()) {
getOptions().getLogger().log(SentryLevel.DEBUG, "Started continuous Profiling.");
getOptions().getContinuousProfiler().start();
} else {
getOptions()
.getLogger()
.log(
SentryLevel.WARNING,
"Continuous Profiling is not enabled. Set profilesSampleRate and profilesSampler to null to enable it.");
}
}

@Override
public void stopProfiler() {
if (getOptions().isContinuousProfilingEnabled()) {
getOptions().getLogger().log(SentryLevel.DEBUG, "Stopped continuous Profiling.");
getOptions().getContinuousProfiler().stop();
} else {
getOptions()
.getLogger()
.log(
SentryLevel.WARNING,
"Continuous Profiling is not enabled. Set profilesSampleRate and profilesSampler to null to enable it.");
}
}

@Override
@ApiStatus.Internal
public void setSpanContext(
Expand Down
10 changes: 10 additions & 0 deletions sentry/src/main/java/io/sentry/ScopesAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,16 @@ public boolean isAncestorOf(final @Nullable IScopes otherScopes) {
return Sentry.startTransaction(transactionContext, transactionOptions);
}

@Override
public void startProfiler() {
Sentry.startProfiler();
}

@Override
public void stopProfiler() {
Sentry.stopProfiler();
}

@ApiStatus.Internal
@Override
public void setSpanContext(
Expand Down
10 changes: 10 additions & 0 deletions sentry/src/main/java/io/sentry/Sentry.java
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,16 @@ public static void endSession() {
return getCurrentScopes().startTransaction(transactionContext, transactionOptions);
}

/** Starts the continuous profiler, if enabled. */
public static void startProfiler() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wdyt of introducing a subclass (like a namespace) Sentry.profiling().start() akin to Sentry.metrics()? We're also gonna do that for replay soon

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to keep the SDKs aligned. Other SDKs, like cocoa, is doing SentrySDK.startProfiler

getCurrentScopes().startProfiler();
}

/** Starts the continuous profiler, if enabled. */
public static void stopProfiler() {
getCurrentScopes().stopProfiler();
}

/**
* Gets the current active transaction or span.
*
Expand Down
10 changes: 10 additions & 0 deletions sentry/src/test/java/io/sentry/HubAdapterTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -265,4 +265,14 @@ class HubAdapterTest {
HubAdapter.getInstance().reportFullyDisplayed()
verify(scopes).reportFullyDisplayed()
}

@Test fun `startProfiler calls Hub`() {
HubAdapter.getInstance().startProfiler()
verify(scopes).startProfiler()
}

@Test fun `stopProfiler calls Hub`() {
HubAdapter.getInstance().stopProfiler()
verify(scopes).stopProfiler()
}
}
6 changes: 6 additions & 0 deletions sentry/src/test/java/io/sentry/NoOpHubTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,10 @@ class NoOpHubTest {
sut.withScope(scopeCallback)
verify(scopeCallback).run(NoOpScope.getInstance())
}

@Test
fun `startProfiler doesnt throw`() = sut.startProfiler()

@Test
fun `stopProfiler doesnt throw`() = sut.stopProfiler()
}
10 changes: 10 additions & 0 deletions sentry/src/test/java/io/sentry/ScopesAdapterTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -265,4 +265,14 @@ class ScopesAdapterTest {
ScopesAdapter.getInstance().reportFullyDisplayed()
verify(scopes).reportFullyDisplayed()
}

@Test fun `startProfiler calls Scopes`() {
ScopesAdapter.getInstance().startProfiler()
verify(scopes).startProfiler()
}

@Test fun `stopProfiler calls Scopes`() {
ScopesAdapter.getInstance().stopProfiler()
verify(scopes).stopProfiler()
}
}
Loading