|
2 | 2 | #if SENTRY_TARGET_PROFILING_SUPPORTED |
3 | 3 |
|
4 | 4 | # import "SentryClient.h" |
| 5 | +# import "SentryDependencyContainerSwiftHelper.h" |
| 6 | +# import "SentryHub.h" |
| 7 | +# import "SentryInternalDefines.h" |
| 8 | +# import "SentryLaunchProfiling.h" |
5 | 9 | # import "SentryLogC.h" |
| 10 | +# import "SentryProfileConfiguration.h" |
6 | 11 | # import "SentryProfiler+Private.h" |
| 12 | +# import "SentrySDK+Private.h" |
7 | 13 | # import "SentrySamplerDecision.h" |
8 | 14 | # import "SentrySwift.h" |
9 | 15 |
|
|
158 | 164 | } |
159 | 165 |
|
160 | 166 | # if SENTRY_HAS_UIKIT |
| 167 | +BOOL |
| 168 | +sentry_appHangsDisabled(void) |
| 169 | +{ |
| 170 | + return [[[[SentrySDKInternal currentHub] getClient] options] isAppHangTrackingDisabled]; |
| 171 | +} |
| 172 | +BOOL |
| 173 | +sentry_autoPerformanceTracingDisabled(void) |
| 174 | +{ |
| 175 | + return ![[[[SentrySDKInternal currentHub] getClient] options] enableAutoPerformanceTracing]; |
| 176 | +} |
161 | 177 | void |
162 | 178 | sentry_startFramesTracker(void) |
163 | 179 | { |
|
183 | 199 | } |
184 | 200 | # endif // SENTRY_HAS_UIKIT |
185 | 201 | #endif // SENTRY_TARGET_PROFILING_SUPPORTED |
| 202 | + |
| 203 | +void |
| 204 | +sentry_configureContinuousProfiling(SentryOptions *options) |
| 205 | +{ |
| 206 | + if (options.configureProfiling == nil) { |
| 207 | + SENTRY_LOG_DEBUG(@"Continuous profiling V2 configuration not set by SDK consumer, nothing " |
| 208 | + @"to do here."); |
| 209 | + return; |
| 210 | + } |
| 211 | + |
| 212 | + SentryProfileOptions *_Nonnull profilingOptions = sentry_getSentryProfileOptions(); |
| 213 | + options.profiling = profilingOptions; |
| 214 | + options.configureProfiling(profilingOptions); |
| 215 | + |
| 216 | + if (sentry_isTraceLifecycle(profilingOptions) && !options.isTracingEnabled) { |
| 217 | + SENTRY_LOG_WARN( |
| 218 | + @"Tracing must be enabled in order to configure profiling with trace lifecycle."); |
| 219 | + return; |
| 220 | + } |
| 221 | + |
| 222 | + // if a launch profiler was started, sentry_profileConfiguration will have been set at that time |
| 223 | + // with the hydrated options that were persisted from the previous SDK start, which are used to |
| 224 | + // help determine when/how to stop the launch profile. otherwise, there won't yet be a |
| 225 | + // SentryProfileConfiguration instance, so we'll instantiate one which will be used to access |
| 226 | + // the profile session sample rate henceforth |
| 227 | + if (sentry_profileConfiguration == nil) { |
| 228 | + sentry_profileConfiguration = |
| 229 | + [[SentryProfileConfiguration alloc] initWithProfileOptions:profilingOptions]; |
| 230 | + } |
| 231 | + |
| 232 | + sentry_reevaluateSessionSampleRate(); |
| 233 | + |
| 234 | + SENTRY_LOG_DEBUG(@"Configured profiling options: <%@: {\n lifecycle: %@\n sessionSampleRate: " |
| 235 | + @"%.2f\n profileAppStarts: %@\n}", |
| 236 | + options.profiling, sentry_isTraceLifecycle(profilingOptions) ? @"trace" : @"manual", |
| 237 | + sentry_sessionSampleRate(profilingOptions), |
| 238 | + sentry_profileAppStarts(profilingOptions) ? @"YES" : @"NO"); |
| 239 | +} |
| 240 | + |
| 241 | +void |
| 242 | +sentry_sdkInitProfilerTasks(SentryOptions *options, SentryHubInternal *hub) |
| 243 | +{ |
| 244 | + // get the configuration options from the last time the launch config was written; it may be |
| 245 | + // different than the new options the SDK was just started with |
| 246 | + SentryProfileConfiguration *configurationFromLaunch = sentry_profileConfiguration; |
| 247 | + |
| 248 | + sentry_configureContinuousProfiling(options); |
| 249 | + |
| 250 | + sentry_dispatchAsync(SentryDependencyContainerSwiftHelper.dispatchQueueWrapper, ^{ |
| 251 | + if (configurationFromLaunch.isProfilingThisLaunch) { |
| 252 | + BOOL shouldStopAndTransmitLaunchProfile = YES; |
| 253 | + |
| 254 | + BOOL profileIsContinuousV2 = configurationFromLaunch.profileOptions != nil; |
| 255 | + BOOL v2LifecycleIsManual = profileIsContinuousV2 |
| 256 | + && !sentry_isTraceLifecycle(SENTRY_UNWRAP_NULLABLE( |
| 257 | + SentryProfileOptions, configurationFromLaunch.profileOptions)); |
| 258 | + |
| 259 | +#if SENTRY_HAS_UIKIT |
| 260 | + BOOL v2LifecycleIsTrace = profileIsContinuousV2 |
| 261 | + && sentry_isTraceLifecycle(SENTRY_UNWRAP_NULLABLE( |
| 262 | + SentryProfileOptions, configurationFromLaunch.profileOptions)); |
| 263 | + BOOL profileIsCorrelatedToTrace = !profileIsContinuousV2 || v2LifecycleIsTrace; |
| 264 | + if (profileIsCorrelatedToTrace && configurationFromLaunch.waitForFullDisplay) { |
| 265 | + SENTRY_LOG_DEBUG( |
| 266 | + @"Will wait to stop launch profile correlated to a trace until full " |
| 267 | + @"display reported."); |
| 268 | + shouldStopAndTransmitLaunchProfile = NO; |
| 269 | + } |
| 270 | +#endif // SENTRY_HAS_UIKIT |
| 271 | + |
| 272 | + if (v2LifecycleIsManual) { |
| 273 | + SENTRY_LOG_DEBUG(@"Continuous manual launch profiles aren't stopped on calls to " |
| 274 | + @"SentrySDK.start, " |
| 275 | + @"not stopping profile."); |
| 276 | + shouldStopAndTransmitLaunchProfile = NO; |
| 277 | + } |
| 278 | + |
| 279 | + if (shouldStopAndTransmitLaunchProfile) { |
| 280 | + SENTRY_LOG_DEBUG( |
| 281 | + @"Stopping launch profile in SentrySDK.start because there is no time " |
| 282 | + @"to display tracker to stop it."); |
| 283 | + sentry_stopAndDiscardLaunchProfileTracer(hub); |
| 284 | + } |
| 285 | + } |
| 286 | + |
| 287 | + sentry_configureLaunchProfilingForNextLaunch(options); |
| 288 | + }); |
| 289 | +} |
0 commit comments