iOS开发-全量日志捕获CocoaLumberjack

前言

全量日志就是app的运行日志打印等等。有时候光凭Crash日志并不能找到并解决问题,如果有CrashApp的日志输出,则会事半功倍。

CocoaLumberjackOSXiOS平台优秀的全量日志抓取第三方库。github链接

此篇文章更着重于分析其实现以及结构组成。

日志重定向

我们通过日志重定向可以进行将控制台的输出日志存储到文件中

- (void)redirectLogToDocumentFolder
{
   
    // 获取沙盒路径
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
    NSString *documentDirectory = [paths objectAtIndex:0];
    // 获取打印输出文件路径
    NSString *fileName = [NSString stringWithFormat:@"myData.log"];
    NSString *logFilePath = [documentDirectory stringByAppendingPathComponent:fileName];
    // 先删除已经存在的文件
    NSFileManager *defaultManager = [NSFileManager defaultManager];
    [defaultManager removeItemAtPath:logFilePath error:nil];
    // 将NSLog的输出重定向到文件,因为C语言的printf打印是往stdout打印的,这里也把它重定向到文件
    freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding],"a+", stdout);
    freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding],"a+", stderr);
}

这样的坏处是,当重定向之后,控制台不再打印日志输出了,虽然我们可以判断xcode是否连接,然后再进行重定向,来解决连接xcode调试的问题。

但是还是有不足,就是当你的日志输出你只想自己看到,而不想影响控制台的输出时,显然重定向不能做到,我们需要自己的日志输出入口,同时还要能监听到系统的日志输出,而不影响控制台的日志。

CocoaLumberjack 就可以帮我们实现这个功能。一般来说我们需要创建3个logger,分别是

  • ASL 用于记录系统的日志输出,这个输出xcode有些不会打印出来
  • TTY 控制台会打印的日志输出
  • File 写入文件中,存为log文件,然后上传,便于分析问题。

Lumberjack组成

传统的NSLog()函数将它的输出指向两个地方:

  • 苹果系统日志ASL (Apple System Logs)
  • StdErr(如果StdErr是一个TTY),所以日志语句显示在Xcode控制台

Capture 捕捉

DDASLLogCaptureCocoaLumberjack中唯一的一个Capture类,用与捕获ASL日志

Logger 输出

logger用于输出日志,有

  • DDASLLogger 用于输出到ASL
  • DDOSLoggeriOS 10之后公开的日志输出方式,用于取代ASL,你可以在官方文档 中查看接口
  • DDTTYLogger 该类为终端输出Xcode控制台输出提供一个日志记录器
  • DDFileLogger 用于将日志输出到文件中,我们一般存储日志文件之后进行压缩。

要实现替换 NSLog() 的功能,您可以简单地添加DDASLLogger和一个DDTTYLogger
但是,如果您选择使用文件记录器(DDFileLogger)(以获得更快的性能),
你可以选择只使用一个文件记录器(DDFileLogger)和一个tty记录器(DDTTYLogger)

message and formatter 消息以及格式化

DDLogMessage是封装的消息实体
DDLogFormatter 是对输出的字符串格式化的类别

你可以对照CocoaLumberjack源码中的Demos进行更好的理解
在这里插入图片描述
里面各种场景都很有参考意义。

ASL 日志系统

ASL (Apple system logger)是苹果公司自己实现的一套输出日志的接口。

通过DDASLLogger.m文件,我们了解到captureAslLogs做了捕捉日志输出的功能

+ (void)captureAslLogs {
   
    @autoreleasepool
    {
   
        /*
           We use ASL_KEY_MSG_ID to see each message once, but there's no
           obvious way to get the "next" ID. To bootstrap the process, we'll
           search by timestamp until we've seen a message.
         */

        struct timeval timeval = {
   
            .tv_sec = 0
        };
        gettimeofday(&timeval, NULL);
        unsigned long long startTime = (unsigned long long)timeval.tv_sec;
        __block unsigned long long lastSeenID = 0;

        /*
           syslogd posts kNotifyASLDBUpdate (com.apple.system.logger.message)
           through the notify API when it saves messages to the ASL database.
           There is some coalescing - currently it is sent at most twice per
           second - but there is no documented guarantee about this. In any
           case, there may be multiple messages per notification.

           Notify notifications don't carry any payload, so we need to search
           for the messages.
         */
        int notifyToken = 0
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值