iOS使用 Metrickit 收集崩溃日志
Metrickit 是什么
MetricKit 是 苹果在 iOS13系统开始引入的用来汇总和分析有关异常和崩溃诊断以及电源和性能指标的每个设备的报告。
为什么要用 MetricKit 收集崩溃日志
当前市面上的开源框架,如 KSCrash,PLCrashReport 等框架都有一些崩溃不能抓取;比如PLCrashReport 不能抓取栈溢出的崩溃,不能抓取SIGKILL, SIGQUIT等信号量的崩溃。KSCrash 对SIGKILL的崩溃抓取也只能抓取一部分
Metrickit 缺陷
1.目前只支持 iOS14 以后的崩溃日志收集
2.崩溃日志没有返回具体的崩溃时间和启动时间,崩溃场景信息除了堆栈外没有其余信息
3.如果使用了段迁移编译技术,主程序 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总格式
key 值类型 解释 demo值 crashDiagnostics Array 记录的崩溃 见下面详情 hangDiagnostics Array 记录的卡顿信息 见下面详情 cpuExceptionDiagnostics Array 记录的cpu异常信息 见下面详情 diskWriteExceptionDiagnostics Array 记录的磁盘写入异常信息 见下面详情 timeStampBegin Date 记录事件开始间隔 2021-12-01 09:06:57 +0000 timeStampEnd Date 记录事件结束间隔 2021-12-01 09:06:57 +0000
crashDiagnostics 详情
每一个崩溃为一个字典,具体内容为下
key 值类型 解释 demo值 version String Metrkit 框架版本 1.0.0 diagnosticMetaData 字典 崩溃的一些核心信息(含App信息) 见二级详情 callStackTree 字典 堆栈相关信息 见二级详情
diagnosticMetaData 字典详情
key 值类型 解释 demo值 appBuildVersion String build 12.29.0.1 appVersion String app 版本 12.29.0 regionFormat String 区域代码 CN exceptionType String 异常类型 1 osVersion String iOS 操作系统 iPhone OS 15.1 (19B74) deviceType String Model iPhone13,1 bundleIdentifier String bundle com.xxx.xxxxx exceptionCode String exception Code 1 signal String 信号量符号 11 platformArchitecture String cpu 架构 arm64e virtualMemoryRegionInfo String 虚拟内存信息 0x10 is not in any region. Bytes before following region: 433969560 REGION TYPE START- END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL UNUSED SPACE AT START—> __**TEXT 102aa8000-11012c000 [214.5M] r-x/r-x SM=COW …p/xxxxx
|terminationReason|String|崩溃原因| RBSTerminateContext domain:10 code:0x8BADF00D explanation:scene-update watchdog transgression: application <com.xxx.xxxx> :6308 exhausted real (wall clock) time allowance of 10.00 seconds|
callStackTree 字典详情
key 值类型 解释 demo值 callStacks Array 每个线程详细堆栈 见三级详情 callStackPerThread BOOL 是否只收集单线程 见二级详情
callStacks 数组详情
数组中元素为字典,详情如下
key 值类型 解释 demo值 threadAttributed BOOL 是否是崩溃线程 true callStackRootFrames Array 单线程堆栈详细信息 见下一级级详情
callStackRootFrames 数组详情
数组中元素为字典,详情如下
key 值类型 解释 demo值 binaryUUID String uuid DC6B1885-FB91-34C4-A9FC-A539C17A08A7 offsetIntoBinaryTextSegment int 基于二进制macho的偏移,十进制 4339695616 sampleCount int 未知 1 binaryName String 二进制macho的名称 xxx address int 二进制macho的基址 4446737180 subFrames Array 诱发此次崩溃的上一级线程 有可能循环递归callStackRootFrames内容
diskWriteExceptionDiagnostics 详情
每一个崩溃为一个字典,具体内容为下
key 值类型 解释 demo值 version String Metrkit 框架版本 1.0.0 diagnosticMetaData 字典 崩溃的一些核心信息(含App信息) 见二级详情 callStackTree 字典 堆栈相关信息 见二级详情
diagnosticMetaData 字典详情
key 值类型 解释 demo值 appBuildVersion String build 12.29.0.1 appVersion String app 版本 12.29.0 regionFormat String 区域代码 CN osVersion String iOS 操作系统 iPhone OS 15.1 (19B74) deviceType String Model iPhone13,1 bundleIdentifier String bundle com.xxx writesCaused String 写原因 2,000字节 platformArchitecture String cpu 架构 arm64e
callStackTree 字典详情
key 值类型 解释 demo值 callStacks Array 每个线程详细堆栈 见三级详情 callStackPerThread BOOL 是否只收集单线程 见二级详情
callStacks 数组详情
数组中元素为字典,详情如下
key 值类型 解释 demo值 threadAttributed BOOL 是否是触发线程 true callStackRootFrames Array 单线程堆栈详细信息 见下一级级详情
callStackRootFrames 数组详情
数组中元素为字典,详情如下
key 值类型 解释 demo值 binaryUUID String uuid DC6B1885-FB91-34C4-A9FC-A539C17A08A7 offsetIntoBinaryTextSegment int 基于二进制macho的偏移,十进制 4339695616 sampleCount int 未知 1 binaryName String 二进制macho的名称 xxxxx address int 二进制macho的基址 4446737180 subFrames Array 诱发此次崩溃的上一级线程 有可能循环递归callStackRootFrames内容
cpuExceptionDiagnostics 详情
每一个崩溃为一个字典,具体内容为下
key 值类型 解释 demo值 version String Metrkit 框架版本 1.0.0 diagnosticMetaData 字典 崩溃的一些核心信息(含App信息) 见二级详情 callStackTree 字典 堆栈相关信息 见二级详情
diagnosticMetaData 字典详情
key 值类型 解释 demo值 appBuildVersion String build 12.29.0.1 appVersion String app 版本 12.29.0 regionFormat String 区域代码 CN osVersion String iOS 操作系统 iPhone OS 15.1 (19B74) deviceType String Model iPhone13,1 bundleIdentifier String bundle com.xxx totalCPUTime String cpu时间 20s totalSampledTime String CPU总采样时间 20s platformArchitecture String cpu 架构 arm64e
callStackTree 字典详情
key 值类型 解释 demo值 callStacks Array 每个线程详细堆栈 见三级详情 callStackPerThread BOOL 是否只收集单线程 见二级详情
callStacks 数组详情
数组中元素为字典,详情如下
key 值类型 解释 demo值 threadAttributed BOOL 是否是触发线程 true callStackRootFrames Array 单线程堆栈详细信息 见下一级级详情
callStackRootFrames 数组详情
数组中元素为字典,详情如下
key 值类型 解释 demo值 binaryUUID String uuid DC6B1885-FB91-34C4-A9FC-A539C17A08A7 offsetIntoBinaryTextSegment int 基于二进制macho的偏移,十进制 4339695616 sampleCount int 未知 1 binaryName String 二进制macho的名称 xxxxx address int 二进制macho的基址 4446737180 subFrames Array 诱发此次崩溃的上一级线程 有可能循环递归callStackRootFrames内容
hangDiagnostics 详情
每一个崩溃为一个字典,具体内容为下
key 值类型 解释 demo值 version String Metrkit 框架版本 1.0.0 diagnosticMetaData 字典 崩溃的一些核心信息(含App信息) 见二级详情 callStackTree 字典 堆栈相关信息 见二级详情
diagnosticMetaData 字典详情
key 值类型 解释 demo值 appBuildVersion String build 12.29.0.1 appVersion String app 版本 12.29.0 regionFormat String 区域代码 CN osVersion String iOS 操作系统 iPhone OS 15.1 (19B74) deviceType String Model iPhone13,1 bundleIdentifier String bundle com.xxx hangDuration String 卡顿时间 20s platformArchitecture String cpu 架构 arm64e
callStackTree 字典详情
key 值类型 解释 demo值 callStacks Array 每个线程详细堆栈 见三级详情 callStackPerThread BOOL 是否只收集单线程 见二级详情
callStacks 数组详情
数组中元素为字典,详情如下
key 值类型 解释 demo值 threadAttributed BOOL 是否是触发线程 true callStackRootFrames Array 单线程堆栈详细信息 见下一级级详情
callStackRootFrames 数组详情
数组中元素为字典,详情如下
key 值类型 解释 demo值 binaryUUID String uuid DC6B1885-FB91-34C4-A9FC-A539C17A08A7 offsetIntoBinaryTextSegment int 基于二进制macho的偏移,十进制 4339695616 sampleCount int 未知 1 binaryName String 二进制macho的名称 xxxxx address int 二进制macho的基址 4446737180 subFrames Array 诱发此次崩溃的上一级线程 有可能循环递归callStackRootFrames内容