社区编辑申请
注册/登录
iOS 使用 Metrickit 收集崩溃日志
移动开发 iOS
MetricKit 是 苹果在 iOS13系统开始引入的用来汇总和分析有关异常和崩溃诊断以及电源和性能指标的每个设备的报告。当前市面上的开源框架,如 KSCrash,PLCrashReport 等框架都有一些崩溃不能抓取。

Metrickit 是什么

MetricKit 是 苹果在 iOS13系统开始引入的用来汇总和分析有关异常和崩溃诊断以及电源和性能指标的每个设备的报告。

为什么要用 MetricKit 收集崩溃日志

当前市面上的开源框架,如 KSCrash,PLCrashReport 等框架都有一些崩溃不能抓取;比如PLCrashReport 不能抓取栈溢出的崩溃,不能抓取SIGKILL, SIGQUIT等信号量的崩溃。KSCrash 对SIGKILL的崩溃抓取也只能抓取一部分

Metrickit 缺陷

  • 目前只支持 iOS14 以后的崩溃日志收集
  • 崩溃日志没有返回具体的崩溃时间和启动时间,崩溃场景信息除了堆栈外没有其余信息
  • 如果使用了段迁移编译技术,主程序 macho 的地址和 uuid 无法匹配。

iOS14的崩溃日志是24小时会回调通知一次,时效性低;iOS15 之后,崩溃日志会在下次启动之后就返回,但经验证,有的会立即回调,有的则不然,规律不可琢磨

开始接入

1.添加 MetricKit

2.添加 MetricKit 监听者

if (@available(iOS 14.0, *)) {

MXMetricManager *manager = [MXMetricManager sharedManager];

if (self && manager && [manager respondsToSelector:@selector(addSubscriber:)]) {

[manager addSubscriber:self];

}

}

3. 监听者实现 MXMetricManagerSubscriber 协议方法, payloadDic 里面包含着上次本应用发生的崩溃日志堆栈和信息

 // 苹果如果有数据数据,注册监听之后就会回调

- (void)didReceiveDiagnosticPayloads:(NSArray<MXDiagnosticPayload *> * _Nonnull)payloads API_AVAILABLE(ios(14.0)){

if (@available(iOS 14.0, *)) {

for (MXDiagnosticPayload *payload in payloads) {

NSDictionary *payloadDic = [payload dictionaryRepresentation];



});

}

}

}

4.日志组装关键代码示例

NSArray *callStackRootFrames = [dicFrame  ArrayValueForKey:kMetrkitCallStackRootFramesKey];

if (callStackRootFrames.count <= 0) {

continue;

}

NSDictionary *dicZero = [callStackRootFrames ObjectAtIndex:0];

int rootIndex = 0;

while (dicZero && dicZero.count > 0) {

NSString *binaryUUID = [dicZero stringValueForKey:kMetrkitBinaryUUIDKey];

NSString *binaryName = [dicZero stringValueForKey:kMetrkitBinaryNameKey];

long long baseAdd = [[dicZero NumberValueForKey:kMetrkitOffsetIntoBinaryTextSegmentKey] longLongValue];

long long address = [[dicZero numberValueForKey:kMetrkitAddressKey] longLongValue];

NSArray *subFrames = [dicZero arrayValueForKey:kMetrkitSubFramesKey];

[strStack appendFormat:@"%d %@ 0x%llx 0x%llx + %lld\n", rootIndex, binaryName, baseAdd, address, address - model.baseAddress];

rootIndex++;

if (subFrames && subFrames.count >= 0) {

dicZero = [subFrames ObjectAtIndex:0];

} else {

dicZero = nil;

}

MetricKit 返回字段含义及详情

JSON总格式

crashDiagnostics 详情

每一个崩溃为一个字典,具体内容为下

diagnosticMetaData 字典详情

|terminationReason|String|崩溃原因| RBSTerminateContext domain:10 code:0x8BADF00D 
explanation:scene-update watchdog transgression: application :6308
exhausted real (wall clock) time allowance of 10.00 seconds|

callStackTree 字典详情

callStacks 数组详情

数组中元素为字典,详情如下

callStackRootFrames 数组详情

数组中元素为字典,详情如下

diskWriteExceptionDiagnostics 详情

每一个崩溃为一个字典,具体内容为下

diagnosticMetaData 字典详情

callStackTree 字典详情

callStacks 数组详情

数组中元素为字典,详情如下

callStackRootFrames 数组详情

数组中元素为字典,详情如下

cpuExceptionDiagnostics 详情

每一个崩溃为一个字典,具体内容为下

diagnosticMetaData 字典详情

callStackTree 字典详情

callStacks 数组详情

数组中元素为字典,详情如下

callStackRootFrames 数组详情

数组中元素为字典,详情如下

hangDiagnostics 详情

diagnosticMetaData 字典详情

callStackTree 字典详情

callStacks 数组详情


callStackRootFrames 数组详情

责任编辑:未丽燕 来源: Swift社区
相关推荐

2022-05-13 09:27:55

Widget机票业务App

2022-03-16 11:32:54

苹果iOS 15.4Face ID

2022-05-20 08:17:43

Java日志

2022-05-07 10:09:01

开发Java日志

2022-03-04 22:46:08

iOS苹果微信

2022-04-08 08:40:36

Nginx日志服务器

2022-04-15 09:23:29

Kubernetes面试题

2022-04-08 09:52:13

前端监控系统

2022-04-11 09:15:44

中间件开源

2022-03-22 15:20:32

微信全文搜索

2022-04-18 10:36:48

社交软件聊天平台rocket.cha

2021-12-15 09:43:31

2022-03-21 09:52:44

LinuxSystemd日志

2022-05-12 08:22:54

内核oopsPC

2022-04-14 15:01:02

Windows 11Windows 10浏览器

2022-04-19 09:24:18

QtC++框架

2022-05-08 09:24:08

微软Windows 11

2022-02-18 11:26:23

2022-04-22 11:16:35

Linux工具命令

2022-03-30 13:56:05

前端监控搭建

同话题下的热门内容

苹果 iOS 15.5 正式版发布,一文看懂都更新了啥苹果官宣:iOS 16 有这些强大新功能iOS 16,为颠覆而来?聊聊 Swift 中的类型占位符

编辑推荐

iOS15到底该不该升级,你的iPhone11还吃香吗?iOS符号表恢复&逆向支付宝苏宁蛙测基于Instruments检测iOS性能技术苹果为已淘汰的设备提供iOS 9.3.6和iOS 10.3.4更新iOS15发烫严重?解决办法在这里,拒绝玄学
我收藏的内容
点赞
收藏

51CTO技术栈公众号