-
-
Notifications
You must be signed in to change notification settings - Fork 372
Flush Logs on WillTerminate or WillResignActive App State
#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
❌ 2 Tests Failed:
View the top 2 failed test(s) by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
|
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 |
|---|---|---|---|
| fae97e5 | 1229.20 ms | 1256.27 ms | 27.06 ms |
| 275e0a6 | 1222.16 ms | 1258.07 ms | 35.91 ms |
| bce9765 | 1229.42 ms | 1243.49 ms | 14.07 ms |
| 0dd7283 | 1230.47 ms | 1255.94 ms | 25.47 ms |
| b074ba9 | 1236.52 ms | 1248.75 ms | 12.23 ms |
| 701acf0 | 1230.24 ms | 1255.60 ms | 25.36 ms |
| 095d886 | 1226.31 ms | 1257.05 ms | 30.73 ms |
| 5cfc768 | 1220.74 ms | 1245.06 ms | 24.32 ms |
| 67e8e3e | 1220.08 ms | 1229.23 ms | 9.15 ms |
| 66147d5 | 1234.45 ms | 1268.45 ms | 34.00 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| fae97e5 | 23.75 KiB | 912.37 KiB | 888.62 KiB |
| 275e0a6 | 24.15 KiB | 1.01 MiB | 1014.90 KiB |
| bce9765 | 23.74 KiB | 874.06 KiB | 850.32 KiB |
| 0dd7283 | 23.74 KiB | 997.28 KiB | 973.53 KiB |
| b074ba9 | 23.74 KiB | 976.79 KiB | 953.05 KiB |
| 701acf0 | 23.75 KiB | 987.96 KiB | 964.21 KiB |
| 095d886 | 24.15 KiB | 1.01 MiB | 1014.91 KiB |
| 5cfc768 | 23.75 KiB | 850.73 KiB | 826.98 KiB |
| 67e8e3e | 23.75 KiB | 919.91 KiB | 896.16 KiB |
| 66147d5 | 23.74 KiB | 1.01 MiB | 1008.77 KiB |
Previous results on branch: feat/flush-logs-on-app-state-change
Startup times
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 5a96fbe | 1223.24 ms | 1239.82 ms | 16.57 ms |
| 6b6ef93 | 1192.06 ms | 1212.08 ms | 20.02 ms |
App size
| Revision | Plain | With Sentry | Diff |
|---|---|---|---|
| 5a96fbe | 24.14 KiB | 1.01 MiB | 1015.46 KiB |
| 6b6ef93 | 24.14 KiB | 1.01 MiB | 1015.51 KiB |
| #import "SentrySDK+Private.h" | ||
| #import "SentrySwift.h" | ||
|
|
||
| #if SENTRY_HAS_UIKIT |
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.
Bug: Platform mismatch between integration and manager
The SentryLogFlushIntegration is conditionally compiled only for SENTRY_HAS_UIKIT platforms (iOS, tvOS, visionOS), but macOS also has equivalent notifications (NSApplication.willTerminateNotification and NSApplication.willResignActiveNotification). The feature won't work on macOS despite the platform having the necessary app lifecycle notifications, creating an inconsistent behavior across platforms. The SentryAppStateManager and its listener infrastructure also exclude macOS, preventing log flushing on app termination or resign on that platform.
Additional Locations (1)
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.
|
|
||
| NS_ASSUME_NONNULL_BEGIN | ||
|
|
||
| @interface SentryLogFlushIntegration () <SentryAppStateListener> |
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.
h: We can write integrations in Swift after merging #6862. I think we should already convert this integration to Swift then.
| return NO; | ||
| } | ||
|
|
||
| [[[SentryDependencyContainer sharedInstance] appStateManager] addListener: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.
h: What drove you to use the app state manager here? I would rather subscribe and also unsubscribe to the notifications willResignActiveNotification and willTerminateNotification as the SentrySessionTracker does. Then we don't need to modify the app state manager for this.
|
|
||
| - (void)flushLogs | ||
| { | ||
| [self.logBatcher captureLogs]; |
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: If the logBatcher then actually flushes the logs, shouldn't we rename the method to flush?
| [self.logBatcher captureLogs]; | |
| [self.logBatcher flush]; |
| // Guard against sync call deadlock when we are already on the dispatchQueue.queue. | ||
| if dispatchQueue.isCurrentQueue() { | ||
| performCaptureLogs() | ||
| } else { | ||
| dispatchQueue.dispatchSync { [weak self] in | ||
| self?.performCaptureLogs() | ||
| } |
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: Wouldn't always calling performCaptureLogs directly not be the same? Or is it because we need to run it on the serial dispatch queue? If yes, I think it would actually be better to do that check in the performCaptureLogs
But actually this seems a bit wrong to me. Maybe we should ensure that the LogBatcher gets its own queue that nobody else MUST use. Then we can be certain nobody else uses this queue, and we can safely call dispatchQueue.dispatchSync. Also when the global dispatchQueue of Sentry is very busy we have to wait until its finished to proceed here.
| // Guard against sync call deadlock when we are already on the dispatchQueue.queue. | |
| if dispatchQueue.isCurrentQueue() { | |
| performCaptureLogs() | |
| } else { | |
| dispatchQueue.dispatchSync { [weak self] in | |
| self?.performCaptureLogs() | |
| } | |
| performCaptureLogs() |
📜 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.