級別: ★☆☆☆☆
標籤:「iOS」「Log」「CocoaLumberjack」
做者: dac_1033
審校: QiShare團隊php
在開發過程當中打印日誌功能是必不可少的,日誌的處理主要分爲如下幾種:git
第一點在開發業務App時最常使用,一行語句就搞定:github
#ifdef DEBUG
#define DLog(fmt, ...) {NSLog((@"%s [Line %d]\n " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);}
#else
#define DLog(...)
#endif
複製代碼
若是圖方便,能夠將以上代碼寫到prefix.pch文件中,在須要輸出log的地方調用DLog(...),便可在Debug/Release模式切換時,自動開啓/關閉打印log。objective-c
將日誌記錄在本地文件經常使用三方庫CocoaLumberjack來處理,咱們經過這個庫能夠將日誌輸出至控制檯,也能夠寫在本地文件中,咱們還能夠設置輸出日誌等級。具體CocoaLumberjack的使用方式能夠參考iOS開發之日誌框架CocoaLumberjack的配置與使用詳解服務器
這個場景常常出如今framework開發過程當中,咱們開發一個framework,其中須要本身輸出日誌到本地文件,另外宿主App聯調時,也經常須要主動控制log的開和關。咱們定義了一個LogManager類,LogManager.h代碼以下:微信
@import Foundation;
//#define LUMBERJACK @"LUMBERJACK"
#ifdef LUMBERJACK
#define LOG_LEVEL_DEF ddLogLevelf
#import <CocoaLumberjack/CocoaLumberjack.h>
#else /* LUMBERJACK */
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)
};
typedef NS_ENUM(NSUInteger, DDLogLevel){
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 CustomLog(format,...) [MQTTLog customLogWithFormatString:[NSString stringWithFormat:format, ##__VA_ARGS__]]
#define DDLogVerbose if (ddLogLevel & DDLogFlagVerbose) CustomLog
#define DDLogDebug if (ddLogLevel & DDLogFlagDebug) CustomLog
#define DDLogWarn if (ddLogLevel & DDLogFlagWarning) CustomLog
#define DDLogInfo if (ddLogLevel & DDLogFlagInfo) CustomLog
#define DDLogError if (ddLogLevel & DDLogFlagError) CustomLog
#endif /* LUMBERJACK */
extern DDLogLevel ddLogLevel;
extern BOOL logEnable;
/** MQTTLog lets you define the log level for MQTTClient
* independently of using CocoaLumberjack
*/
@interface MQTTLog: NSObject
// default one is DDLogLevelVerbose
+ (void)setLogLevel:(DDLogLevel)logLevel;
+ (void)setLogEnable:(BOOL)logEnable;
+ (void)customLogWithFormatString:(NSString *)formatString;
@end
複製代碼
LogManager.m代碼以下:框架
#import "MQTTLog.h"
#ifdef LUMBERJACK
// 自定義日誌文件裏 log的格式
@interface DDLogFileFormatter : NSObject <DDLogFormatter>
{
NSDateFormatter *dateFormatter;
}
- (id)init;
- (instancetype)initWithDateFormatter:(NSDateFormatter *)dateFormatter;
@end
@implementation DDLogFileFormatter
- (id)init {
return [self initWithDateFormatter:nil];
}
- (instancetype)initWithDateFormatter:(NSDateFormatter *)aDateFormatter {
if ((self = [super init])) {
if (aDateFormatter) {
dateFormatter = aDateFormatter;
} else {
dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; // 10.4+ style
[dateFormatter setDateFormat:@"yyyyMMdd-HHmmss.SSS"];
}
}
return self;
}
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage {
NSString *dateAndTime = [dateFormatter stringFromDate:(logMessage.timestamp)];
NSString* level;
switch(logMessage.flag) {
case DDLogFlagError:
level=@"E";
break;
case DDLogFlagWarning:
level=@"W";
break;
case DDLogFlagInfo:
level=@"I";
break;
case DDLogFlagDebug:
level=@"D";
break;
case DDLogFlagVerbose:
level=@"V";
break;
default:
level=@"U";
break;
}
NSString *formatStr = [NSString stringWithFormat:@"%@ %@ %d.%@[%@:%ld:%@] %@", level, dateAndTime, getpid(),logMessage.threadID, logMessage.fileName, (unsigned long)logMessage.line, logMessage.function, logMessage.message];
return formatStr;
}
@end
#endif
BOOL mqttLogEnable = NO;
@implementation MQTTLog
DDLogLevel ddLogLevel = DDLogLevelVerbose;
+ (void)setLogLevel:(DDLogLevel)logLevel {
ddLogLevel = logLevel;
}
+ (void)setLogEnable:(BOOL)logEnable {
mqttLogEnable = logEnable;
if (logEnable) {
[MQTTLog startDDLogger];
}
}
+ (void)startDDLogger {
#ifdef LUMBERJACK
#ifdef DEBUG
//[DDLog addLogger:[DDTTYLogger sharedInstance]]; // TTY = Xcode console
[[DDTTYLogger sharedInstance] setColorsEnabled:YES];
[DDLog addLogger:[DDOSLogger sharedInstance]]; // ASL = Apple System Logs
#endif
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; // 10.4+ style
[dateFormatter setDateFormat:@"yyyyMMdd-HHmmss.SSS"];
NSArray *path = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
NSString *folderPath = [NSString stringWithFormat:@"%@/QiTestSDK/QiTestSDKLogs", path[0]];
if (![[NSFileManager defaultManager] fileExistsAtPath:folderPath]) {
[[NSFileManager defaultManager] createDirectoryAtPath:folderPath withIntermediateDirectories:YES attributes:nil error:nil];
}
DDLogFileManagerDefault *fileManager = [[DDLogFileManagerDefault alloc] initWithLogsDirectory:folderPath];
DDFileLogger *fileLogger = [[DDFileLogger alloc] initWithLogFileManager:fileManager];
fileLogger.rollingFrequency = 60 * 60 * 24 * 3; // 3 days rolling
fileLogger.logFileManager.maximumNumberOfLogFiles = 5;
fileLogger.logFileManager.logFilesDiskQuota = 50 * 1024 * 1024; // 50M
fileLogger.maximumFileSize = 10 * 1024 * 1024;
fileLogger.logFormatter = [[DDLogFileFormatter alloc] init];
[DDLog addLogger:fileLogger];
#endif
}
+ (void)customLogWithFormatString:(NSString *)formatString {
if (mqttLogEnable) {// 開啓了Log
NSLog(@"%@", formatString);
}
}
@end
複製代碼
這樣經過宏定義,既能兼容CocoaLumberjack,也能實現log的開關。若是想美觀一點實現CocoaLumberjack的「掛載」,請參考iOS App中實現可拆卸一個framework的兩種方式。函數
小編微信:可加並拉入《QiShare技術交流羣》。工具
關注咱們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公衆號)優化
推薦文章:
iOS App中可拆卸一個framework的兩種方式
自定義WKWebView顯示內容(一)
Swift 5.1 (6) - 函數 Swift 5.1 (5) - 控制流
Xcode11 新建工程中的SceneDelegate
iOS App啓動優化(二)—— 使用「Time Profiler」工具監控App的啓動耗時
iOS App啓動優化(一)—— 瞭解App的啓動流程
iOS WKWebView的基本使用
Swift 5.1 (4) - 集合類型
奇舞週刊