iOSはMetrickitを使用してクラッシュログを収集します
Metrickitとは何ですか
MetricKitは、iOS 13でAppleによって導入され、例外とクラッシュの診断、および電力とパフォーマンスのメトリックに関するデバイスごとのレポートを集約および分析します。
MetricKitを使用してクラッシュログを収集する理由
KSCrash、PLCrashReport、その他のフレームワークなど、現在市場に出回っているオープンソースフレームワークには、キャプチャできないクラッシュがいくつかあります。たとえば、PLCrashReportはスタックオーバーフロークラッシュをキャプチャできず、SIGKILL、SIGQUIT、その他のセマフォクラッシュをキャプチャできません。KSCrashによるSIGKILLのクラッシュキャプチャは、その一部しかキャプチャできません
Metrickitのバグ
1.現在、iOS14以降のクラッシュログ収集のみをサポートしています
2.クラッシュログは特定のクラッシュ時間と起動時間を返しません。クラッシュシーン情報には、スタック以外の情報はありません。
3.セグメント移行コンパイル技術を使用する場合、メインプログラムmachoのアドレスとuuidを一致させることはできません。
iOS14のクラッシュログは24時間に1回通知され、適時性は低いです。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の一般的な形式
鍵 |
値型 |
説明 |
demo值 |
クラッシュ診断 |
配列 |
記録されたクラッシュ |
以下の詳細を参照してください |
hangDiagnostics |
配列 |
記録されたCaton情報 |
以下の詳細を参照してください |
cpuExceptionDiagnostics |
配列 |
記録されたCPU例外情報 |
以下の詳細を参照してください |
diskWriteExceptionDiagnostics |
配列 |
記録されたディスク書き込み例外情報 |
以下の詳細を参照してください |
timeStampBegin |
日にち |
ロギングイベントの開始間隔 |
2021-12-01 09:06:57 +0000 |
timeStampEnd |
日にち |
イベント終了間隔をログに記録する |
2021-12-01 09:06:57 +0000 |
クラッシュ診断の詳細
各クラッシュは辞書であり、具体的な内容は次のとおりです
鍵 |
値型 |
説明 |
demo值 |
バージョン |
弦 |
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内容 |