Skip to content

Commit

Permalink
Merge 8a829a6 into d0c8e78
Browse files Browse the repository at this point in the history
  • Loading branch information
armcknight committed May 14, 2024
2 parents d0c8e78 + 8a829a6 commit db1c44f
Show file tree
Hide file tree
Showing 14 changed files with 206 additions and 198 deletions.
12 changes: 7 additions & 5 deletions Sentry.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -631,7 +631,6 @@
7DC8310A2398283C0043DD9A /* SentryCrashIntegration.h in Headers */ = {isa = PBXBuildFile; fileRef = 7DC831082398283C0043DD9A /* SentryCrashIntegration.h */; };
7DC8310C2398283C0043DD9A /* SentryCrashIntegration.m in Sources */ = {isa = PBXBuildFile; fileRef = 7DC831092398283C0043DD9A /* SentryCrashIntegration.m */; };
840A11122B61E27500650D02 /* SentrySamplerDecision.m in Sources */ = {isa = PBXBuildFile; fileRef = 840A11102B61E27500650D02 /* SentrySamplerDecision.m */; };
840A11132B61FE5800650D02 /* SentryAppLaunchProfilingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 840A11092B5F47F700650D02 /* SentryAppLaunchProfilingTests.m */; };
84281C432A578E5600EE88F2 /* SentryProfilerState.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84281C422A578E5600EE88F2 /* SentryProfilerState.mm */; };
84281C462A57905700EE88F2 /* SentrySample.h in Headers */ = {isa = PBXBuildFile; fileRef = 84281C442A57905700EE88F2 /* SentrySample.h */; };
84281C472A57905700EE88F2 /* SentrySample.m in Sources */ = {isa = PBXBuildFile; fileRef = 84281C452A57905700EE88F2 /* SentrySample.m */; };
Expand Down Expand Up @@ -681,6 +680,7 @@
848A451D2BBF9504006AAAEC /* SentryProfilerTestHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 848A451C2BBF9504006AAAEC /* SentryProfilerTestHelpers.m */; };
848A451E2BBF9504006AAAEC /* SentryProfilerTestHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 848A451B2BBF9504006AAAEC /* SentryProfilerTestHelpers.h */; };
849AC40029E0C1FF00889C16 /* SentryFormatterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 849AC3FF29E0C1FF00889C16 /* SentryFormatterTests.swift */; };
84A305492BC7328400D84283 /* SentryAppLaunchProfilingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A305472BC72A0A00D84283 /* SentryAppLaunchProfilingTests.swift */; };
84A305572BC9EF8C00D84283 /* SentryLegacyProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 84A305552BC9EF8C00D84283 /* SentryLegacyProfiler.h */; };
84A305582BC9EF8C00D84283 /* SentryLegacyProfiler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 84A305562BC9EF8C00D84283 /* SentryLegacyProfiler.mm */; };
84A5D75B29D5170700388BFA /* TimeInterval+Sentry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84A5D75A29D5170700388BFA /* TimeInterval+Sentry.swift */; };
Expand Down Expand Up @@ -1644,7 +1644,6 @@
7DC27EC423997EB7006998B5 /* SentryAutoBreadcrumbTrackingIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryAutoBreadcrumbTrackingIntegration.m; sourceTree = "<group>"; };
7DC831082398283C0043DD9A /* SentryCrashIntegration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryCrashIntegration.h; path = include/SentryCrashIntegration.h; sourceTree = "<group>"; };
7DC831092398283C0043DD9A /* SentryCrashIntegration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryCrashIntegration.m; sourceTree = "<group>"; };
840A11092B5F47F700650D02 /* SentryAppLaunchProfilingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentryAppLaunchProfilingTests.m; sourceTree = "<group>"; };
840A11102B61E27500650D02 /* SentrySamplerDecision.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SentrySamplerDecision.m; sourceTree = "<group>"; };
840A11142B62041600650D02 /* SentryLaunchProfiling+Tests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryLaunchProfiling+Tests.h"; sourceTree = "<group>"; };
840B7EEA2BBF2ABA008B8120 /* .slather.yml */ = {isa = PBXFileReference; lastKnownFileType = text.yaml; path = .slather.yml; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1721,6 +1720,7 @@
849472822971C2CD002603DE /* SentryNSProcessInfoWrapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryNSProcessInfoWrapperTests.swift; sourceTree = "<group>"; };
849472842971C41A002603DE /* SentryNSTimerFactoryTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryNSTimerFactoryTest.swift; sourceTree = "<group>"; };
849AC3FF29E0C1FF00889C16 /* SentryFormatterTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SentryFormatterTests.swift; sourceTree = "<group>"; };
84A305472BC72A0A00D84283 /* SentryAppLaunchProfilingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SentryAppLaunchProfilingTests.swift; sourceTree = "<group>"; };
84A305552BC9EF8C00D84283 /* SentryLegacyProfiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SentryLegacyProfiler.h; path = ../include/SentryLegacyProfiler.h; sourceTree = "<group>"; };
84A305562BC9EF8C00D84283 /* SentryLegacyProfiler.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = SentryLegacyProfiler.mm; sourceTree = "<group>"; };
84A305592BC9FD1600D84283 /* SentryLegacyProfiler+Test.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SentryLegacyProfiler+Test.h"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2460,7 +2460,6 @@
7B569DFE2590EEF600B653FC /* SentryScope+Equality.h */,
7B569E052590F04700B653FC /* SentryScope+Properties.h */,
7B9421C4260CA393001F9349 /* SentrySDK+Tests.h */,
840A11142B62041600650D02 /* SentryLaunchProfiling+Tests.h */,
8431D4572BE175A1009EAEC1 /* SentryContinuousProfiler+Test.h */,
639889D21EDF06C100EA7442 /* SentryTests-Bridging-Header.h */,
63B819131EC352A7002FDF4C /* SentryInterfacesTests.m */,
Expand Down Expand Up @@ -3409,7 +3408,7 @@
035E73CB27D575B3005EEB11 /* SentrySamplingProfilerTests.mm */,
035E73CD27D5790A005EEB11 /* SentryThreadMetadataCacheTests.mm */,
03F9D37B2819A65C00602916 /* SentryProfilerTests.mm */,
840A11092B5F47F700650D02 /* SentryAppLaunchProfilingTests.m */,
84A305472BC72A0A00D84283 /* SentryAppLaunchProfilingTests.swift */,
8419C0C328C1889D001C8259 /* SentryLegacyProfilerTests.swift */,
8446F5182BE172290040D57E /* SentryContinuousProfilerTests.swift */,
8431D4522BE1741E009EAEC1 /* SentryProfileTestFixture.swift */,
Expand All @@ -3431,6 +3430,7 @@
8431F00B29B284F200D8DC56 /* SentryTestUtils */ = {
isa = PBXGroup;
children = (
840A11142B62041600650D02 /* SentryLaunchProfiling+Tests.h */,
7BD47B4C268F0B080076A663 /* ClearTestState.swift */,
7B18DE4328D9F8F6004845C6 /* TestNSNotificationCenterWrapper.swift */,
84AC61D829F7643B009EEF61 /* TestDispatchFactory.swift */,
Expand Down Expand Up @@ -4228,6 +4228,8 @@
8431EED229B27B1100D8DC56 /* PBXTargetDependency */,
);
name = SentryProfilerTests;
packageProductDependencies = (
);
productName = "Tests-iOS";
productReference = 8431EFD929B27B1100D8DC56 /* SentryProfilerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
Expand Down Expand Up @@ -4961,8 +4963,8 @@
8431EFE129B27B5300D8DC56 /* SentryThreadMetadataCacheTests.mm in Sources */,
8431EFE029B27B5300D8DC56 /* SentryBacktraceTests.mm in Sources */,
8431EFDF29B27B5300D8DC56 /* SentryThreadHandleTests.mm in Sources */,
840A11132B61FE5800650D02 /* SentryAppLaunchProfilingTests.m in Sources */,
8431EFE829B27BAD00D8DC56 /* SentrySystemWrapperTests.swift in Sources */,
84A305492BC7328400D84283 /* SentryAppLaunchProfilingTests.swift in Sources */,
8431EFE529B27BAD00D8DC56 /* SentryNSProcessInfoWrapperTests.swift in Sources */,
8431EFDE29B27B5300D8DC56 /* SentryLegacyProfilerTests.swift in Sources */,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ SENTRY_EXTERN NSString *const kSentryLaunchProfileConfigKeyProfilesSampleRate;

SentryLaunchProfileConfig sentry_shouldProfileNextLaunch(SentryOptions *options);

/**
* `sentry_shouldProfileNextLaunch` cannot be exposed to Swift tests because its return type is not
* expressible in Swift. This wraps it and only returns the `BOOL shouldProfile` value in the
* struct.
*/
BOOL sentry_willProfileNextLaunch(SentryOptions *options);

SentryTransactionContext *sentry_context(NSNumber *tracesRate);

NS_ASSUME_NONNULL_END
Expand Down
63 changes: 48 additions & 15 deletions Sources/Sentry/Profiling/SentryLaunchProfiling.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

#if SENTRY_TARGET_PROFILING_SUPPORTED

# import "SentryContinuousProfiler.h"
# import "SentryDependencyContainer.h"
# import "SentryDispatchQueueWrapper.h"
# import "SentryFileManager.h"
# import "SentryInternalDefines.h"
# import "SentryLaunchProfiling.h"
# import "SentryLog.h"
# import "SentryOptions.h"
# import "SentryOptions+Private.h"
# import "SentryProfiler+Private.h"
# import "SentryRandom.h"
# import "SentrySamplerDecision.h"
Expand All @@ -23,6 +24,12 @@

NS_ASSUME_NONNULL_BEGIN

BOOL isProfilingAppLaunch;
NSString *const kSentryLaunchProfileConfigKeyTracesSampleRate = @"traces";
NSString *const kSentryLaunchProfileConfigKeyProfilesSampleRate = @"profiles";
NSString *const kSentryLaunchProfileConfigKeyContinuousProfiling = @"continuous-profiling";
static SentryTracer *_Nullable launchTracer;

# pragma mark - Private

static SentryTracer *_Nullable sentry_launchTracer;
Expand All @@ -41,16 +48,18 @@

typedef struct {
BOOL shouldProfile;
/** Only needed for legacy launch profiling; unused with continuous profiling. */
SentrySamplerDecision *_Nullable tracesDecision;
SentrySamplerDecision *_Nullable profilesDecision;
} SentryLaunchProfileConfig;

NSString *const kSentryLaunchProfileConfigKeyTracesSampleRate = @"traces";
NSString *const kSentryLaunchProfileConfigKeyProfilesSampleRate = @"profiles";

SentryLaunchProfileConfig
sentry_shouldProfileNextLaunch(SentryOptions *options)
{
if (options.enableContinuousProfiling) {
return (SentryLaunchProfileConfig) { YES, nil, nil };
}

BOOL shouldProfileNextLaunch = options.enableAppLaunchProfiling && options.enableTracing;
if (!shouldProfileNextLaunch) {
SENTRY_LOG_DEBUG(@"Won't profile next launch due to specified options configuration: "
Expand All @@ -74,11 +83,11 @@
SentrySamplerDecision *profilesSamplerDecision
= sentry_sampleTraceProfile(context, tracesSamplerDecision, options);
if (profilesSamplerDecision.decision != kSentrySampleDecisionYes) {
SENTRY_LOG_DEBUG(@"Sampling out the launch profile.");
SENTRY_LOG_DEBUG(@"Sampling out the launch legacy profile.");
return (SentryLaunchProfileConfig) { NO, nil, nil };
}

SENTRY_LOG_DEBUG(@"Will profile the next launch.");
SENTRY_LOG_DEBUG(@"Will start legacy profile next launch.");
return (SentryLaunchProfileConfig) { YES, tracesSamplerDecision, profilesSamplerDecision };
}

Expand All @@ -95,6 +104,16 @@
return context;
}

# pragma mark - Testing only

# if defined(TEST) || defined(TESTCI) || defined(DEBUG)
BOOL
sentry_willProfileNextLaunch(SentryOptions *options)
{
return sentry_shouldProfileNextLaunch(options).shouldProfile;
}
# endif // defined(TEST) || defined(TESTCI) || defined(DEBUG)

# pragma mark - Public

BOOL sentry_isTracingAppLaunch;
Expand All @@ -111,8 +130,12 @@

NSMutableDictionary<NSString *, NSNumber *> *configDict =
[NSMutableDictionary<NSString *, NSNumber *> dictionary];
configDict[kSentryLaunchProfileConfigKeyTracesSampleRate]
= config.tracesDecision.sampleRate;
if (options.enableContinuousProfiling) {
configDict[kSentryLaunchProfileConfigKeyContinuousProfiling] = @YES;
} else {
configDict[kSentryLaunchProfileConfigKeyTracesSampleRate]
= config.tracesDecision.sampleRate;
}
configDict[kSentryLaunchProfileConfigKeyProfilesSampleRate]
= config.profilesDecision.sampleRate;
writeAppLaunchProfilingConfigFile(configDict);
Expand All @@ -122,7 +145,6 @@
void
sentry_startLaunchProfile(void)
{

static dispatch_once_t onceToken;
// this function is called from SentryTracer.load but in the future we may expose access
// directly to customers, and we'll want to ensure it only runs once. dispatch_once is an
Expand All @@ -140,12 +162,23 @@
[SentryLog configure:YES diagnosticLevel:kSentryLevelDebug];
# endif // defined(DEBUG)

NSDictionary<NSString *, NSNumber *> *rates = appLaunchProfileConfiguration();
NSNumber *profilesRate = rates[kSentryLaunchProfileConfigKeyProfilesSampleRate];
NSNumber *tracesRate = rates[kSentryLaunchProfileConfigKeyTracesSampleRate];
if (profilesRate == nil || tracesRate == nil) {
SENTRY_LOG_DEBUG(
@"Received a nil configured launch sample rate, will not trace or profile.");
NSDictionary<NSString *, NSNumber *> *launchConfig = appLaunchProfileConfiguration();
NSNumber *profilesRate = launchConfig[kSentryLaunchProfileConfigKeyProfilesSampleRate];
if ([launchConfig[kSentryLaunchProfileConfigKeyContinuousProfiling] boolValue]) {
if (profilesRate == nil) {
SENTRY_LOG_DEBUG(@"Received a nil configured launch profile sample rate, will not "
@"start continuous profiler for launch.");
return;
}

[SentryContinuousProfiler start];
return;
}

NSNumber *tracesRate = launchConfig[kSentryLaunchProfileConfigKeyTracesSampleRate];
if (tracesRate == nil) {
SENTRY_LOG_DEBUG(@"Received a nil configured launch trace sample rate, will not start "
@"a profiled launch trace.");
return;
}

Expand Down
8 changes: 4 additions & 4 deletions Sources/Sentry/SentryOptions.m
Original file line number Diff line number Diff line change
Expand Up @@ -561,15 +561,15 @@ - (void)setSampleRate:(NSNumber *)sampleRate
{
if (sampleRate == nil) {
_sampleRate = nil;
} else if (isValidSampleRate(sampleRate)) {
} else if (sentry_isValidSampleRate(sampleRate)) {
_sampleRate = sampleRate;
} else {
_sampleRate = SENTRY_DEFAULT_SAMPLE_RATE;
}
}

BOOL
isValidSampleRate(NSNumber *sampleRate)
sentry_isValidSampleRate(NSNumber *sampleRate)
{
double rate = [sampleRate doubleValue];
return rate >= 0 && rate <= 1.0;
Expand All @@ -592,7 +592,7 @@ - (void)setTracesSampleRate:(NSNumber *)tracesSampleRate
{
if (tracesSampleRate == nil) {
_tracesSampleRate = nil;
} else if (isValidSampleRate(tracesSampleRate)) {
} else if (sentry_isValidSampleRate(tracesSampleRate)) {
_tracesSampleRate = tracesSampleRate;
if (!_enableTracingManual) {
_enableTracing = YES;
Expand Down Expand Up @@ -622,7 +622,7 @@ - (void)setProfilesSampleRate:(NSNumber *)profilesSampleRate
{
if (profilesSampleRate == nil) {
_profilesSampleRate = nil;
} else if (isValidSampleRate(profilesSampleRate)) {
} else if (sentry_isValidSampleRate(profilesSampleRate)) {
_profilesSampleRate = profilesSampleRate;
} else {
_profilesSampleRate = SENTRY_DEFAULT_PROFILES_SAMPLE_RATE;
Expand Down
24 changes: 12 additions & 12 deletions Sources/Sentry/SentrySampling.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@
* @return A sample rate if the specified sampler callback was defined on @c SentryOptions and
* returned a valid value, @c nil otherwise.
*/
NSNumber *_Nullable samplerCallbackRate(SentryTracesSamplerCallback _Nullable callback,
NSNumber *_Nullable _sentry_samplerCallbackRate(SentryTracesSamplerCallback _Nullable callback,
SentrySamplingContext *context, NSNumber *defaultSampleRate)
{
if (callback == nil) {
return nil;
}

NSNumber *callbackRate = callback(context);
if (!isValidSampleRate(callbackRate)) {
if (!sentry_isValidSampleRate(callbackRate)) {
return defaultSampleRate;
}

return callbackRate;
}

SentrySamplerDecision *
calcSample(NSNumber *rate)
_sentry_calcSample(NSNumber *rate)
{
double random = [SentryDependencyContainer.sharedInstance.random nextNumber];
SentrySampleDecision decision
Expand All @@ -42,14 +42,14 @@
}

SentrySamplerDecision *
calcSampleFromNumericalRate(NSNumber *rate)
_sentry_calcSampleFromNumericalRate(NSNumber *rate)
{
if (rate == nil) {
return [[SentrySamplerDecision alloc] initWithDecision:kSentrySampleDecisionNo
forSampleRate:nil];
}

return calcSample(rate);
return _sentry_calcSample(rate);
}

#pragma mark - Public
Expand All @@ -64,10 +64,10 @@
forSampleRate:context.transactionContext.sampleRate];
}

NSNumber *callbackRate
= samplerCallbackRate(options.tracesSampler, context, SENTRY_DEFAULT_TRACES_SAMPLE_RATE);
NSNumber *callbackRate = _sentry_samplerCallbackRate(
options.tracesSampler, context, SENTRY_DEFAULT_TRACES_SAMPLE_RATE);
if (callbackRate != nil) {
return calcSample(callbackRate);
return _sentry_calcSample(callbackRate);
}

// check the _parent_ transaction's sampling decision, if any
Expand All @@ -77,7 +77,7 @@
forSampleRate:context.transactionContext.sampleRate];
}

return calcSampleFromNumericalRate(options.tracesSampleRate);
return _sentry_calcSampleFromNumericalRate(options.tracesSampleRate);
}

#if SENTRY_TARGET_PROFILING_SUPPORTED
Expand All @@ -103,13 +103,13 @@
}
# pragma clang diagnostic pop

NSNumber *callbackRate = samplerCallbackRate(
NSNumber *callbackRate = _sentry_samplerCallbackRate(
options.profilesSampler, context, SENTRY_DEFAULT_PROFILES_SAMPLE_RATE);
if (callbackRate != nil) {
return calcSample(callbackRate);
return _sentry_calcSample(callbackRate);
}

return calcSampleFromNumericalRate(options.profilesSampleRate);
return _sentry_calcSampleFromNumericalRate(options.profilesSampleRate);
}

#endif // SENTRY_TARGET_PROFILING_SUPPORTED
Expand Down
8 changes: 8 additions & 0 deletions Sources/Sentry/SentryTimeToDisplayTracker.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
# import "SentryFramesTracker.h"
# import "SentryLog.h"
# import "SentryMeasurementValue.h"
# import "SentryOptions+Private.h"
# import "SentryProfilingConditionals.h"
# import "SentrySDK+Private.h"
# import "SentrySpan.h"
# import "SentrySpanContext.h"
# import "SentrySpanId.h"
Expand Down Expand Up @@ -140,6 +142,9 @@ - (void)framesTrackerHasNewFrame:(NSDate *)newFrameDate
if (!_waitForFullDisplay) {
[SentryDependencyContainer.sharedInstance.framesTracker removeListener:self];
# if SENTRY_TARGET_PROFILING_SUPPORTED
if (SentrySDK.options.enableContinuousProfiling) {
return;
}
sentry_stopAndDiscardLaunchProfileTracer();
# endif // SENTRY_TARGET_PROFILING_SUPPORTED
}
Expand All @@ -150,6 +155,9 @@ - (void)framesTrackerHasNewFrame:(NSDate *)newFrameDate
self.fullDisplaySpan.timestamp = newFrameDate;
[self.fullDisplaySpan finish];
# if SENTRY_TARGET_PROFILING_SUPPORTED
if (SentrySDK.options.enableContinuousProfiling) {
return;
}
sentry_stopAndDiscardLaunchProfileTracer();
# endif // SENTRY_TARGET_PROFILING_SUPPORTED
}
Expand Down
7 changes: 0 additions & 7 deletions Sources/Sentry/SentryTracer.m
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,6 @@ @implementation SentryTracer {
static NSObject *appStartMeasurementLock;
static BOOL appStartMeasurementRead;

#if SENTRY_TARGET_PROFILING_SUPPORTED
+ (void)load
{
sentry_startLaunchProfile();
}
#endif // SENTRY_TARGET_PROFILING_SUPPORTED

+ (void)initialize
{
if (self == [SentryTracer class]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
@class SentrySystemWrapper;
@class SentryThreadWrapper;
@class SentryThreadInspector;
@class SentryOptions;
@protocol SentryRandom;

#if SENTRY_HAS_METRIC_KIT
Expand Down

0 comments on commit db1c44f

Please sign in to comment.