getsentry/sentry-cocoa

MemoryBreadcrumbs V2

Opened this issue · 1 comments

Description

The SDK reports memory warning breadcrumbs by subscribing to the addObserverForName:UIApplicationDidReceiveMemoryWarningNotification

[NSNotificationCenter.defaultCenter
addObserverForName:UIApplicationDidReceiveMemoryWarningNotification
object:nil
queue:nil
usingBlock:^(NSNotification *notification) {
if (nil != [SentrySDK.currentHub getClient]) {
SentryBreadcrumb *crumb =
[[SentryBreadcrumb alloc] initWithLevel:kSentryLevelWarning
category:@"device.event"];
crumb.type = @"system";
crumb.data = @ { @"action" : @"LOW_MEMORY" };
crumb.message = @"Low memory";
[SentrySDK addBreadcrumb:crumb];
}
}];

With #2493 we now use a dispatch queue for a more fine grained approach

const auto queueAttributes
= dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY, 0);
_memoryWarningQueue = dispatch_queue_create("io.sentry.queue.memory-warnings", queueAttributes);
_memoryWarningSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MEMORYPRESSURE, 0,
DISPATCH_MEMORYPRESSURE_NORMAL | DISPATCH_MEMORYPRESSURE_WARN
| DISPATCH_MEMORYPRESSURE_CRITICAL,
_memoryWarningQueue);
__weak auto weakSelf = self;
dispatch_source_set_event_handler(_memoryWarningSource, ^{
const auto strongSelf = weakSelf;
if (!strongSelf) {
return;
}
handler(dispatch_source_get_data(strongSelf->_memoryWarningSource));
});
dispatch_resume(_memoryWarningSource);

With that we could also create breadcrumbs for DISPATCH_MEMORYPRESSURE_NORMAL, DISPATCH_MEMORYPRESSURE_WARN, DISPATCH_MEMORYPRESSURE_CRITICA. Furthermore, we could add the currently available memory with

- (mach_vm_size_t)memoryFootprintBytes:(NSError *__autoreleasing _Nullable *)error
{
task_vm_info_data_t info;
mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
const auto status = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&info, &count);
if (status != KERN_SUCCESS) {
if (error) {
*error = NSErrorFromSentryErrorWithKernelError(
kSentryErrorKernel, @"task_info reported an error.", status);
}
return 0;
}
mach_vm_size_t footprintBytes;
if (count >= TASK_VM_INFO_REV1_COUNT) {
footprintBytes = info.phys_footprint;
} else {
footprintBytes = info.resident_size;
}
return footprintBytes;
}

Thermal State

- (void)registerStateChangeNotifications
{
// According to Apple docs: "To receive NSProcessInfoThermalStateDidChangeNotification, you must
// access the thermalState prior to registering for the notification." (from
// https://developer.apple.com/documentation/foundation/nsprocessinfothermalstatedidchangenotification/)
[self recordThermalState];
[_processInfoWrapper monitorForThermalStateChanges:self callback:@selector(recordThermalState)];
if (@available(macOS 12.0, *)) {
[_processInfoWrapper monitorForPowerStateChanges:self
callback:@selector(recordPowerLevelState)];
}
}

We should ensure that this doesn't spam breadcrumbs. Its possible for the system to be in the edge of a warning On and Off.