iOS利用NSLogger和CocoaLumberjack打造日志系統(tǒng)(異常捕捉)

前言

最近剛接手一個(gè)新項(xiàng)目,被分派到一個(gè)日志功能的需求,我們的需求是把日志記錄到本地,然后讓用戶上傳到服務(wù)端,我分別嘗試了用NSLogger和CocoaLumberjack完成便锨,下面說下具體過程。

過程

** NSLogger**
github地址
NSLogger的導(dǎo)入十分簡單我碟,以下是github上的Installation

Step 1. Download the NSLogger desktop app on your Mac.
Step 2. Add the NSLogger framework to your project.
Step 3. There is no step 3…

NSLogger在mac端有一個(gè)專門查看日志的客戶端軟件放案,可在github上下載。
而在客戶端中保存的日志格式為.rawnsloggerdata矫俺。LoggerSetBufferFile這句代碼讓你設(shè)置日志保存的位置吱殉。如下:

NSString *cacheDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];  
NSString *logPath = [cacheDirectory stringByAppendingPathComponent:@"log.rawnsloggerdata"];  
LoggerSetBufferFile(NULL, (__bridge CFStringRef)logPath); 

導(dǎo)入框架后,為了方便調(diào)用厘托,可以按照自己的想法先定義宏定義

#define NSLog(...)  LogMessageF(__FILE__, __LINE__, __FUNCTION__, @"NSLog", 0, __VA_ARGS__)

下面只要在你想打印日志的地方加入NSLog()即可友雳。

需要注意的是:當(dāng)電腦和測試機(jī)處于同一個(gè)局域網(wǎng)內(nèi),且NSLogger Viewer開啟時(shí)铅匹,NSLogger Viewer會(huì)將手機(jī)客戶端運(yùn)行時(shí)的日志實(shí)時(shí)顯示押赊,而此時(shí)這部分日志是不會(huì)寫入手機(jī)客戶端本地的,只有NSLogger Viewer沒開啟監(jiān)控包斑,日志才會(huì)寫入本地流礁,這點(diǎn)要注意!B薹帷神帅!

另外,NSLogger支持多種數(shù)據(jù)類型萌抵,如文件找御,圖片,文字等等绍填,有需要同學(xué)可以深入研究下萎坷。

因?yàn)镹SLogger只能把日志保存.rawnsloggerdata格式,并且只能在mac上用相應(yīng)客戶端查看沐兰,不符合我們的需求,于是蔽挠,我用了另一個(gè)框架-CocoaLumberjack住闯。

** CocoaLumberjack**
github地址
導(dǎo)入框架可參考這篇文章,寫得不錯(cuò)瓜浸,下面也根據(jù)我自身的需求大概說下:

首先說下CocoaLumberjack的日志級(jí)別:

LOG_LEVEL_ERROR:如果設(shè)置為LOG_LEVEL_ERROR,僅僅能看到Error相關(guān)的日志輸出比原。
LOG_LEVEL_WARN:如果設(shè)置為LOG_LEVEL_WARN插佛,能看到Error、Warn相關(guān)的日志輸出量窘。
LOG_LEVEL_INFO:如果設(shè)置為LOG_LEVEL_INFO雇寇,能夠看到Error、Warn蚌铜、Info相關(guān)的日志輸出锨侯。
LOG_LEVEL_DEBUG:如果設(shè)置為LOG_LEVEL_DEBUG,能夠看到Error/Warn/Info/Debug相關(guān)的日志輸出冬殃。
LOG_LEVEL_VERBOSE:如果設(shè)置為LOG_FLAG_VERBOSE囚痴,能夠看到Error/Warn/Info/Debug/Verbose相關(guān)日志輸出。
LOG_LEVEL_OFF:不輸出日志

CocoaLumberjack記錄日志有幾種方式审葬,可以根據(jù)自己的需求選擇是否導(dǎo)入
DDASLLogger(發(fā)送日志語句到蘋果的日志系統(tǒng)深滚,以便它們顯示在Console.app上)
DDTTYLoyger(發(fā)送日志語句到Xcode控制臺(tái),如果可用)
DDFIleLoger(把日志語句發(fā)送至文件)
因?yàn)槲抑恍枰讶罩景l(fā)送控制臺(tái)和記錄在文件涣觉,所以我只導(dǎo)入了DDTTYLoyger和DDFIleLoger

在pch頭文件設(shè)置全局日志等級(jí)

static const DDLogLevel ddLogLevel = DDLogLevelVerbose;

DDLogLevel 定義了全局的 log 等級(jí)痴荐,DDLogFlag 是我們打 log 時(shí)設(shè)定的 log 等級(jí),CocoaLumberjack 會(huì)比較兩者官册,如果 flag 低于 level生兆,則不會(huì)打 log:

//在appdelegate中初始化
    //發(fā)送日志語句到Xcode控制臺(tái)
    [DDLog addLogger:[DDTTYLogger sharedInstance]];
    //把日志語句發(fā)送至文件
    DDFileLogger *fileLogger = [[DDFileLogger alloc] init];
    fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling
    fileLogger.logFileManager.maximumNumberOfLogFiles = 7;
    [DDLog addLogger:fileLogger withLevel:DDLogLevelError];

在實(shí)際應(yīng)用中我定義了兩個(gè)不同日志等級(jí)的宏

//INFO級(jí)別
#define HZLogInfo(format, ...) DDLogInfo((@"[%@][Line:%d]:" format), [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, ## __VA_ARGS__)
//Error級(jí)別
#define HZLogError(format, ...) DDLogError((@"[%@][Line:%d]:" format), [[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__, ## __VA_ARGS__)

解釋下上面代碼:
我設(shè)置全局日志等級(jí)為DDLogLevelVerbose,可打印Error/Warn/Info/Debug/Verbose相關(guān)等級(jí)的日志攀隔,當(dāng)然這里還可以根據(jù)debug和release設(shè)置不同的等級(jí)皂贩。

另外,導(dǎo)入DDTTYLogger沒設(shè)置level昆汹,這里會(huì)默認(rèn)打印全部等級(jí)日志明刷,而DDFileLogger我設(shè)置了DDLogLevelError等級(jí),所以只有error等級(jí)日志才能寫入文件满粗。

所以我定義的兩句宏:
HZLogInfo寫入的是INFO級(jí)別的日志辈末,所以這類日志只能顯示在控制臺(tái),而不能寫入文件映皆。
HZLogError是ERROR級(jí)別日志挤聘,所以這類日志不僅顯示在控制臺(tái),還可以寫入文件捅彻。
當(dāng)然各位可以根據(jù)自己需求而定组去,CocoaLumberjack記錄的本地日志格式為.log格式,上傳到服務(wù)器時(shí)不需特定在mac端觀看步淹,滿足我們的需求从隆。

另外诚撵,我的需求中還需要捕獲異常并寫入日志,這篇異常捕捉的文章寫得十分詳細(xì)键闺,推薦給大家寿烟。要注意的是,使用 NSUncaughtExceptionHandler 捕獲 NSException辛燥,后注冊(cè)的NSUncaughtExceptionHandler會(huì)把前面注冊(cè)的handler覆蓋筛武,在我們的項(xiàng)目中就有這樣的問題。正確的做法是利用NSGetUncaughtExceptionHandler拿到上一個(gè)注冊(cè)的Handler挎塌,處理完自己的Handler后再把exception傳給上一個(gè)Handler徘六。示例如下

static NSUncaughtExceptionHandler *previousUncaughtExceptionHandler;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   //保存之前的Handler
   previousUncaughtExceptionHandler = NSGetUncaughtExceptionHandler();
   // 將下面C函數(shù)的函數(shù)地址當(dāng)做參數(shù)
  NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);
   return YES;
}

void UncaughtExceptionHandler(NSException *exception){
   // 錯(cuò)誤reason
    NSString *reason = [exception reason];
    // exception name
    NSString *name = [exception name];
    //異常的堆棧信息
    NSArray *stackArray = [exception callStackSymbols];
    //拼接錯(cuò)誤信息
    NSString *exceptionInfo = [NSString stringWithFormat:@" Exception reason: %@\nException name: %@\nException stack:%@", reason , name , stackArray];
   //在此處理我們自己的Handler

    //調(diào)用之前注冊(cè)的Handler
    previousUncaughtExceptionHandler(exception);
}

NSSetUncaughtExceptionHandler()函數(shù)指針的惡意覆蓋的問題就解決了。參考文章

結(jié)束

學(xué)習(xí)之路勃蜘,與君共勉硕噩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市缭贡,隨后出現(xiàn)的幾起案子炉擅,更是在濱河造成了極大的恐慌,老刑警劉巖阳惹,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谍失,死亡現(xiàn)場離奇詭異,居然都是意外死亡莹汤,警方通過查閱死者的電腦和手機(jī)快鱼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來纲岭,“玉大人抹竹,你說我怎么就攤上這事≈钩保” “怎么了窃判?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長喇闸。 經(jīng)常有香客問我袄琳,道長,這世上最難降的妖魔是什么燃乍? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任唆樊,我火速辦了婚禮,結(jié)果婚禮上刻蟹,老公的妹妹穿的比我還像新娘逗旁。我一直安慰自己,他們只是感情好舆瘪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布痢艺。 她就那樣靜靜地躺著仓洼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪堤舒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天哺呜,我揣著相機(jī)與錄音舌缤,去河邊找鬼。 笑死某残,一個(gè)胖子當(dāng)著我的面吹牛国撵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播玻墅,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼介牙,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了澳厢?” 一聲冷哼從身側(cè)響起环础,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎剩拢,沒想到半個(gè)月后线得,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡徐伐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年贯钩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片办素。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡角雷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出性穿,到底是詐尸還是另有隱情勺三,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布季二,位于F島的核電站檩咱,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏胯舷。R本人自食惡果不足惜刻蚯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望桑嘶。 院中可真熱鬧炊汹,春花似錦、人聲如沸逃顶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至霸褒,卻和暖如春伴找,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背废菱。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國打工技矮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人殊轴。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓衰倦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親旁理。 傳聞我的和親對(duì)象是個(gè)殘疾皇子樊零,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 在應(yīng)用程序中添加日志記錄總的來說基于三個(gè)目的:監(jiān)視代碼中變量的變化情況,周期性的記錄到文件中供其他應(yīng)用進(jìn)行統(tǒng)計(jì)分析...
    時(shí)待吾閱讀 5,041評(píng)論 1 13
  • 在應(yīng)用程序中添加日志記錄總的來說基于三個(gè)目的:監(jiān)視代碼中變量的變化情況孽文,周期性的記錄到文件中供其他應(yīng)用進(jìn)行統(tǒng)計(jì)分析...
    時(shí)待吾閱讀 4,985評(píng)論 0 6
  • 會(huì)的不難驻襟,難的不會(huì),這大概就是溫習(xí)舊知識(shí)和學(xué)習(xí)新知識(shí)時(shí)的感受了吧叛溢。 這幾天百度Debug日志管理塑悼,利用CocoaL...
    plantseeds閱讀 12,879評(píng)論 9 62
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)楷掉,斷路器厢蒜,智...
    卡卡羅2017閱讀 134,652評(píng)論 18 139
  • Spring Boot-日志配置(超詳細(xì)) 更新日志:20170810 更新通過 application.yml傳...
    inke閱讀 67,323評(píng)論 9 122