(20160604)開源第三方學習之CocoaLumberjack,cocoalumberjack
CocoaLumberjack是一個很好用的日誌列印工具,它可以協助我們把工程中的日誌資訊列印到終端或者輸出到檔案中。
地址:https://github.com/CocoaLumberjack/CocoaLumberjack
類圖:
一:外掛程式的運用
因為網上已經對CocoaLumberjack的運用都有很詳細的介紹,有部分內容整理源自於網路結合項目中的運用進行講解;
1.1:DDLog輸出的類型
DDLog:基礎類,必須引入的。DDASLLogger:支援將調試語句寫入到蘋果的日誌中。一般正對Mac開發。可選。DDTTYLogger:支援將調試語句寫入xCode控制台。我們即使要用它。可選。DDFileLogger:支援將調試語句寫入到檔案系統。可選。
1.2: DDLog日誌等級種類
DDLogError:定義輸出錯誤文本DDLogWarn:定義輸出警告文本DDLogInfo:定義輸出資訊文本DDLogDebug:定義輸出調試文本DDLogVerbose:定義輸出詳細文本提供的記錄層級為:LOG_LEVEL_ERROR:只顯示錯誤記錄檔。LOG_LEVEL_WARN:包括:LOG_LEVEL_ERRORLOG_LEVEL_INFO:包括:LOG_LEVEL_WARNLOG_LEVEL_DEBUG:包括:LOG_LEVEL_INFOLOG_LEVEL_VERBOSE:包括:LOG_LEVEL_DEBUGLOG_LEVEL_OFF:關閉日誌
1.3: 設定不同等級顏色
[[DDTTYLogger sharedInstance] setColorsEnabled:YES];// 啟用顏色區分[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor whiteColor] backgroundColor:[UIColor grayColor] forFlag:DDLogFlagVerbose]; //設定文字為白色,背景為灰色。[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor redColor] backgroundColor:[UIColor whiteColor] forFlag:DDLogFlagDebug];[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor cyanColor] backgroundColor:[UIColor blueColor] forFlag:DDLogFlagInfo];[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor lightGrayColor] backgroundColor:[UIColor orangeColor] forFlag:DDLogFlagWarning];[[DDTTYLogger sharedInstance] setForegroundColor:[UIColor whiteColor] backgroundColor:[UIColor redColor] forFlag:DDLogFlagError];
注意:顯示顏色是指標對XCode控制台的輸出顯示,還要結合外掛程式XcodeColors(地址:https://github.com/robbiehanson/XcodeColors);然後要增加如下的setenv代碼,它的位置放在上面,否則將沒有效果;
setenv("XcodeColors", "YES", 0);[DDLog addLogger:[DDTTYLogger sharedInstance]];
1.4:設定輸出日誌的格式
因為在輸出時我們希望獲得更多的資訊,DDLog可以自訂設定一個格式,從而獲得日誌詳細資料;下面這個類是我們項目中運用:
ZULoggerFormatter* formatter = [[ZULoggerFormatter alloc] init];[[DDTTYLogger sharedInstance] setLogFormatter:formatter]; //目前是在DDTTYLogger類型上顯示,也可以加到輸入到檔案時
格式類:ZULoggerFormatter
@interface ZULoggerFormatter: NSObject<DDLogFormatter>@end#import "ZULoggerFormatter.h"#import "NSDate+Utilities.h"@implementation ZULoggerFormatter {}- (NSString *)formatLogMessage:(DDLogMessage *)logMessage { NSString *logLevel = nil; switch (logMessage.flag) { case DDLogFlagError: logLevel = @"[ERROR]"; break; case DDLogFlagWarning: logLevel = @"[WARN]"; break; case DDLogFlagInfo: logLevel = @"[INFO]"; break; case DDLogFlagDebug: logLevel = @"[DEBUG]"; break; default: logLevel = @"[VBOSE]"; break; } NSString *formatStr = [NSString stringWithFormat:@"%@ %@ [%@][line %ld] %@ %@", logLevel, [logMessage.timestamp stringWithFormat:@"yyyy-MM-dd HH:mm:ss.S"], logMessage.fileName, logMessage.line, logMessage.function, logMessage.message]; return formatStr;}@end
1.5 設定宏取代NSLog
#if Product || Local#define NSLog(...) DDLogVerbose(__VA_ARGS__)#define Log(...) DDLogVerbose(__VA_ARGS__)#else#define NSLog(...) {}#define Log(...) {}#endif#define LogError(...) DDLogError(__VA_ARGS__)
這樣就可以把項目中那些NSLog也替換成DDLogVerbose層級的錯誤;
1.6 設定不同環境輸出日誌等級
#if Product ||Localstatic const int ddLogLevel = LOG_LEVEL_VERBOSE;#elsestatic const int ddLogLevel = LOG_LEVEL_ERROR;#endif
1.7 設定輸出到檔案
- (DDFileLogger *)fileLogger{ if (!_fileLogger) { DDFileLogger *fileLogger = [[DDFileLogger alloc] init]; fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling fileLogger.logFileManager.maximumNumberOfLogFiles = 7; _fileLogger = fileLogger; } return _fileLogger;}
如果沒有設定,它是有提供相應的預設值:
unsigned long long const kDDDefaultLogMaxFileSize = 1024 * 1024; // 1 MB 一個檔案大小NSTimeInterval const kDDDefaultLogRollingFrequency = 60 * 60 * 24; // 24 Hours 一天NSUInteger const kDDDefaultLogMaxNumLogFiles = 5; // 5 Files 五個unsigned long long const kDDDefaultLogFilesDiskQuota = 20 * 1024 * 1024; // 20 MB 總共
如果有儲存路徑(可以設定paths):
NSString *appName = [[NSProcessInfo processInfo] processName];NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);NSString *basePath = ([paths count] > 0) ? paths[0] : NSTemporaryDirectory();NSString *logsDirectory = [[basePath stringByAppendingPathComponent:@"Logs"] stringByAppendingPathComponent:appName];
1.8 分享項目用到的日誌管理類
#import <Foundation/Foundation.h>#import <CocoaLumberjack.h>#import "ZULoggerFormatter.h"@interface MyFileLogger : NSObject@property (nonatomic, strong, readwrite) DDFileLogger *fileLogger;+(MyFileLogger *)sharedManager;@end#import "MyFileLogger.h"@implementation MyFileLogger#pragma mark - Inititlization- (instancetype)init{ self = [super init]; if (self) { [self configureLogging]; } return self;}#pragma mark 單例模式static MyFileLogger *sharedManager=nil;+(MyFileLogger *)sharedManager{ static dispatch_once_t once; dispatch_once(&once, ^{ sharedManager=[[self alloc]init]; }); return sharedManager;}#pragma mark - Configuration- (void)configureLogging{ setenv("XcodeColors", "YES", 0); [DDLog addLogger:[DDASLLogger sharedInstance]]; [DDLog addLogger:[DDTTYLogger sharedInstance]]; [[DDTTYLogger sharedInstance] setColorsEnabled:YES]; [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor blueColor] backgroundColor:nil forFlag:DDLogFlagInfo]; [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor purpleColor] backgroundColor:nil forFlag:DDLogFlagDebug]; [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor redColor] backgroundColor:nil forFlag:DDLogFlagError]; [[DDTTYLogger sharedInstance] setForegroundColor:[UIColor greenColor] backgroundColor:nil forFlag:DDLogFlagVerbose]; ZULoggerFormatter* formatter = [[ZULoggerFormatter alloc] init]; [[DDTTYLogger sharedInstance] setLogFormatter:formatter]; [DDLog addLogger:self.fileLogger];}#pragma mark - Getters- (DDFileLogger *)fileLogger{ if (!_fileLogger) { DDFileLogger *fileLogger = [[DDFileLogger alloc] init]; fileLogger.rollingFrequency = 60 * 60 * 24; // 24 hour rolling fileLogger.logFileManager.maximumNumberOfLogFiles = 7; _fileLogger = fileLogger; } return _fileLogger;}@end
二:知識點
2.1 關於等級包含的設定,DDLogLevelAll顯示所有,基它則依次降底跟相互包含;可以通過這個代碼瞭解到枚舉的設定;
typedef NS_OPTIONS(NSUInteger, DDLogFlag){ /** * 0...00001 DDLogFlagError */ DDLogFlagError = (1 << 0), /** * 0...00010 DDLogFlagWarning */ DDLogFlagWarning = (1 << 1), /** * 0...00100 DDLogFlagInfo */ DDLogFlagInfo = (1 << 2), /** * 0...01000 DDLogFlagDebug */ DDLogFlagDebug = (1 << 3), /** * 0...10000 DDLogFlagVerbose */ DDLogFlagVerbose = (1 << 4)};/** * Log levels are used to filter out logs. Used together with flags. */typedef NS_ENUM(NSUInteger, DDLogLevel){ /** * No logs */ DDLogLevelOff = 0, /** * Error logs only */ DDLogLevelError = (DDLogFlagError), /** * Error and warning logs */ DDLogLevelWarning = (DDLogLevelError | DDLogFlagWarning), /** * Error, warning and info logs */ DDLogLevelInfo = (DDLogLevelWarning | DDLogFlagInfo), /** * Error, warning, info and debug logs */ DDLogLevelDebug = (DDLogLevelInfo | DDLogFlagDebug), /** * Error, warning, info, debug and verbose logs */ DDLogLevelVerbose = (DDLogLevelDebug | DDLogFlagVerbose), /** * All logs (1...11111) */ DDLogLevelAll = NSUIntegerMax};
增加相應的宏進行處理
#define NSLogError(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 1) NSLog((frmt), ##__VA_ARGS__); } while(0)#define NSLogWarn(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 2) NSLog((frmt), ##__VA_ARGS__); } while(0)#define NSLogInfo(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 3) NSLog((frmt), ##__VA_ARGS__); } while(0)#define NSLogDebug(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 4) NSLog((frmt), ##__VA_ARGS__); } while(0)#define NSLogVerbose(frmt, ...) do{ if(DD_NSLOG_LEVEL >= 5) NSLog((frmt), ##__VA_ARGS__); } while(0)
2.2:進程類NSProcessInfo方法
+(NSProcessInfo*)processInfo //返回當前進程的資訊-(NSArray*)arguments //以NSString對象數組的形式返回當前進程的參數-(NSDictionary *)environment //返回變數/值對詞典,以描述當前的環境變數(比如PATH和HOME)及其值-(int)processIdentifier //返回進程標識符,它是作業系統賦予進程的唯一數字,用於識別每個正在啟動並執行進程-(NSString*)processName //返回當前正在執行的進程名稱-(NSString *)globallyUniqueString //每次調用這個方法時,都返回不同的單值字串,可以用這個字串產生單值臨時檔案名稱-(NSString *)hostname //返回主機系統的名稱(在筆者的Mac OS x系統中,返回的是mac-mato-ipad.local)-(NSUInteger)operatingSystem //返回表示作業系統的數字(在筆者的Mac OS x系統中,返回的是5)-(NSString *)operatingSystemName //返回作業系統的名稱(筆者的Mac OS x系統中返回NSMACHOperatingSystem,可能返回的值定義在NSProgressInfo.h檔案中)-(NSString *)operatingSystemVersionString //返回作業系統的目前的版本(筆者的Mac OS x系統中返回Version 10.7.5 (Build 11G56))-(void)setProcessName:(NSString *)name //將當前進程名稱設定為name。應該謹慎地使用這個方法,應為關於進程名稱存在一些假設(比如使用者預設的設定)
例如:NSString *appName = [[NSProcessInfo processInfo] processName];
2.3: lengthOfBytesUsingEncoding:NSUTF8StringEncoding
用於計算含有中英文的字串長度,包含一個中文字用上面的方法時會轉化成三個位元組,其它一個位元組;int len = [textField.text lengthOfBytesUsingEncoding:NSUTF8StringEncoding];