Skip to content
New issue

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

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

Already on GitHub? # to your account

ref(profiling): public methods for new API #4995

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
16 changes: 15 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@

## Unreleased

### Features

- New continuous profiling configuration API (#4952)

> [!Important]
> With the addition of the new profiling configuation API, the previous profiling API are deprecated and will be removed in the next major version of the SDK:
>
> - `SentryOptions.enableProfiling`
> - `SentryOptions.isProfilingEnabled`
> - `SentryOptions.profilesSampleRate`
> - `SentryOptions.profilesSampler`
> - `SentryOptions.enableLaunchProfiling`
>
> Additionally, note that the behavior of `SentrySDK.startProfiler()` will change once the above APIs are removed, as follows: before adding the new configuration API (`SentryProfileOptions`), `SentrySDK.startProfiler()` would unconditionally start a continuous profile if both `SentryOptions.profilesSampleRate` and `SentryOptions.profilesSampler` were `nil`, or no-op if either was non-`nil` (meaning the SDK would operate under original, transaction-based, profiling model). In the next major version, `SentryOptions.profilesSampleRate` and `SentryOptions.profilesSampler` will be removed, and `SentrySDK.startProfile()` will become a no-op unless you configure `SentryProfileOptions.sessionSampleRate` to a value greater than zero (which is its default). If you already have calls to `SentrySDK.startProfiler()` in your code, ensure you properly configure `SentryProfileOptions` via `SentryOptions.configureProfiling` to avoid losing profiling coverage.

### Fixes

- Continuous profile stop requests are cancelled by subsequent timely calls to start (#4993)
Expand Down Expand Up @@ -39,7 +54,6 @@
### Features

- Add extension for `Data` to track file I/O operations with Sentry (#4862)
- New continuous profiling API (#4952)
- Send fatal app hang session updates (#4921) only when enabling the option `enableAppHangTrackingV2`.
- Add experimental flag `options.sessionReplay.enableExperimentalViewRenderer` to enable up to 5x times more performance in Session Replay (#4940)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,11 @@ class ProfilingViewController: UIViewController, UITextFieldDelegate {
}

@IBAction func startContinuousProfiler(_ sender: Any) {
SentrySDK.startProfileSession()
SentrySDK.startProfiler()
}

@IBAction func stopContinuousProfiler(_ sender: Any) {
SentrySDK.stopProfileSession()
SentrySDK.stopProfiler()
}

@IBAction func viewLastProfile(_ sender: Any) {
Expand Down
5 changes: 2 additions & 3 deletions Sources/Configuration/SDK.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,6 @@ ENABLE_NS_ASSERTIONS = $(ENABLE_NS_ASSERTIONS_$(CONFIGURATION))

ENABLE_STRICT_OBJC_MSGSEND = YES

GCC_TREAT_WARNINGS_AS_ERRORS = YES

CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES
CLANG_WARN_COMMA = YES
CLANG_WARN_DOCUMENTATION_COMMENTS = YES
Expand Down Expand Up @@ -163,7 +161,8 @@ SWIFT_OPTIMIZATION_LEVEL_Test = -Onone
SWIFT_OPTIMIZATION_LEVEL_TestCI = -Onone
SWIFT_OPTIMIZATION_LEVEL = $(SWIFT_OPTIMIZATION_LEVEL_$(CONFIGURATION))

SWIFT_TREAT_WARNINGS_AS_ERRORS = YES
GCC_TREAT_WARNINGS_AS_ERRORS = NO
SWIFT_TREAT_WARNINGS_AS_ERRORS = NO

MTL_ENABLE_DEBUG_INFO_Debug = YES
MTL_ENABLE_DEBUG_INFO_DebugWithoutUIKit = YES
Expand Down
3 changes: 1 addition & 2 deletions Sources/Sentry/Public/SentryOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -519,8 +519,7 @@ NS_SWIFT_NAME(Options)
/**
* Block used to configure the continuous profiling options.
* @warning Continuous profiling is an experimental feature and may contain bugs.
* @seealso @c SentryProfileOptions, @c SentrySDK.startProfileSession and
* @c SentrySDK.stopProfileSession .
* @seealso @c SentryProfileOptions, @c SentrySDK.startProfiler and @c SentrySDK.stopProfiler .
*/
typedef void (^SentryProfilingConfigurationBlock)(SentryProfileOptions *_Nonnull profiling);

Expand Down
54 changes: 21 additions & 33 deletions Sources/Sentry/Public/SentrySDK.h
Original file line number Diff line number Diff line change
Expand Up @@ -372,51 +372,39 @@ SENTRY_NO_INIT
/**
* Start a new continuous profiling session if one is not already running.
* @warning Continuous profiling mode is experimental and may still contain bugs.
* @warning This property is deprecated and will be removed in a future version of the SDK. See
* @c startProfileSession .
* @note Unlike trace-based profiling, continuous profiling does not take into account @c
* SentryOptions.profilesSampleRate ; a call to this method will always start a profile if one is
* not already running. This includes app launch profiles configured with @c
* SentryOptions.enableAppLaunchProfiling .
* @seealso https://docs.sentry.io/platforms/apple/guides/ios/profiling/#continuous-profiling
*/
+ (void)startProfiler;

/**
* Start a new continuous profile session.
* @warning Continuous profiling mode is experimental and may still contain bugs.
* @note Does nothing if the profiling session is sampled with respect
* @c SentryOptions.profileSessionSampleRate and the profiler is already running.
* @note Does nothing if the profile session is not sampled.
* @note Does nothing if @c SentryOptions.profileLifecycle is set to @c trace . In this scenario,
* the profiler is automatically started and stopped depending on whether there is an active sampled
* span so it is not permitted to manually start profiling.
* @note Unlike transaction-based profiling, continuous profiling does not take into account
* @c SentryOptions.profilesSampleRate or @c SentryOptions.profilesSampler . If either of those
* options are set, this method does nothing.
* @note Taking into account the above note, if @c SentryOptions.configureProfiling is not set,
* calls to this method will always start a profile if one is not already running. This includes app
* launch profiles configured with @c SentryOptions.enableAppLaunchProfiling .
* @note If neither @c SentryOptions.profilesSampleRate nor @c SentryOptions.profilesSampler are
* set, and @c SentryOptions.configureProfiling is set, this method does nothing if the profiling
* session is not sampled with respect to @c SentryOptions.profileSessionSampleRate , or if it is
* sampled but the profiler is already running.
* @note If neither @c SentryOptions.profilesSampleRate nor @c SentryOptions.profilesSampler are
* set, and @c SentryOptions.configureProfiling is set, this method does nothing if
* @c SentryOptions.profileLifecycle is set to @c trace . In this scenario, the profiler is
* automatically started and stopped depending on whether there is an active sampled span, so it is
* not permitted to manually start profiling.
* @note Profiling is automatically disabled if a thread sanitizer is attached.
* @seealso https://docs.sentry.io/platforms/apple/guides/ios/profiling/#continuous-profiling
*/
+ (void)startProfileSession;

/**
* Stop a continuous profiling session if there is one ongoing.
* @warning Continuous profiling mode is experimental and may still contain bugs.
* @warning This property is deprecated and will be removed in a future version of the SDK. See
* @c stopProfileSession .
* @seealso https://docs.sentry.io/platforms/apple/guides/ios/profiling/#continuous-profiling
*/
+ (void)stopProfiler;
+ (void)startProfiler;

/**
* Stop a continuous profiling session if there is one ongoing.
* @warning Continuous profiling mode is experimental and may still contain bugs.
* @note Does nothing if @c SentryOptions.profileLifecycle is set to @c trace .
* @note Does not immediately stop the profiler. Profiling data is uploaded at regular timed
* intervals; when the current interval completes, then the profiler stops. If a profiler session
* would be started before that interval completes, the start call is ignored; it doesn't have the
* effect of cancelling the previous stop call.
* intervals; when the current interval completes, then the profiler stops and the data gathered
* during that last interval is uploaded.
* @note If a new call to @c startProfiler that would start the profiler is made before the last
* interval completes, the profiler will continue running until another call to stop is made.
* @note Profiling is automatically disabled if a thread sanitizer is attached.
* @seealso https://docs.sentry.io/platforms/apple/guides/ios/profiling/#continuous-profiling
*/
+ (void)stopProfileSession;
+ (void)stopProfiler;
#endif // SENTRY_TARGET_PROFILING_SUPPORTED

@end
Expand Down
78 changes: 30 additions & 48 deletions Sources/Sentry/SentrySDK.m
Original file line number Diff line number Diff line change
Expand Up @@ -617,52 +617,30 @@ + (void)crash
#if SENTRY_TARGET_PROFILING_SUPPORTED
+ (void)startProfiler
{
if (![currentHub.client.options isContinuousProfilingEnabled]) {
SentryOptions *options = currentHub.client.options;
if (![options isContinuousProfilingEnabled]) {
SENTRY_LOG_WARN(
@"You must disable trace profiling by setting SentryOptions.profilesSampleRate and "
@"SentryOptions.profilesSampler to nil (which is the default initial value for both "
@"properties, so you can also just remove those lines from your configuration "
@"altogether) before attempting to start a continuous profiling session.");
@"altogether) before attempting to start a continuous profiling session. This behavior "
@"relies on deprecated options and will change in a future version.");
return;
}

[SentryContinuousProfiler start];
}

+ (void)stopProfiler
{
if (![currentHub.client.options isContinuousProfilingEnabled]) {
SENTRY_LOG_WARN(
@"You must disable trace profiling by setting SentryOptions.profilesSampleRate and "
@"SentryOptions.profilesSampler to nil (which is the default initial value for both "
@"properties, so you can also just remove those lines from your configuration "
@"altogether) before attempting to stop a continuous profiling session.");
return;
}

[SentryContinuousProfiler stop];
}

+ (void)startProfileSession
{
if (![currentHub.client.options isContinuousProfilingV2Enabled]) {
SENTRY_LOG_WARN(
@"You must initialize the SDK with continuous profiling configured before starting a "
@"profile session. See SentryProfilingOptions.");
return;
}

if (currentHub.client.options.profiling.lifecycle == SentryProfileLifecycleTrace) {
SENTRY_LOG_WARN(
@"The profiling lifecycle is set to trace, so you cannot start profile sessions "
@"manually. See SentryProfileLifecycle for more information.");
return;
}
if (options.profiling != nil) {
if (options.profiling.lifecycle == SentryProfileLifecycleTrace) {
SENTRY_LOG_WARN(
@"The profiling lifecycle is set to trace, so you cannot start profile sessions "
@"manually. See SentryProfileLifecycle for more information.");
return;
}

if (sentry_profilerSessionSampleDecision.decision != kSentrySampleDecisionYes) {
SENTRY_LOG_DEBUG(
@"The profiling session has been sampled out, no profiling will take place.");
return;
if (sentry_profilerSessionSampleDecision.decision != kSentrySampleDecisionYes) {
SENTRY_LOG_DEBUG(
@"The profiling session has been sampled out, no profiling will take place.");
return;
}
}

if ([SentryContinuousProfiler isCurrentlyProfiling]) {
Expand All @@ -673,27 +651,31 @@ + (void)startProfileSession
[SentryContinuousProfiler start];
}

+ (void)stopProfileSession
+ (void)stopProfiler
{
if (![currentHub.client.options isContinuousProfilingV2Enabled]) {
SentryOptions *options = currentHub.client.options;
if (![options isContinuousProfilingEnabled]) {
SENTRY_LOG_WARN(
@"You must initialize the SDK with continuous profiling configured before interacting"
@"with profile sessions. See SentryProfilingOptions.");
return;
}

if (![SentryContinuousProfiler isCurrentlyProfiling]) {
SENTRY_LOG_WARN(@"No profile session to stop.");
@"You must disable trace profiling by setting SentryOptions.profilesSampleRate and "
@"SentryOptions.profilesSampler to nil (which is the default initial value for both "
@"properties, so you can also just remove those lines from your configuration "
@"altogether) before attempting to stop a continuous profiling session. This behavior "
@"relies on deprecated options and will change in a future version.");
return;
}

if (currentHub.client.options.profiling.lifecycle == SentryProfileLifecycleTrace) {
if (options.profiling != nil && options.profiling.lifecycle == SentryProfileLifecycleTrace) {
SENTRY_LOG_WARN(
@"The profiling lifecycle is set to trace, so you cannot stop profile sessions "
@"manually. See SentryProfileLifecycle for more information.");
return;
}

if (![SentryContinuousProfiler isCurrentlyProfiling]) {
SENTRY_LOG_WARN(@"No profile session to stop.");
return;
}

[SentryContinuousProfiler stop];
}
#endif // SENTRY_TARGET_PROFILING_SUPPORTED
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@ import Foundation
/// - warning: Continuous profiling is an experimental feature and may still contain bugs.
/// - note: If either `SentryOptions.profilesSampleRate` or `SentryOptions.profilesSampler` are
/// set to a non-nil value such that transaction-based profiling is being used, these settings
/// will have no effect, nor will `SentrySDK.startProfileSession()` or
/// `SentrySDK.stopProfileSession()`.
/// will have no effect, nor will `SentrySDK.startProfiler()` or `SentrySDK.stopProfiler()`.
/// - note: Profiling is automatically disabled if a thread sanitizer is attached.
@objcMembers
public class SentryProfileOptions: NSObject {
/// Different modes for starting and stopping the profiler.
@objc public enum SentryProfileLifecycle: Int {
/// Profiling is controlled manually, and is independent of transactions & spans. Developers
/// must use`SentrySDK.startProfileSession()` and `SentrySDK.stopProfileSession()` to
/// manage the profile session. If the session is sampled,
/// `SentrySDK.startProfileSession()` will always start profiling.
/// must use`SentrySDK.startProfiler()` and `SentrySDK.stopProfiler()` to manage the profile
/// session. If the session is sampled, `SentrySDK.startProfiler()` will always start
/// profiling.
/// - warning: Continuous profiling is an experimental feature and may still contain bugs.
/// - note: Profiling is automatically disabled if a thread sanitizer is attached.
case manual
Expand Down Expand Up @@ -72,8 +71,8 @@ public class SentryProfileOptions: NSObject {
/// - note: `sessionSampleRate` is evaluated on the previous launch and only takes effect when
/// app start profiling activates on the next launch.
/// - note: If `lifecycle` is `manual`, profiling is started automatically on startup, but you
/// must manually call `SentrySDK.stopProfileSession()` whenever you app startup to be complete.
/// If `lifecycle` is `trace`, profiling is started automatically on startup, and will
/// must manually call `SentrySDK.stopProfiler()` whenever you app startup to be complete. If
/// `lifecycle` is `trace`, profiling is started automatically on startup, and will
/// automatically be stopped when the root span that is associated with app startup ends.
/// - note: Profiling is automatically disabled if a thread sanitizer is attached.
public var profileAppStarts: Bool = false
Expand Down
3 changes: 3 additions & 0 deletions Tests/Configuration/SentryTests.xcconfig
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ CLANG_ENABLE_OBJC_ARC = YES
CLANG_ENABLE_MODULES = YES
OTHER_CFLAGS = -Wall -Wextra
APPLICATION_EXTENSION_API_ONLY = NO

GCC_TREAT_WARNINGS_AS_ERRORS = NO
SWIFT_TREAT_WARNINGS_AS_ERRORS = NO
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,6 @@ struct LaunchProfileOptions: Equatable {
let profileAppStarts: Bool
}

///
var continuousProfileV2Options: ContinuousProfileV2Options?
}

Expand Down
Loading
Loading