深入解析iOS日志庫CocoaLumberjack

我們在開發(fā)中經(jīng)常需要打日志,iOS提供的NSLog只能在Xcode里面查看,這種方式有如下限制:

1、只有處于Debug模式下才能在Xcode看到日志,其他情況無能為力。測試、產(chǎn)品等同事在測試和體驗App的時候由于日志沒有記錄到本地,對于一些無法復現(xiàn)或者復現(xiàn)路徑很難的問題肯定束手無策。

2、發(fā)布到App Store的App,下載了這個App的用戶出現(xiàn)了無法復現(xiàn)或者復現(xiàn)路徑很難的問題,我們也只能干著急。

CocoaLumberjack這個開源日志庫就是為了解決上訴兩個問題的。

一、什么是CocoaLumberjack?

CocoaLumberjack是iOS業(yè)界有名的github開源日志庫,提供如下功能:

1、支持日志打印到Xcode控制臺,打印到mac的console程序、打印到文件

2、日志功能支持關(guān)閉和打開,支持Error、Warning、Info、Debug、Verbose、All日志等級

3、支持基于DDLogFormatter協(xié)議自定義日志格式和繼承DDAbstractLogger和協(xié)議DDLogger自定義logger

二、用法

用法很簡單,具體參照github,這里貼一段簡單的代碼

[DDLog addLogger:[DDTTYLogger sharedInstance]]; // TTY = Xcode console

[DDTTYLogger sharedInstance].logFormatter = [[MyCustomDDLogFormatter alloc] init];

DDFileLogger *fileLogger = [[DDFileLogger alloc] init]; // File Logger

fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling

fileLogger.maximumFileSize = 50 * 1024 * 1024; //50MB

fileLogger.logFileManager.maximumNumberOfLogFiles = 7;

fileLogger.logFormatter = [[MyCustomDDLogFormatter alloc] init];

[DDLog addLogger:fileLogger];

三、架構(gòu)圖


梳理一下各個類的作用和關(guān)系:

1、DDLog,全局單例類。此類通過方法+ (void)addLogger:(id)logger保存了一系列繼承于DDAbstractLogger的logger,通過_loggers屬性保存logger,該類相當于一個服務(wù)分發(fā)器,外部調(diào)用DDLogxxx宏(比如DDLogDebug)實際上都會路由到DDLog的log方法,最終通過lt_log方法調(diào)用各個logger的logMessage方法實現(xiàn)日志打印。

2、DDAbstractLogger,實現(xiàn)了協(xié)議DDLogger,所有l(wèi)ogger都繼承于該類。

3、DDLogger協(xié)議,最重要的方法是- (void)logMessage:(DDLogMessage *)logMessage,所有繼承于DDAbstractLogger的logger通過實現(xiàn)該方法進行日志的打印。通過logFormatter屬性保存了日志格式化實例

4、DDLogFormatter,通過方法- (NSString *)formatLogMessage:(DDLogMessage *)logMessage格式化DDLogMessage對象

5、DDTTYLogger,通過該類把日志打印到Xcode控制臺。

6、DDASLLogger,通過該類把日志打印到mac的console程序里面。

7、DDFileLogger,通過該類把日志保存到文件。

8、DDAbstractDatabaseLogger,通過實現(xiàn)該類把日志保存到數(shù)據(jù)庫里面。

四、實現(xiàn)關(guān)鍵點:

1、如何實現(xiàn)日志打印不阻塞主線程?

對于每個繼承于DDAbstractLogger的類比如DDFileLogger,內(nèi)部會創(chuàng)建一個分發(fā)對象_loggerQueue,所有的logMessage方法都會運行在這個_loggerQueue里面。

DDLog類創(chuàng)建了一個串行的分發(fā)隊列_loggingQueue,通過_loggingQueue把外部的DDLogxxx調(diào)用異步路由到lt_log方法里面;通過全局分發(fā)組對象dispatch_group_t _loggingGroup來等待外部的DDLogxxx調(diào)用分發(fā)到相應的logger打印結(jié)束;另外,通過信號量_queueSemaphore來控制queueLogMessage最大調(diào)用量,最大為1000,大于1000將排隊等待。

2、DDFileLogger的工作機制

rollingFrequency和maximumFileSize如何控制單個日志文件?

CocoaLumberjack在訪問最近創(chuàng)建的一個日志文件時,會根據(jù)回滾頻率和日志文件大小決定是否需要創(chuàng)建新的日志文件,如果日志文件存活時間大于等于回滾頻率或者日志文件大小大于等于最大大小,則回滾該日志文件(給該日志文件后綴加上kDDXAttrArchivedName),并且創(chuàng)建一個新的日志文件來存日志;否則繼續(xù)用這個日志文件存日志。日志文件存活時間是以日志文件創(chuàng)建時間為基準的。

每次調(diào)用logMessage方法的時候都會調(diào)用maybeRollLogFileDueToSize檢測日志文件大小是否超過maximumFileSize; 通過dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.loggerQueue)創(chuàng)建一個計時器,定時掃描文件來實現(xiàn)文件存活時間功能。

logFileManager屬性maximumNumberOfLogFiles如何控制一系列日志文件。

通過kvo maximumNumberOfLogFiles 和logFilesDiskQuota調(diào)用deleteOldLogFiles來實現(xiàn)最多保持maximumNumberOfLogFiles個日志文件。

3、如何實現(xiàn)日志文件上傳到自己的服務(wù)器?

后臺下發(fā)一個命令字,打包壓縮日志文件上傳即可。也可以通過自己自定義logger來實現(xiàn)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容