Skip to content

Commit 7606482

Browse files
authoredMar 19, 2025
Merge 0d7a452 into 33196d7
2 parents 33196d7 + 0d7a452 commit 7606482

File tree

7 files changed

+84
-102
lines changed

7 files changed

+84
-102
lines changed
 

‎CHANGELOG.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,21 @@
22

33
## Unreleased
44

5+
### Features
6+
7+
- New continuous profiling configuration API (#4952)
8+
9+
> [!Important]
10+
> 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:
11+
>
12+
> - `SentryOptions.enableProfiling`
13+
> - `SentryOptions.isProfilingEnabled`
14+
> - `SentryOptions.profilesSampleRate`
15+
> - `SentryOptions.profilesSampler`
16+
> - `SentryOptions.enableLaunchProfiling`
17+
>
18+
> Additionally, note that the behavior of `SentrySDK.startProfiler()` will change once the above API 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 it's 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.
19+
520
### Fixes
621

722
- Continuous profile stop requests are cancelled by subsequent timely calls to start (#4993)
@@ -35,7 +50,6 @@
3550
### Features
3651

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

‎Samples/iOS-Swift/iOS-Swift/Profiling/ProfilingViewController.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,11 @@ class ProfilingViewController: UIViewController, UITextFieldDelegate {
108108
}
109109

110110
@IBAction func startContinuousProfiler(_ sender: Any) {
111-
SentrySDK.startProfileSession()
111+
SentrySDK.startProfiler()
112112
}
113113

114114
@IBAction func stopContinuousProfiler(_ sender: Any) {
115-
SentrySDK.stopProfileSession()
115+
SentrySDK.stopProfiler()
116116
}
117117

118118
@IBAction func viewLastProfile(_ sender: Any) {

‎Sources/Sentry/Public/SentryOptions.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -519,8 +519,7 @@ NS_SWIFT_NAME(Options)
519519
/**
520520
* Block used to configure the continuous profiling options.
521521
* @warning Continuous profiling is an experimental feature and may contain bugs.
522-
* @seealso @c SentryProfileOptions, @c SentrySDK.startProfileSession and
523-
* @c SentrySDK.stopProfileSession .
522+
* @seealso @c SentryProfileOptions, @c SentrySDK.startProfiler and @c SentrySDK.stopProfiler .
524523
*/
525524
typedef void (^SentryProfilingConfigurationBlock)(SentryProfileOptions *_Nonnull profiling);
526525

‎Sources/Sentry/Public/SentrySDK.h

+21-33
Original file line numberDiff line numberDiff line change
@@ -372,51 +372,39 @@ SENTRY_NO_INIT
372372
/**
373373
* Start a new continuous profiling session if one is not already running.
374374
* @warning Continuous profiling mode is experimental and may still contain bugs.
375-
* @warning This property is deprecated and will be removed in a future version of the SDK. See
376-
* @c startProfileSession .
377-
* @note Unlike trace-based profiling, continuous profiling does not take into account @c
378-
* SentryOptions.profilesSampleRate ; a call to this method will always start a profile if one is
379-
* not already running. This includes app launch profiles configured with @c
380-
* SentryOptions.enableAppLaunchProfiling .
381-
* @seealso https://docs.sentry.io/platforms/apple/guides/ios/profiling/#continuous-profiling
382-
*/
383-
+ (void)startProfiler;
384-
385-
/**
386-
* Start a new continuous profile session.
387-
* @warning Continuous profiling mode is experimental and may still contain bugs.
388-
* @note Does nothing if the profiling session is sampled with respect
389-
* @c SentryOptions.profileSessionSampleRate and the profiler is already running.
390-
* @note Does nothing if the profile session is not sampled.
391-
* @note Does nothing if @c SentryOptions.profileLifecycle is set to @c trace . In this scenario,
392-
* the profiler is automatically started and stopped depending on whether there is an active sampled
393-
* span so it is not permitted to manually start profiling.
375+
* @note Unlike transaction-based profiling, continuous profiling does not take into account
376+
* @c SentryOptions.profilesSampleRate or @c SentryOptions.profilesSampler . If either of those
377+
* options are set, this method does nothing.
378+
* @note Taking into account the above note, if @c SentryOptions.configureProfiling is not set,
379+
* calls to this method will always start a profile if one is not already running. This includes app
380+
* launch profiles configured with @c SentryOptions.enableAppLaunchProfiling .
381+
* @note If neither @c SentryOptions.profilesSampleRate nor @c SentryOptions.profilesSampler are
382+
* set, and @c SentryOptions.configureProfiling is set, this method does nothing if the profiling
383+
* session is not sampled with respect to @c SentryOptions.profileSessionSampleRate , or if it is
384+
* sampled but the profiler is already running.
385+
* @note If neither @c SentryOptions.profilesSampleRate nor @c SentryOptions.profilesSampler are
386+
* set, and @c SentryOptions.configureProfiling is set, this method does nothing if
387+
* @c SentryOptions.profileLifecycle is set to @c trace . In this scenario, the profiler is
388+
* automatically started and stopped depending on whether there is an active sampled span, so it is
389+
* not permitted to manually start profiling.
394390
* @note Profiling is automatically disabled if a thread sanitizer is attached.
395391
* @seealso https://docs.sentry.io/platforms/apple/guides/ios/profiling/#continuous-profiling
396392
*/
397-
+ (void)startProfileSession;
398-
399-
/**
400-
* Stop a continuous profiling session if there is one ongoing.
401-
* @warning Continuous profiling mode is experimental and may still contain bugs.
402-
* @warning This property is deprecated and will be removed in a future version of the SDK. See
403-
* @c stopProfileSession .
404-
* @seealso https://docs.sentry.io/platforms/apple/guides/ios/profiling/#continuous-profiling
405-
*/
406-
+ (void)stopProfiler;
393+
+ (void)startProfiler;
407394

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

422410
@end

‎Sources/Sentry/SentrySDK.m

+30-48
Original file line numberDiff line numberDiff line change
@@ -617,52 +617,30 @@ + (void)crash
617617
#if SENTRY_TARGET_PROFILING_SUPPORTED
618618
+ (void)startProfiler
619619
{
620-
if (![currentHub.client.options isContinuousProfilingEnabled]) {
620+
SentryOptions *options = currentHub.client.options;
621+
if (![options isContinuousProfilingEnabled]) {
621622
SENTRY_LOG_WARN(
622623
@"You must disable trace profiling by setting SentryOptions.profilesSampleRate and "
623624
@"SentryOptions.profilesSampler to nil (which is the default initial value for both "
624625
@"properties, so you can also just remove those lines from your configuration "
625-
@"altogether) before attempting to start a continuous profiling session.");
626+
@"altogether) before attempting to start a continuous profiling session. This behavior "
627+
@"relies on deprecated options and will change in a future version.");
626628
return;
627629
}
628630

629-
[SentryContinuousProfiler start];
630-
}
631-
632-
+ (void)stopProfiler
633-
{
634-
if (![currentHub.client.options isContinuousProfilingEnabled]) {
635-
SENTRY_LOG_WARN(
636-
@"You must disable trace profiling by setting SentryOptions.profilesSampleRate and "
637-
@"SentryOptions.profilesSampler to nil (which is the default initial value for both "
638-
@"properties, so you can also just remove those lines from your configuration "
639-
@"altogether) before attempting to stop a continuous profiling session.");
640-
return;
641-
}
642-
643-
[SentryContinuousProfiler stop];
644-
}
645-
646-
+ (void)startProfileSession
647-
{
648-
if (![currentHub.client.options isContinuousProfilingV2Enabled]) {
649-
SENTRY_LOG_WARN(
650-
@"You must initialize the SDK with continuous profiling configured before starting a "
651-
@"profile session. See SentryProfilingOptions.");
652-
return;
653-
}
654-
655-
if (currentHub.client.options.profiling.lifecycle == SentryProfileLifecycleTrace) {
656-
SENTRY_LOG_WARN(
657-
@"The profiling lifecycle is set to trace, so you cannot start profile sessions "
658-
@"manually. See SentryProfileLifecycle for more information.");
659-
return;
660-
}
631+
if (options.profiling != nil) {
632+
if (options.profiling.lifecycle == SentryProfileLifecycleTrace) {
633+
SENTRY_LOG_WARN(
634+
@"The profiling lifecycle is set to trace, so you cannot start profile sessions "
635+
@"manually. See SentryProfileLifecycle for more information.");
636+
return;
637+
}
661638

662-
if (sentry_profilerSessionSampleDecision.decision != kSentrySampleDecisionYes) {
663-
SENTRY_LOG_DEBUG(
664-
@"The profiling session has been sampled out, no profiling will take place.");
665-
return;
639+
if (sentry_profilerSessionSampleDecision.decision != kSentrySampleDecisionYes) {
640+
SENTRY_LOG_DEBUG(
641+
@"The profiling session has been sampled out, no profiling will take place.");
642+
return;
643+
}
666644
}
667645

668646
if ([SentryContinuousProfiler isCurrentlyProfiling]) {
@@ -673,27 +651,31 @@ + (void)startProfileSession
673651
[SentryContinuousProfiler start];
674652
}
675653

676-
+ (void)stopProfileSession
654+
+ (void)stopProfiler
677655
{
678-
if (![currentHub.client.options isContinuousProfilingV2Enabled]) {
656+
SentryOptions *options = currentHub.client.options;
657+
if (![options isContinuousProfilingEnabled]) {
679658
SENTRY_LOG_WARN(
680-
@"You must initialize the SDK with continuous profiling configured before interacting"
681-
@"with profile sessions. See SentryProfilingOptions.");
682-
return;
683-
}
684-
685-
if (![SentryContinuousProfiler isCurrentlyProfiling]) {
686-
SENTRY_LOG_WARN(@"No profile session to stop.");
659+
@"You must disable trace profiling by setting SentryOptions.profilesSampleRate and "
660+
@"SentryOptions.profilesSampler to nil (which is the default initial value for both "
661+
@"properties, so you can also just remove those lines from your configuration "
662+
@"altogether) before attempting to stop a continuous profiling session. This behavior "
663+
@"relies on deprecated options and will change in a future version.");
687664
return;
688665
}
689666

690-
if (currentHub.client.options.profiling.lifecycle == SentryProfileLifecycleTrace) {
667+
if (options.profiling != nil && options.profiling.lifecycle == SentryProfileLifecycleTrace) {
691668
SENTRY_LOG_WARN(
692669
@"The profiling lifecycle is set to trace, so you cannot stop profile sessions "
693670
@"manually. See SentryProfileLifecycle for more information.");
694671
return;
695672
}
696673

674+
if (![SentryContinuousProfiler isCurrentlyProfiling]) {
675+
SENTRY_LOG_WARN(@"No profile session to stop.");
676+
return;
677+
}
678+
697679
[SentryContinuousProfiler stop];
698680
}
699681
#endif // SENTRY_TARGET_PROFILING_SUPPORTED

‎Sources/Swift/Integrations/Performance/SentryProfileOptions.swift

+6-7
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,16 @@ import UIKit
99
/// - warning: Continuous profiling is an experimental feature and may still contain bugs.
1010
/// - note: If either `SentryOptions.profilesSampleRate` or `SentryOptions.profilesSampler` are
1111
/// set to a non-nil value such that transaction-based profiling is being used, these settings
12-
/// will have no effect, nor will `SentrySDK.startProfileSession()` or
13-
/// `SentrySDK.stopProfileSession()`.
12+
/// will have no effect, nor will `SentrySDK.startProfiler()` or `SentrySDK.stopProfiler()`.
1413
/// - note: Profiling is automatically disabled if a thread sanitizer is attached.
1514
@objcMembers
1615
public class SentryProfileOptions: NSObject {
1716
/// Different modes for starting and stopping the profiler.
1817
@objc public enum SentryProfileLifecycle: Int {
1918
/// Profiling is controlled manually, and is independent of transactions & spans. Developers
20-
/// must use`SentrySDK.startProfileSession()` and `SentrySDK.stopProfileSession()` to
21-
/// manage the profile session. If the session is sampled,
22-
/// `SentrySDK.startProfileSession()` will always start profiling.
19+
/// must use`SentrySDK.startProfiler()` and `SentrySDK.stopProfiler()` to manage the profile
20+
/// session. If the session is sampled, `SentrySDK.startProfiler()` will always start
21+
/// profiling.
2322
/// - warning: Continuous profiling is an experimental feature and may still contain bugs.
2423
/// - note: Profiling is automatically disabled if a thread sanitizer is attached.
2524
case manual
@@ -71,8 +70,8 @@ public class SentryProfileOptions: NSObject {
7170
/// - note: `sessionSampleRate` is evaluated on the previous launch and only takes effect when
7271
/// app start profiling activates on the next launch.
7372
/// - note: If `lifecycle` is `manual`, profiling is started automatically on startup, but you
74-
/// must manually call `SentrySDK.stopProfileSession()` whenever you app startup to be complete.
75-
/// If `lifecycle` is `trace`, profiling is started automatically on startup, and will
73+
/// must manually call `SentrySDK.stopProfiler()` whenever you app startup to be complete. If
74+
/// `lifecycle` is `trace`, profiling is started automatically on startup, and will
7675
/// automatically be stopped when the root span that is associated with app startup ends.
7776
/// - note: Profiling is automatically disabled if a thread sanitizer is attached.
7877
public var profileAppStarts: Bool = false

‎Tests/SentryProfilerTests/SentryProfilingPublicAPITests.swift

+9-9
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ extension SentryProfilingPublicAPITests {
127127
givenSdkWithHub()
128128

129129
// Act
130-
SentrySDK.startProfileSession()
130+
SentrySDK.startProfiler()
131131

132132
// Assert
133133
XCTAssert(SentryContinuousProfiler.isCurrentlyProfiling())
@@ -147,7 +147,7 @@ extension SentryProfilingPublicAPITests {
147147
givenSdkWithHub()
148148

149149
// Act
150-
SentrySDK.startProfileSession()
150+
SentrySDK.startProfiler()
151151

152152
// Assert
153153
XCTAssertFalse(SentryContinuousProfiler.isCurrentlyProfiling())
@@ -157,7 +157,7 @@ extension SentryProfilingPublicAPITests {
157157
// Arrange - do nothing, simulating actions before starting sdk
158158

159159
// Act
160-
SentrySDK.startProfileSession()
160+
SentrySDK.startProfiler()
161161

162162
// Assert
163163
XCTAssertFalse(SentryContinuousProfiler.isCurrentlyProfiling())
@@ -169,7 +169,7 @@ extension SentryProfilingPublicAPITests {
169169

170170
// Act
171171
SentrySDK.close()
172-
SentrySDK.startProfileSession()
172+
SentrySDK.startProfiler()
173173

174174
// Assert
175175
XCTAssertFalse(SentryContinuousProfiler.isCurrentlyProfiling())
@@ -181,7 +181,7 @@ extension SentryProfilingPublicAPITests {
181181
givenSdkWithHub()
182182

183183
// Act
184-
SentrySDK.startProfileSession()
184+
SentrySDK.startProfiler()
185185

186186
// Assert
187187
XCTAssertFalse(SentryContinuousProfiler.isCurrentlyProfiling())
@@ -195,7 +195,7 @@ extension SentryProfilingPublicAPITests {
195195
givenSdkWithHub()
196196

197197
// Act
198-
SentrySDK.startProfileSession()
198+
SentrySDK.startProfiler()
199199

200200
// Assert
201201
XCTAssertFalse(SentryContinuousProfiler.isCurrentlyProfiling())
@@ -311,7 +311,7 @@ extension SentryProfilingPublicAPITests {
311311
givenSdkWithHub()
312312

313313
// Act
314-
SentrySDK.startProfileSession()
314+
SentrySDK.startProfiler()
315315

316316
// Assert
317317
XCTAssert(SentryContinuousProfiler.isCurrentlyProfiling())
@@ -325,7 +325,7 @@ extension SentryProfilingPublicAPITests {
325325
givenSdkWithHub()
326326

327327
// Act
328-
SentrySDK.startProfileSession()
328+
SentrySDK.startProfiler()
329329

330330
// Assert
331331
XCTAssertFalse(SentryContinuousProfiler.isCurrentlyProfiling())
@@ -450,7 +450,7 @@ private extension SentryProfilingPublicAPITests {
450450
}
451451

452452
func stopProfilerV2() throws {
453-
SentrySDK.stopProfileSession()
453+
SentrySDK.stopProfiler()
454454
fixture.currentDate.advance(by: 60)
455455
try fixture.timerFactory.check()
456456
}

0 commit comments

Comments
 (0)