美文网首页
控制日志的开关

控制日志的开关

作者: 大成小栈 | 来源:发表于2019-10-30 19:24 被阅读0次

在开发过程中打印日志功能是必不可少的,日志的处理主要分为以下几种:

  • Debug/Release模式下日志的处理;
  • 将日志记录在本地文件,并上传服务器;
  • 由业务App控制是否开启日志。
1. Debug/Release模式下日志的处理

第一点在开发业务App时最常使用,一行语句就搞定:

#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。

2. 将日志记录在本地文件

将日志记录在本地文件常用三方库CocoaLumberjack来处理,我们通过这个库可以将日志输出至控制台,也可以写在本地文件中,我们还可以设置输出日志等级。具体CocoaLumberjack的使用方式可以参考iOS开发之日志框架CocoaLumberjack的配置与使用详解

3. 兼容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控制台打印,控制台打印直接使用了NSLog()

这样通过宏定义,既能兼容CocoaLumberjack,也能实现log的开关。如果想美观一点实现CocoaLumberjack的“挂载”,请参考iOS App中实现可拆卸一个framework的两种方式

相关文章

  • 控制日志的开关

    在开发过程中打印日志功能是必不可少的,日志的处理主要分为以下几种: Debug/Release模式下日志的处理; ...

  • iOS 控制日志的开关

    级别: ★☆☆☆☆标签:「iOS」「Log」「CocoaLumberjack」作者: dac_1033审校: Qi...

  • 日志 LogR 的使用

    你还在为Log日志发愁吗? LogR是个人使用封装的一个android log库,可以全局控制日志的开关,可以指定...

  • 开启MySQL慢查询日志

    查询慢日志开关是否开启 打开慢查询日志开关 再次查询,发现开关打开了 查询mysql安装路径 慢查询日志默认是放在...

  • mac mysql 日志

    查看日志开关 查看log文件位置 设置开关

  • Paddle-Mobile中的日志打印

    编译时添加宏定义 一、Paddle-Mobile 的日志开关 1.Paddle-Mobile 的日志开关在 cma...

  • 全屋设计(本文仅临时发布)

    全屋设计 一、入户玄关 进门右侧,开关布置or灯具控制凌动开关控制 玄关射灯+客厅大灯+餐厅灯;智能开关控制 玄关...

  • iOS打印日志配置(全局日志和局部日志)

    使用人群:iOS开发人员。本文内容:iOS开发日志的开关控制。 需求:每次打包release版本的时候,需要去掉N...

  • 安全学习-高低压开关2020-12-21

    一:低压电器 低压电器分为控制电器和保护电器。 1:低压控制电器 控制电器主要是负责开关的。 ①:刀开关 刀开关就...

  • 查看windows开关机日志

    查看windows开关机日志 【事件查看器】-->【windows日志】-->【系统】 选择右边【筛选当前日志】 ...

网友评论

      本文标题:控制日志的开关

      本文链接:https://www.haomeiwen.com/subject/kmuevctx.html