diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ccd4cb1245..da3585d1077 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## Unreleased + +### Features + +- Send debug meta for app start transactions (#3543) + ## 8.18.0 ### Features diff --git a/Sources/Sentry/SentryTracer.m b/Sources/Sentry/SentryTracer.m index aea8a1d8a53..716737946fb 100644 --- a/Sources/Sentry/SentryTracer.m +++ b/Sources/Sentry/SentryTracer.m @@ -71,6 +71,7 @@ @property (nonatomic, nullable, strong) NSTimer *deadlineTimer; @property (nonnull, strong) SentryTracerConfiguration *configuration; @property (nonatomic, strong) SentryDispatchQueueWrapper *dispatchQueue; +@property (nonatomic, strong) SentryDebugImageProvider *debugImageProvider; #if SENTRY_TARGET_PROFILING_SUPPORTED @property (nonatomic) BOOL isProfiling; @@ -134,6 +135,7 @@ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transacti _startSystemTime = SentryDependencyContainer.sharedInstance.dateProvider.systemTime; _configuration = configuration; _dispatchQueue = SentryDependencyContainer.sharedInstance.dispatchQueueWrapper; + _debugImageProvider = SentryDependencyContainer.sharedInstance.debugImageProvider; self.transactionContext = transactionContext; _children = [[NSMutableArray alloc] init]; @@ -751,6 +753,10 @@ - (void)addAppStartMeasurements:(SentryTransaction *)transaction NSDictionary *appContext = @{ @"app" : @ { @"start_type" : appStartType } }; [context mergeEntriesFromDictionary:appContext]; [transaction setContext:context]; + + // The backend calculates statistics on the number and size of debug images for app + // start transactions. Therefore, we add all debug images here. + transaction.debugMeta = [self.debugImageProvider getDebugImagesCrashed:NO]; } } } diff --git a/Tests/SentryTests/Transaction/SentryTracerTests.swift b/Tests/SentryTests/Transaction/SentryTracerTests.swift index b9d2dbfd456..f556d8047f0 100644 --- a/Tests/SentryTests/Transaction/SentryTracerTests.swift +++ b/Tests/SentryTests/Transaction/SentryTracerTests.swift @@ -26,6 +26,7 @@ class SentryTracerTests: XCTestCase { let hub: TestHub let scope: Scope let dispatchQueue = TestSentryDispatchQueueWrapper() + let debugImageProvider = TestDebugImageProvider() let timerFactory = TestSentryNSTimerFactory() let transactionName = "Some Transaction" @@ -53,6 +54,9 @@ class SentryTracerTests: XCTestCase { SentryDependencyContainer.sharedInstance().dateProvider = currentDateProvider SentryDependencyContainer.sharedInstance().dispatchQueueWrapper = dispatchQueue + + debugImageProvider.debugImages = [TestData.debugImage] + SentryDependencyContainer.sharedInstance().debugImageProvider = debugImageProvider appStart = currentDateProvider.date() appStartEnd = appStart.addingTimeInterval(appStartDuration) @@ -865,6 +869,28 @@ class SentryTracerTests: XCTestCase { assertAppStartMeasurementNotPutOnTransaction() } + + func testAppStartTransaction_AddsDebugMeta() { + let appStartMeasurement = fixture.getAppStartMeasurement(type: .cold) + SentrySDK.setAppStartMeasurement(appStartMeasurement) + + whenFinishingAutoUITransaction(startTimestamp: 5) + + expect(self.fixture.hub.capturedEventsWithScopes.count) == 1 + let serializedTransaction = fixture.hub.capturedEventsWithScopes.first?.event.serialize() + + let debugMeta = serializedTransaction?["debug_meta"] as? [String: Any] + expect(debugMeta?.count) == fixture.debugImageProvider.getDebugImagesCrashed(false).count + } + + func testNoAppStartTransaction_AddsNoDebugMeta() { + whenFinishingAutoUITransaction(startTimestamp: 5) + + expect(self.fixture.hub.capturedEventsWithScopes.count) == 1 + let serializedTransaction = fixture.hub.capturedEventsWithScopes.first?.event.serialize() + + expect(serializedTransaction?["debug_meta"]) == nil + } #endif // os(iOS) || os(tvOS) || targetEnvironment(macCatalyst)