微信号:gh_37ebe37722aa

介绍:txx的笔记分享

实时上报 iOS Log 的实现

2016-05-29 19:25 txx

前言

我们经常会遇到这样一种情况,一个 Bug 在同事特别是老板的手机上特别容易重现,但出于种种原因没法插电脑调试。或者热心用户和你汇报 BUG,出于地域原因只能收购她的手机,明显不可能。这时要是能看到她的实时 Log 就好了。于是我就想了一个相对简单的解决方案。

拿到 Log

首先,你要若想上报 Log,你要有 Log。

我们开发的时候,可以选用 DDLog 替代 NSLog。来达到要求,然而这样的 LOG 是不完整的。因为就算你用宏替换把 NSLog 换成 DDLog,这样收集上来的也只有你代码的 Log 而已。对于第三方的什么统计、推送、支付 SDK,他们的 Log 是拿不到的。

于是怎么办呢?用我们擅长的 Hook 么?留心的童鞋会注意到 NSLog 并不是 OC 方法,而是 C 方法。C 方法可以 Hook 咩?当然可以,但总觉得略扯淡。

经过一番查找(其实我本来就知道),我们发现 Flipboard 的 FLEX 有拿到系统 LOG,看了一下实现。他使用了一个叫做 asl.h 也就是 Apple System Log 来实现的。

于是我们有:


以及对应的 Model:


这里需要注意几个问题:

  1. 最好看一下 FLEXSystemLogTableViewController 的代码,在拿 Log 的时候,如果为了兼容 iOS 7,用了一些很脏的手法。据注释说,是 iOS 7 的 Bug..
  2. 可以注意到 Log 是全量的,所以当项目跑久了,Log 会非常多。主线程来拿明显有点蠢。
  3. 模拟器下因为要做 Filter,效率比 Device 要低很多,轮询间隔 5 秒以上。

内部版本的 Log 处理方案

我开始追求实时的效果,用 Socket.io 的 Client.js 丢到 JSCore 里面来和 terminal 的 socket.io server 做数据通信。

但是最近我在把所有的模块全都换成 Ruby 的时候,这个方案不是那么可行了。毕竟 ruby 有 ruby 的一套东西。以及姜军同学极力安利我在 iOS 上跑一个 Server,于是就这么搞吧。

在 iOS 上跑 Server,如果你不想用 Swift 那堆后端框架的话,只有一个选择:CocoaHTTPServer。这个库坑很多,他的的最后一次提交在 2013 年。但还是能用的,不过这次懒了点,不想手动写 router map 了,毕竟这么点小功能,就上了一个封装(同样最后一次提交在 13 年),参见:https://github.com/mattstevens/RoutingHTTPServer

嗯,作者又是一个 matt,看来这名字容易出 iOS 大牛。

于是,写了几行代码就完成了这项任务:

这里注意一个问题,我们会用 timer 来做 Log 的轮询,且在一个子线程中。而 server 是有自己的线程池的,毕竟server 要支持并发。这样就等于跨线程访问一个很有可能会修改的数组,是有安全隐患的,虽说貌似有问题也无所谓,但强迫症嘛。建议给数组加入临界区,或者上个锁。

最终结果就是这样了:


对了,安利一下 HTTPie 这个命令行工具,JSON 有 Pretty,有高亮,而且语法比 curl 简单。

外部版本的 Log 处理方案

我们不可能在用户手机上跑个 server,然后接一个花生壳之类的东西。所以我们要有一个后台可以上报。然而礼物说平时的工作还是蛮忙的,因为我们不加班 ,后端的大大们是没空给我们写后台的。

自己撸一个后台,又要去麻烦运维大大,于是有没有更优雅的解决方案?

当然有,Leancloud!而且是免费的,毕竟给开发者玩的免费流量已经可以满足要求了,论撸羊毛党的自我修养,撸完七牛,撸leancloud…(这么主动的推荐,Leancloud 有人想给我赞助一波么。不要鲱鱼罐头...

他们有很不错的 SDK,然而太占地方了。我们只需要一个上传接口,一个网络请求配合一个低优先级的队列就可以了。(这里记得多采集点用户设备数据。

于是效果大概是这样的:


后台还支持各种查询建立索引之类的,怎么说也比只会 iOS 开发的我们来说,写出来的东西更好用。

Log 开关

实话实说,我们用户量还是不小的。这样的日活情况下,leancloud 肯定一天不到就能爆流量,于是如何做到动态开启关闭呢?

解决方法有很多种:

之前做过 navigationbar 暴击 20 下。但是总觉得太奇怪了,弃用。

这里推荐 OmniGroup 家的解决方案,用自定义 scheme。比如他们切换语言可以这样:omnifocus:///change-preference?AppleLanguages=。于是我们做一个诸如: liwushuo:///debug?online_log=√ 这样的即可,用户反馈的时候发给她一个链接用 safari 打开重定向过去就好了。

后记

一般大公司都有自己整套日志系统,维护他的人都有可能是一个 Team,而小公司是完全做不来的。所以我们只能 君子生非异也 善假于物也。借用一些第三方的做的很完善的工具来达到同样的效果。这篇文章是我的一些解决方案,希望能给大家一些启发。

如果这篇文章有帮到你的话,请关注我的公众号,转发到朋友圈。我会一如既往的写一些与众不同的技术文章,而不是“技术大V们的营销文”,更不会是鸡汤。

对了,好朋友们要求我直播吃鲱鱼罐头,盛情难却,毕竟众筹给我的,还要求卖家给我挑一个最臭的。于是近期会找个良辰吉日直播一发,也许顺路做个漱口水的评测。若选好日子,我会第一时间发公众号推送的。


 
糖炒小虾 更多文章 另辟蹊径的网络协议分析方法 逆向分析网络协议 iOS 篇 给那些刚入行的 iOS/Android 开发新手们的一些建议 [一周一算法] 基础知识 如何正确理解 Bitcode
猜您喜欢 SRE,一场消灭人类的战争 依赖 IDE 做开发,会让你成为一名糟糕的程序员么? 我们身边的大数据 你以为你在合群,其实你在浪费青春