iOS 开发高手课
戴铭
前滴滴出行技术专家
42934 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
用户故事 (1讲)
iOS 开发高手课
15
15
1.0x
00:00/00:00
登录|注册

15 | 日志监控:怎样获取 App 中的全量日志?

实现使用 dup2 替换默认句柄的方法
监听设备磁盘空间不足并清理缓存文件
获取全量日志的方法
获取日志文件的目录路径
CocoaLumberjack 的架构
重定向 NSLog 的输出
统一日志系统的使用
使用 DDASLLogCapture 捕获 ASL 日志
ASL 存储日志的方式
使用不侵入的方式获取所有日志
逐个分析各团队使用的日志库
多团队使用不同日志库
课后作业
小结
获取 CocoaLumberjack 日志
获取 NSLog 的日志
解决方法
获取全量日志的挑战
获取全量日志的重要性
问题定位需要更多日志信息
获取 App 中的全量日志
日志监控

该思维导图由 AI 生成,仅供参考

你好,我是戴铭。
我在前面的第 12、13 和 14 三篇文章中,和你分享了崩溃、卡顿、内存问题的监控。一旦监控到问题,我们还需要记录下问题的详细信息,形成日志告知开发者,这样开发者才能够从这些日志中定位问题。
但是,很多问题的定位仅靠问题发生的那一刹那记录的信息是不够的,我们还需要依赖更多的日志信息。
在以前公司还没有全量日志的时候,我发现线上有一个上报到服务器的由数据解析出错而引起崩溃的问题。由于数据解析是在生成数据后在另一个线程延迟执行的,所以很难定位到是谁生成的数据造成了崩溃。
如果这个时候,我能够查看到崩溃前的所有日志,包括手动打的日志和无侵入自动埋点的日志,就能够快速定位到是由谁生成的数据造成了崩溃。这些在 App 里记录的所有日志,比如用于记录用户行为和关键操作的日志,就是全量日志了。
有了更多的信息,才更利于开发者去快速、精准地定位各种复杂问题,并提高解决问题的效率。那么,怎样才能够获取到 App 里更多的日志呢
你可能会觉得获取到全量的日志很容易啊,只要所有数据都通过相同的打日志库,不就可以收集到所有日志了吗?但,现实情况并没有这么简单。
一个 App 很有可能是由多个团队共同开发维护的,不同团队使用的日志库由于历史原因可能都不一样,要么是自己开发的,要么就是使用了不同第三方日志库。如果我们只是为了统一获取日志,而去推动其他团队将以前的日志库代码全部替换掉,明显是不现实的。因为,我们谁也无法确定,这种替换日志库的工作,以后是不是还会再来一次。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入探讨了日志监控在定位应用程序问题中的重要性,以及获取全量日志所面临的挑战和解决方案。作者指出不同团队使用不同的日志库,统一获取全量日志并非简单任务。为解决这一问题,作者提出了逐个分析各团队使用的日志库,并使用不侵入的方式获取所有日志的方法。文章还介绍了如何获取系统自带NSLog的日志,并探讨了iOS 10之后如何获取NSLog日志。通过介绍获取NSLog日志的方法,强调了获取全量日志对于开发者定位和解决应用程序问题的重要性。文章内容丰富,对于开发者来说具有实际指导意义,尤其是在处理不同日志库和获取全量日志方面,提供了有益的解决方案。文章还提到了获取 CocoaLumberjack 日志和小结,强调了收集全量日志的重要性,以及提高分析和解决问题的效率。同时,课后作业和鼓励读者分享观点,增加了互动性和实践性。整体而言,本文内容丰富,涵盖了多种日志获取方法和实践作业,对读者具有一定的指导意义。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《iOS 开发高手课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(17)

  • 最新
  • 精选
  • Geek_97bcf5
    一般大厂的app都不会用NSLog来打印日志的,我不知道滴滴打车是否用NSLog来打印日志,所以,本文的方案并不符合生产环境。日志是需要分类的,需要压缩,需要加密,实时染色等。NSLog根本不可能完成这些功能,所以,大厂的app都有专门的日志框架。各个模块中也不会用NSLog来输出日志。

    作者回复: 对,大厂都有自己的日志框架。可能是一套或者多套。也有很多直接包装了CocoaLumberjack。加解密一般都是安全团队统一处理的,不光用在日志上。

    2019-04-13
    2
    17
  • drunkenMouse
    ASL在iOS10.0之后没法用了。所以CocoaLumberJack无法获取到所有的日志,但除了NSLog日志外,别的日志都能获取到吗?

    作者回复: CocoaLumberJack 其他日志不受影响

    2019-04-13
    2
  • lhjzzu
    上周才第一次用CocoaLumberjack做了日志系统,并且看了fishhook的原理,这次看这篇文章就全用上了,太nice了,对两者的使用和理解更深了。哈哈😄

    作者回复: 赞

    2019-04-14
    1
  • drunkenMouse
    所以,几个人的小团队直接使用统一的日志库就可以了? syslogd是一个进程,保护系统接收分发日志消息的进程? CocoaLumberJack这段有点乱,整理了一下: captureAslLogs方法对ASL日志的处理措施是:将日志消息转换成char * 字符串类型,然后再转成NSString类型,随后将其记录。 记录使用DDLog:log:message:方法。 记录时需要将NSString转成DDLogMessage类型,而DDLogMessage设置了日志级别,所以转换类型后也要设置日志级别。 NSLog的日志级别是Verbose。 最后,iOS10之后,为了兼容新的统一日志系统,需要对NSLog日志的输出进行重定向。iOS10之后CocoaLumberJack获取不到NSLog的日志了?

    作者回复: 是的

    2019-04-13
    1
  • daniel
    static void(*orig_nslog) (NSString *format,...); 这里声明的时候是*号不是&号,声明是一个对象,估计老师那边打错了 还有下面这段代码 va_list va; va_start(va,format); NSLogv(format, va); va_end(va); 可以换成orig_nslog(format) ,这时候我们的orig_nslog就是原来NSLog在Mach-o中的地址了,这时候可以直接拦截使用了,老师希望课里面代码可以检查仔细点再发出来,好多次直接报错,然后又找不到原因,这样挺打击人的。。。还有注释可以再清楚点
    2019-05-31
    8
  • Ant
    温故而知新, 对我来说是反过来说的, 知新而温故。 main函数执行之前 加载可执行文件、 加载动态链接库rebase指针调整和bind符号绑定、 运行时开始处理, objc类注册,category注册,selector唯一性检查, load方法,attribute修饰函数调用, 创建c++静态全局变量
    2019-04-17
    6
  • jimbo
    static void (&orig_nslog)(NSString *format, ...); 这里是不是应该变成 static void (*orig_nslog)(NSString *format, ...); 不然报错
    2019-04-16
    3
  • 小赢一场
    不太明白,获取日志,怎么上传,什么时候上传日志到后台
    2020-04-21
    2
  • jiang
    完成第一次作业,这样便可以无侵入的实现日志上报惹 - (void)viewDidLoad { [super viewDidLoad]; [self outLog]; [self writeMsg]; } - (void)outLog{ self.filePath = [NSString stringWithFormat:@"%@/Documents/LOG", NSHomeDirectory()]; [[NSFileManager defaultManager] createDirectoryAtPath:self.filePath withIntermediateDirectories:YES attributes:nil error:nil]; self.filePath = [self.filePath stringByAppendingString:@"/log.txt"]; [[NSFileManager defaultManager] createFileAtPath:self.filePath contents:nil attributes:nil]; self.fileHandle = [NSFileHandle fileHandleForWritingAtPath:self.filePath]; int fileDesc = self.fileHandle.fileDescriptor; dup2(fileDesc, STDERR_FILENO); } int count = 0; - (void)writeMsg{ count ++; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSString *str = [NSString stringWithFormat:@"+%d",count]; [self writeMsg]; NSLog(@"%@",str); }); }
    2020-11-27
    1
  • zhonglaoban
    所以nslog能输出日志到console.app里面是因为用了asl?
    2020-08-02
    1
收起评论
显示
设置
留言
17
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部