目前大部分iOS的小型開發團隊都不是很重視log,致使不少線上發生的或者用戶反饋的bug難以排查。對於App來講一個好的日誌系統能夠幫助咱們用最小的代價來排查一些疑難bug,咱們惟一要作的就是在合適的位置打印日誌,記錄App的運行情況。這樣作不只僅可讓咱們在debug時查看App運行日誌,還能夠容許App經過某些方式將日誌文件回傳供開發人員分析問題。html
蘋果提供的NSLog
是大多數開發者經常使用的日誌工具,可是NSLog
仍是沒法知足咱們對於Log的其餘需求,如日誌分級、日誌持久化等。另外咱們知道NSLog
其實並非printf
的封裝而是ASL的高級封裝,蘋果在文檔上也說明了NSLog
的設計目的是Logs an error message
,所以咱們若是在開發中大量使用NSLog
,App的性能會變得很是糟糕。關於NSLog的性能問題能夠參看這篇sunnyxx的文章【NSLog效率低下的緣由及嘗試lldb斷點打印Log】git
os.log
來取代NSLog
,咱們但願有一個具備很強擴展性的log庫,使咱們能夠很輕易地將log底層實現替換爲os.log
而沒必要改變原有的log代碼。NSLog
在Mac提供了Console.app
這樣的調試工具,使得咱們即便不在xcode的debug模式下也能夠隨時查看App的日誌。甚至,咱們但願使用windows PC也能夠在非debug模式下查看log。Coolog設計之初就是爲了解決上面所提到的這些需求。Coolog具備高度的可擴展性和靈活性,同時提供了一個瀏覽器的調試工具。目前,Coolog還有不少須要完善的地方,包括瀏覽器調試工具目前也只是一個demo,歡迎你們成爲Coolog的Contributor。github
爲了保證可擴展性和靈活性,Coolog包含了了生成器(COLLogger)、格式化協議與格式化器(COLFormatable和COLLogFormatter)、驅動器(COLLoggerDriver)、引擎(COLEngine)、管理者(COLLogManager),他們之間的關係可見下圖: objective-c
下面咱們來一一說明它們各自的做用。windows
顧名思義,生成器負責最終log的生成,COLLogger
是一個協議。Coolog提供了三種生成器,分別是COLNSLogger
、COLConsoleLogger
、COLFileLogger
,這三個類都實現了COLLogger
協議中- (void)log:(NSString *)logString;
這個方法。在該方法中咱們最終定義了這個類型的log最後的生成方法,log引擎會經過驅動器調用到該方法輸出log。 除了這三種生成器,也能夠本身實現COLLogger
協議來自定義一個生成器。xcode
這個協議只有一個方法,這個方法定義了log的輸出格式。瀏覽器
- (NSString *)completeLogWithType:(COLLogType)type
tag:(NSString *)tag
message:(NSString *)message
date:(NSDate *)date;
複製代碼
格式化器就是實現了COLFormatable
格式化協議的類,默認咱們提供了與上述三種生成器對應的三種格式化器NSLogFormatter
、ConsoleFormatter
、FileFormatter
,他們分別對應原生NSLog、控制檯與瀏覽器工具log和文件log。這個三個類咱們使用了類族提供工廠方法完成初始化,在自定義格式化器時並不須要繼承COLLogFormatter
,是須要實現COLFormatable
協議便可。性能優化
驅動器是一個容器,生成器與格式化器將做爲依賴注入到驅動器中,同時驅動器負責log的級別的配置,實現log分級過濾。log類型分爲5中:Error>Warning>Info>Default>Debug
,過濾的級別分爲7級:LevelOff>LevelError>LevelWarning>LevelInfo>LevelDefault>LevelDebug>LevelAll
,低級別的log可能會被過濾,好比若是當前過濾級別爲LevelInfo
,那麼將只有Error
、Warning
、Info
這三種類型的log會被輸出。最終驅動器將交由log引擎統一管理。架構
引擎負責管理全部的驅動器,由它負責啓動log,引擎能夠隨時移除或者加入單個log驅動器,實現不一樣log的獨立開關。app
[[COLLogManager sharedInstance] setup];
[[COLLogManager sharedInstance] enableFileLog]; // 打開文件log
[[COLLogManager sharedInstance] enableConsoleLog]; // 打開控制檯log
// [[COLLogManager sharedInstance] enableNSLog]; // 通常控制檯log和NSLog不一樣時打開
// Debug下打開全部級別log,Release下打開Info級別以上的log
#ifdef DEBUG
[COLLogManager sharedInstance].level = COLLogLevelAll;
#else
[COLLogManager sharedInstance].level = COLLogLevelInfo;
#endif
複製代碼
CLogError(@"tag", @"%@", @"log content");
CLogE(@"%@", @"log content");
CLogWarning(@"tag", @"%@", @"log content");
CLogW(@"%@", @"log content");
CLogInfo(@"tag", @"%@", @"log content");
CLogI(@"%@", @"log content");
CLogDefault(@"tag", @"%@", @"log content");
CLog(@"%@", @"log content");
CLogDebug(@"tag", @"%@", @"log content");
CLogD(@"%@", @"log content");
複製代碼
首先打開瀏覽器調試功能。
[[COLLogManager sharedInstance] enableRemoteConsole];
複製代碼
將電腦和手機連到同一個wifi下,打開瀏覽器訪問(http://coolog.oss-cn-hangzhou.aliyuncs.com/index.html?host=ws://[YourPhoneIPAddr]:9001/coolog,注意地址後面的參數[YourPhoneIPAddr]替換爲手機的IP地址。
目前效果是下面這樣。
#import "COLLogger.h"
@interface MyLogger : NSObject <COLLogger>
@end
複製代碼
#import "MyLogger.h"
#import <os/log.h>
@implementation MyLogger
@synthesize formatterClass = _formatterClass;
+ (instancetype)logger {
return [[MyLogger alloc] init];
}
// This is your own log method. It will be called by log engine.
- (void)log:(NSString *)logString {
//For example, here below uses os_log as its implementation.
os_log(OS_LOG_DEFAULT, "%{public}s", [logString UTF8String]);
}
@end
複製代碼
#import "COLLogFormatter.h"
@interface MyLogFormatter : NSObject <COLFormatable>
@end
複製代碼
#import "MyLogFormatter.h"
@implementation MyLogFormatter
// The log's format depends on this method.
- (NSString *)completeLogWithType:(COLLogType)type tag:(NSString *)tag message:(NSString *)message date:(NSDate *)date {
return [NSString stringWithFormat:@"tag=[%@], type=[%zd], message=[%@], date=[%@]", tag, type, message, date];
}
@end
複製代碼
COLLoggerDriver *myDriver = [[COLLoggerDriver alloc] initWithLogger:[MyLogger logger]
formatter:[[MyLogFormatter alloc] init]
level:COLLogLevelInfo];
[[COLLogManager sharedInstance].logEngine addDriver:myDriver];
複製代碼
Log是咱們開發過程當中容易忽略的一步,但它又是十分重要的一項工做,咱們要學會如何在合適的位置記錄合適log,這對於咱們復現和排查問題真的有很大的幫助。
目前Coolog仍是頗有不少不完善的地方,包括瀏覽器調試工具也是一個初級的demo狀態,後續工做會放在log的性能優化和調試工具的搜索和過濾功能,包括調試工具的UI也會進一步優化。