CocoaLumberjack 日志分文件输出

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];

参考

推荐阅读更多精彩内容