Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 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
14 changes: 7 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

- Add Continuous Profiling Support ([#3710](https://github.com/getsentry/sentry-java/pull/3710))

To enable Continuous Profiling use the `Sentry.startProfiler` and `Sentry.stopProfiler` experimental APIs. Sampling rate can be set through `options.continuousProfilesSampleRate` (defaults to 1.0).
To enable Continuous Profiling use the `Sentry.startProfileSession` and `Sentry.stopProfileSession` experimental APIs. Sampling rate can be set through `options.profileSessionSampleRate` (defaults to 0.0).
Note: Both `options.profilesSampler` and `options.profilesSampleRate` must **not** be set to enable Continuous Profiling.

```java
Expand All @@ -15,27 +15,27 @@
SentryAndroid.init(context) { options ->

// Currently under experimental options:
options.getExperimental().setContinuousProfilesSampleRate(1.0);
options.getExperimental().setProfileSessionSampleRate(1.0);
}
// Start profiling
Sentry.startProfiler();
Sentry.startProfileSession();

// After all profiling is done, stop the profiler. Profiles can last indefinitely if not stopped.
Sentry.stopProfiler();
Sentry.stopProfileSession();
```
```kotlin
import io.sentry.android.core.SentryAndroid

SentryAndroid.init(context) { options ->

// Currently under experimental options:
options.experimental.continuousProfilesSampleRate = 1.0
options.experimental.profileSessionSampleRate = 1.0
}
// Start profiling
Sentry.startProfiler()
Sentry.startProfileSession()

// After all profiling is done, stop the profiler. Profiles can last indefinitely if not stopped.
Sentry.stopProfiler()
Sentry.stopProfileSession()
```

To learn more visit [Sentry's Continuous Profiling](https://docs.sentry.io/product/explore/profiling/transaction-vs-continuous-profiling/#continuous-profiling-mode) documentation page.
Expand Down
3 changes: 2 additions & 1 deletion sentry-android-core/api/sentry-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public class io/sentry/android/core/AndroidContinuousProfiler : io/sentry/IConti
public fun getProfilerId ()Lio/sentry/protocol/SentryId;
public fun isRunning ()Z
public fun onRateLimitChanged (Lio/sentry/transport/RateLimiter;)V
public fun start ()V
public fun reevaluateSampling ()V
public fun start (Lio/sentry/TracesSampler;)V
public fun stop ()V
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.sentry.SentryLevel;
import io.sentry.SentryNanotimeDate;
import io.sentry.SentryOptions;
import io.sentry.TracesSampler;
import io.sentry.android.core.internal.util.SentryFrameMetricsCollector;
import io.sentry.protocol.SentryId;
import io.sentry.transport.RateLimiter;
Expand Down Expand Up @@ -55,6 +56,8 @@ public class AndroidContinuousProfiler
private @NotNull SentryId chunkId = SentryId.EMPTY_ID;
private final @NotNull AtomicBoolean isClosed = new AtomicBoolean(false);
private @NotNull SentryDate startProfileChunkTimestamp = new SentryNanotimeDate();
private boolean shouldSample = true;
private boolean isSampled = false;

public AndroidContinuousProfiler(
final @NotNull BuildInfoProvider buildInfoProvider,
Expand Down Expand Up @@ -100,7 +103,24 @@ private void init() {
logger);
}

public synchronized void start() {
public synchronized void start(final @NotNull TracesSampler tracesSampler) {
if (shouldSample) {
isSampled = tracesSampler.sampleSessionProfile();
shouldSample = false;
}
if (!isSampled) {
logger.log(SentryLevel.DEBUG, "Profiler was not started due to sampling decision.");
return;
}
if (isRunning()) {
logger.log(SentryLevel.DEBUG, "Profiler is already running.");
return;
}
logger.log(SentryLevel.DEBUG, "Started Profiler.");
startProfile();
}

private synchronized void startProfile() {
if ((scopes == null || scopes == NoOpScopes.getInstance())
&& Sentry.getCurrentScopes() != NoOpScopes.getInstance()) {
this.scopes = Sentry.getCurrentScopes();
Expand Down Expand Up @@ -236,14 +256,18 @@ private synchronized void stop(final boolean restartProfiler) {

if (restartProfiler) {
logger.log(SentryLevel.DEBUG, "Profile chunk finished. Starting a new one.");
start();
startProfile();
} else {
// When the profiler is stopped manually, we have to reset its id
profilerId = SentryId.EMPTY_ID;
logger.log(SentryLevel.DEBUG, "Profile chunk finished.");
}
}

public synchronized void reevaluateSampling() {
shouldSample = true;
}

public synchronized void close() {
stop();
isClosed.set(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ final class ManifestMetadataReader {

static final String PROFILES_SAMPLE_RATE = "io.sentry.traces.profiling.sample-rate";

static final String CONTINUOUS_PROFILES_SAMPLE_RATE =
"io.sentry.traces.profiling.continuous-sample-rate";
static final String PROFILE_SESSION_SAMPLE_RATE =
"io.sentry.traces.profiling.session-sample-rate";

@ApiStatus.Experimental static final String TRACE_SAMPLING = "io.sentry.traces.trace-sampling";
static final String TRACE_PROPAGATION_TARGETS = "io.sentry.traces.trace-propagation-targets";
Expand Down Expand Up @@ -318,11 +318,11 @@ static void applyMetadata(
}
}

if (options.getContinuousProfilesSampleRate() == 1.0) {
final double continuousProfilesSampleRate =
readDouble(metadata, logger, CONTINUOUS_PROFILES_SAMPLE_RATE);
if (continuousProfilesSampleRate != -1) {
options.getExperimental().setContinuousProfilesSampleRate(continuousProfilesSampleRate);
if (options.getProfileSessionSampleRate() == 0.0) {
final double profileSessionSampleRate =
readDouble(metadata, logger, PROFILE_SESSION_SAMPLE_RATE);
if (profileSessionSampleRate != -1) {
options.getExperimental().setProfileSessionSampleRate(profileSessionSampleRate);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.sentry.SentryExecutorService;
import io.sentry.SentryLevel;
import io.sentry.SentryOptions;
import io.sentry.TracesSampler;
import io.sentry.TracesSamplingDecision;
import io.sentry.android.core.internal.util.FirstDrawDoneListener;
import io.sentry.android.core.internal.util.SentryFrameMetricsCollector;
Expand Down Expand Up @@ -180,7 +181,12 @@ private void createAndStartContinuousProfiler(
appStartMetrics.setAppStartProfiler(null);
appStartMetrics.setAppStartContinuousProfiler(appStartContinuousProfiler);
logger.log(SentryLevel.DEBUG, "App start continuous profiling started.");
appStartContinuousProfiler.start();
SentryOptions sentryOptions = SentryOptions.empty();
// Let's fake a sampler to accept the sampling decision that was calculated on last run
sentryOptions
.getExperimental()
.setProfileSessionSampleRate(profilingOptions.isContinuousProfileSampled() ? 1 : 0);
appStartContinuousProfiler.start(new TracesSampler(sentryOptions));
}

private void createAndStartTransactionProfiler(
Expand Down
Loading