-
-
Notifications
You must be signed in to change notification settings - Fork 371
Flush Logs on WillTerminate or WillResignActive Notifications
#6909
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WillTerminate or WillResignActive` App State
WillTerminate or WillResignActive` App StateWillTerminate or WillResignActive App State
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #6909 +/- ##
=============================================
+ Coverage 85.069% 85.077% +0.008%
=============================================
Files 453 454 +1
Lines 27681 27730 +49
Branches 12166 12178 +12
=============================================
+ Hits 23548 23592 +44
- Misses 3874 4094 +220
+ Partials 259 44 -215
... and 40 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
|
|
The app state manager is only enabled for UIKit, but the notification-equivalents for terminate/active should also be available for macOS. Is this intended behaviour? |
Performance metrics 🚀
|
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 0ede342 | 1233.47 ms | 1262.29 ms | 28.82 ms |
| d05d866 | 1211.78 ms | 1230.96 ms | 19.18 ms |
| bbe6658 | 1221.00 ms | 1248.51 ms | 27.51 ms |
| bc0a04c | 1226.83 ms | 1255.04 ms | 28.21 ms |
| 15a6325 | 1209.43 ms | 1233.43 ms | 24.00 ms |
| 25d9b58 | 1233.76 ms | 1267.92 ms | 34.16 ms |
| 532bde4 | 1210.63 ms | 1256.24 ms | 45.61 ms |
| f83dcc4 | 1210.88 ms | 1246.22 ms | 35.35 ms |
| 449d185 | 1216.31 ms | 1251.94 ms | 35.62 ms |
| dad68ad | 1229.15 ms | 1261.98 ms | 32.83 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 0ede342 | 23.75 KiB | 928.15 KiB | 904.40 KiB |
| d05d866 | 23.75 KiB | 878.60 KiB | 854.85 KiB |
| bbe6658 | 23.75 KiB | 908.02 KiB | 884.27 KiB |
| bc0a04c | 23.75 KiB | 933.32 KiB | 909.57 KiB |
| 15a6325 | 23.75 KiB | 933.33 KiB | 909.58 KiB |
| 25d9b58 | 24.15 KiB | 1.01 MiB | 1014.91 KiB |
| 532bde4 | 24.15 KiB | 1.01 MiB | 1014.89 KiB |
| f83dcc4 | 23.75 KiB | 1.02 MiB | 1019.11 KiB |
| 449d185 | 23.75 KiB | 980.81 KiB | 957.06 KiB |
| dad68ad | 23.75 KiB | 912.37 KiB | 888.63 KiB |
Previous results on branch: feat/flush-logs-on-app-state-change
Startup times
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| a6be137 | 1221.02 ms | 1260.93 ms | 39.91 ms |
| 27d2fb4 | 1228.62 ms | 1260.15 ms | 31.53 ms |
| 2cb9aef | 1228.32 ms | 1265.86 ms | 37.54 ms |
| 862c32d | 1212.94 ms | 1246.50 ms | 33.56 ms |
| 58c01c4 | 1193.19 ms | 1242.47 ms | 49.28 ms |
| 5a96fbe | 1223.24 ms | 1239.82 ms | 16.57 ms |
| e1bf267 | 1215.20 ms | 1241.04 ms | 25.84 ms |
| 6b6ef93 | 1192.06 ms | 1212.08 ms | 20.02 ms |
| 9ee58f1 | 1231.78 ms | 1268.67 ms | 36.89 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| a6be137 | 24.14 KiB | 1.02 MiB | 1017.81 KiB |
| 27d2fb4 | 24.14 KiB | 1.02 MiB | 1017.82 KiB |
| 2cb9aef | 24.14 KiB | 1.02 MiB | 1017.76 KiB |
| 862c32d | 24.14 KiB | 1.02 MiB | 1017.77 KiB |
| 58c01c4 | 24.14 KiB | 1.01 MiB | 1013.67 KiB |
| 5a96fbe | 24.14 KiB | 1.01 MiB | 1015.46 KiB |
| e1bf267 | 24.14 KiB | 1.01 MiB | 1015.57 KiB |
| 6b6ef93 | 24.14 KiB | 1.01 MiB | 1015.51 KiB |
| 9ee58f1 | 24.14 KiB | 1.01 MiB | 1013.68 KiB |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for doing this. I found a few high-level issues we need to address before I give this a closer look.
# Conflicts: # Sentry.xcodeproj/project.pbxproj
Tests/SentryTests/Integrations/Log/SentryLogFlushIntegrationTests.swift
Outdated
Show resolved
Hide resolved
# Conflicts: # Sources/Swift/Core/Integrations/Integrations.swift
WillTerminate or WillResignActive App StateWillTerminate or WillResignActive Notifications
Sources/Sentry/SentryClient.m
Outdated
|
|
||
| // Uses DEFAULT priority (not LOW) because captureLogs() is called synchronously during | ||
| // app lifecycle events (willResignActive, willTerminate) and needs to complete quickly. | ||
| dispatch_queue_attr_t attributes = dispatch_queue_attr_make_with_qos_class( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m: Consider moving this to SentryDispatchFactory.m available via SentryDependencyContainer.sharedInstance.dispatchFactory so the creating of queues is consolidated to one position (as it should be everywhere)
| let commonIntegrations: [AnyIntegration] = [.init(SwiftAsyncIntegration.self)] | ||
|
|
||
| var integrations: [AnyIntegration] = [.init(SwiftAsyncIntegration.self)] | ||
| #if os(iOS) && !SENTRY_NO_UIKIT | ||
| let integrations: [AnyIntegration] = commonIntegrations + [.init(UserFeedbackIntegration<SentryDependencyContainer>.self)] | ||
| #else | ||
| let integrations: [AnyIntegration] = commonIntegrations | ||
| integrations.append(.init(UserFeedbackIntegration<SentryDependencyContainer>.self)) | ||
| #endif | ||
|
|
||
| #if ((os(iOS) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT) || ((os(macOS) || targetEnvironment(macCatalyst)) && !SENTRY_NO_UIKIT) | ||
| integrations.append(.init(FlushLogsIntegration<SentryDependencyContainer>.self)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
l: What's your reason for refactoring this logic to not use "commonIntegrations" and added ones?
Tests/SentryTests/Integrations/Log/FlushLogsIntegrationTests.swift
Outdated
Show resolved
Hide resolved
philipphofmann
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @denrase, we're getting closer to an LGTM.
| // Uses DEFAULT priority (not LOW) because captureLogs() is called synchronously during | ||
| // app lifecycle events (willResignActive, willTerminate) and needs to complete quickly. | ||
| dispatch_queue_attr_t attributes | ||
| = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_DEFAULT, 0); | ||
| SentryDispatchQueueWrapper *logBatcherQueue = | ||
| [[SentryDispatchQueueWrapper alloc] initWithName:"io.sentry.log-batcher" | ||
| attributes:attributes]; | ||
|
|
||
| self.logBatcher = [[SentryLogBatcher alloc] initWithOptions:options | ||
| dispatchQueue:logBatcherQueue | ||
| delegate:self]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m: Thanks for adding an extra dispatch queue. What bugs me a bit is that the SentryLogBatcher specifically needs the dispatch queue above to work correctly, so the init of this specific DispatchQueueWrapper should be in the SentryLogBatcher.swift file if possible, IMO. What about removing the SentryDispatchQueueWrapper param from the convenience init and let the convenience init create the SentryDispatchQueueWrapper. We anyways use the other init method for tests.
| import UIKit | ||
| private typealias CrossPlatformApplication = UIApplication | ||
| #elseif (os(macOS) || targetEnvironment(macCatalyst)) && !SENTRY_NO_UIKIT | ||
| #elseif os(macOS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m: Is this change still intended?
|
|
||
| @objc private func willResignActive() { | ||
| guard let client = SentrySDKInternal.currentHub().getClient() else { | ||
| return |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
l: Maybe worth adding a log message that the client is nil so we don't have to call captureLogs
| import UIKit | ||
| typealias Application = UIApplication | ||
| #elseif (os(macOS) || targetEnvironment(macCatalyst)) && !SENTRY_NO_UIKIT | ||
| #elseif os(macOS) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m: Are these changes here intended?
| } | ||
| } | ||
|
|
||
| private var fixture: Fixture! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m: We didn't write this down yet somewhere, but we're trying to get rid of the fixture pattern. Please define the fixture variables as properties of the test instead.
|
|
||
| override func tearDown() { | ||
| super.tearDown() | ||
| clearTestState() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m: Please avoid using the clearTestState if you can because it does so many things. If you can, consider only unsetting the things you need to unset. In this case, it should be SentrySDKInternal.setCurrentHub(nil).
| dependencies = SentryDependencyContainer.sharedInstance() | ||
| notificationCenterWrapper = TestNSNotificationCenterWrapper() | ||
| dependencies.notificationCenterWrapper = notificationCenterWrapper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
m: Please don't use the SentryDependencyContainer for the test dependencies. Do it like this instead
sentry-cocoa/Tests/SentryTests/Integrations/Feedback/UserFeedbackIntegrationTests.swift
Lines 14 to 16 in b2295d4
| private struct TestDependencies: ScreenshotSourceProvider { | |
| let screenshotSource: SentryScreenshotSource? | |
| } |
📜 Description
captureLogson batcher if app terminatescaptureLogson batcher if app resigns activeIntroduces listeners on the AppState and observes it in a conditional (UIKit) integration.
💡 Motivation and Context
Implements missing behaviour from batch processor spec.
Closes #6478
💚 How did you test it?
Added tests and tested manually.
📝 Checklist
You have to check all boxes before merging:
sendDefaultPIIis enabled.