CocoaLumberjack 是 iOS 下强大的日志解决方案,项目开发中,需要将不同模块代码下的 Log 输出到不同文件。本文解决了这一问题。
- 自定义输出的标签和level(分文件用)
- 自定义DDLogFileManagerDefault,重写文件存储文件的路径和名称。
- 利用DDContextWhitelistFilterLogFormatter设置白名单
自定义宏
// HLUMailLog.h
#import <CocoaLumberjack/CocoaLumberjack.h>
/**
flag 系统默认枚举值的位移范围是 0 到 4,不要和宿主 app 的自定义枚举重复
context 系统默认是0,不要和宿主 app 的自定义 context 重复
*/
#define LOG_FLAG_MAIL (1 << 15)
#define LOG_CONTEXT_MAIL 15
// 使用 HLULog 代替 DDLog,防止项目中误用 DDLog
#undef DDLogError
#undef DDLogWarn
#undef DDLogInfo
#undef DDLogDebug
#undef DDLogVerbose
// 自定义 4 个 Log 宏
#define HLULogError(frmt, ...) LOG_MAYBE(YES, ddLogLevel, DDLogFlagError, LOG_CONTEXT_MAIL, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define HLULogWarn(frmt, ...) LOG_MAYBE(YES, ddLogLevel, DDLogFlagWarning, LOG_CONTEXT_MAIL, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define HLULogInfo(frmt, ...) LOG_MAYBE(YES, ddLogLevel, DDLogFlagInfo, LOG_CONTEXT_MAIL, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define HLULogDebug(frmt, ...) LOG_MAYBE(YES, ddLogLevel, DDLogFlagDebug, LOG_CONTEXT_MAIL, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
#define HLULogVerbose(frmt, ...) LOG_MAYBE(YES, ddLogLevel, DDLogFlagVerbose, LOG_CONTEXT_MAIL, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
// 可能会报类型错误,所以用(DDLogLevel)强转一下
#ifdef DEBUG
static const DDLogLevel ddLogLevel = (DDLogLevel)(DDLogLevelVerbose | LOG_FLAG_MAIL);
#else
static const DDLogLevel ddLogLevel = (DDLogLevel)(DDLogLevelInfo | LOG_FLAG_MAIL);
#endif
实现 LogFormatter
@interface HLULogFormatter : DDContextWhitelistFilterLogFormatter
/**
这个类继承于 DDContextWhitelistFilterLogFormatter
1. 利用加白名单实现分文件输出
2. 重载formatLogMessage:方法,实现输出内容格式化
*/
@end
// HLULogFormatter.m
- (NSString *)formatLogMessage:(DDLogMessage *)logMessage
{
NSString *logLevel;
switch (logMessage->_flag) {
case DDLogFlagError : logLevel = @"Error"; break;
case DDLogFlagWarning : logLevel = @"Warning"; break;
case DDLogFlagInfo : logLevel = @"Info"; break;
case DDLogFlagDebug : logLevel = @"Debug"; break;
case DDLogFlagVerbose : logLevel = @"Verbose"; break;
default : logLevel = @"Default"; break;
}
NSDate *date = logMessage->_timestamp;
NSTimeZone *zone = [NSTimeZone systemTimeZone];
NSTimeInterval time = [zone secondsFromGMTForDate:date];
NSDate *nowDate = [date dateByAddingTimeInterval:time];
return [NSString stringWithFormat:@"%@ | %@ | %@ | %@ | %@", nowDate, logLevel, logMessage->_fileName, logMessage->_function, logMessage->_message];
}
开启 Logger
// 在 app delege 中开启 Logger
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *logPath = [paths.firstObject stringByAppendingPathComponent:@"otherLogs/YouziMail"]; // 输出到一个指定的文件夹
DDLogFileManagerDefault *mailFileManager = [[DDLogFileManagerDefault alloc] initWithLogsDirectory:logPath];
DDFileLogger *mailLogger = [[DDFileLogger alloc] initWithLogFileManager:mailFileManager];
mailLogger.maximumFileSize = 1024 * 1024; //单个日志最大1M
mailLogger.rollingFrequency = 2 * 60 * 60 * 24; // 保存周期2天
mailLogger.logFileManager.maximumNumberOfLogFiles = 7;
HLULogFormatter *mailFormatter = [[HLULogFormatter alloc] init];
[mailFormatter addToWhitelist:LOG_CONTEXT_MAIL];
[mailLogger setLogFormatter:mailFormatter];
[DDLog addLogger:mailLogger withLevel:ddLogLevel];