日志收集
iOS開發中經常會遇到程序異常閃退的情況,快速的錯誤定位、問題修復、很大程度上依賴我們的異常日志,所以日志收集、分析及定位在修復問題時至關重要,在日志收集時如果保密性不高的應用來說,可以選擇Crash統計產品,如:友盟、Bugly等,如果是保密性高,或者不愿意其他平臺收集自己的日志??梢赃x擇自己實現日志的收集及分析。本文主要介紹使用KSCrash開源第三方庫實現奔潰日志的收集,使用DSYMTools工具進行日志分析及代碼定位。
- 在Podfile中使用pod 'KSCrash'然后pod install安裝KSCrash庫,也可以使用代碼集成的方式,這里不做介紹
- 新建CrashReportFilter類遵循KSCrashReportFilter協議,實現協議方法
- (void)filterReports:(NSArray *)reports onCompletion:(KSCrashReportFilterCompletion)onCompletion
具體代碼如下:
- CrashReportFilter.h
#import <Foundation/Foundation.h>
#import <KSCrash/KSCrash.h>
@interface CrashReportFilter : NSObject<KSCrashReportFilter>
@end
- CrashReportFilter.m
#import "CrashReportFilter.h"
#import <KSCrash/KSCrash.h>
#import "KSJSONCodecObjC.h"
#import <KSCrash/KSHTTPMultipartPostBody.h>
#import "Network.h"
@implementation CrashReportFilter
+ (CrashReportFilter*)sink {
return [[CrashReportFilter alloc]init] ;
}
- (CrashReportFilter*)defaultCrashReportFilterSet{
return self;
}
- (void)filterReports:(NSArray *)reports
onCompletion:(KSCrashReportFilterCompletion)onCompletion{
NSError *error;
for (id object in reports) {
NSData *jsonData = [KSJSONCodec encode:object options:KSJSONEncodeOptionSorted error:&error];
KSHTTPMultipartPostBody *body = [[KSHTTPMultipartPostBody alloc] init];
[body appendData:jsonData name:@"formFile" contentType:@"application/json" filename:@"reports.json"];
[[Network share] uploadCrashByData:[body data] contengType:body.contentType completion:^(NSError * _Nullable error) {
kscrash_callCompletion(onCompletion, reports, error == nil, error);
}];
}
}
@end
- 新建CrashInstallation類繼承KSCrashInstallation,重寫父類方法
- (id<KSCrashReportFilter>)sink
,該方法返回CrashReportFilter上報過濾器。 - CrashInstallation.h
#import <KSCrash/KSCrash.h>
#import "CrashReportFilter.h"
#import <KSCrash/KSCrashInstallation.h>
@interface CrashInstallation : KSCrashInstallation
+(CrashInstallation *)share;
@end
- CrashInstallation.m
#import "CrashInstallation.h"
#import <KSCrash/KSCrashInstallation+Private.h>
@implementation CrashInstallation
#pragma 單列方法
+(CrashInstallation *)share {
static CrashInstallation *shareManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
shareManager = [[CrashInstallation alloc] init];
});
return shareManager;
}
- (id)init {
self = [super initWithRequiredProperties:@[]];
return self;
}
- (id<KSCrashReportFilter>)sink {
return [[CrashReportFilter alloc]init];
}
@end
- 調用CrashInstallation內的方法sendAllReportsWithCompletion上傳日志
- (void)uploadCrashLog:(nullable CrashBlock)completion {
CrashInstallation *installation = [CrashInstallation share];
[installation install];
// 上傳成功刪除本地日志
[KSCrash sharedInstance].deleteBehaviorAfterSendAll = KSCDeleteOnSucess;
// 自定義user json數據
[KSCrash sharedInstance].userInfo = @{
@"MachineId": @"8179C19D-5ADC-4C9F-A768-99999999",
@"PackageId": @"包名",
@"PatchVersionCode": @(1),
@"Type": @"iOS",
@"VersionCode": @"版本號"
}
[installation sendAllReportsWithCompletion:^(NSArray *filteredReports, BOOL completed, NSError *error) {
if (completion) {
completion(error);
}
}];
}
-
文件格式
GitHub set up
其中user對應json可由用戶自定義,這里我定義了如圖所示的五個字段,用于標記應用的相關信息,在上面代碼中
[KSCrash sharedInstance].userInfo = @{};就是設置user對應json數據。其余的字段report、binary_images、process、system、crash、debug等為KSCrash框架定義的字段。需要和服務端約定相應的解析格式。
崩潰測試
- 崩潰測試必須在真機上并且不能Xcode運行調試,目前我們的崩潰日志收集邏輯是下一次啟動時上傳之前閃退的日志,上傳完成后刪除本地存儲的閃退日志(刪除邏輯由KSCrash內部處理)。閃退測試代碼如下:
NSArray *testArray = @[@"s1",@"s2"];
NSLog(@"%@",testArray[10]);
- 目前我們的邏輯在應用啟動的時候上傳奔潰日志
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self uploadCrashLog:nil];
}
日志分析及定位
分析日志使用DSYMTools工具,每次打包發布時,項目目錄都存在符號表,查看符號表步驟如下:
Xcode->Window->Organizer->對應的打包記錄右鍵->Show in finder->xxxx.xcarchive->顯示包內容->dSYMs目錄下,會有多個。將xxx.app.dSYM符號表文件拖至DSYMTools工具中,如下圖所示,選擇對于的cpu類型。根據收集到的日志,貼入默認地址和錯誤地址,即可分析定位異常閃退代碼。符號表文件xxx.app.dSYM必須和ipad包一一對應。
小結
本文主要使用KSCrash收集日志并將日志上傳至自己服務端,更服務端解析展示的日志詳情,借助DSYMTools進行日志分析、定位然后問題修復,DSYMTools使用寫得有點粗糙,大家可以自行DSYMTools的使用。
寫得不好的地方,歡迎大家指正。