:## 为什么
为什么要寻找单独的logger库?用Andorid原生的Log不好吗?原生Log长得这样:
先分级,再打上TAG,然后直接输出。功能很基础,平时基本够用。但是在长期的Android开发实践中,我们会发现,这个功能太基础了,当:
- 每次打TAG都要写下雷同的代码,太不DRY了。
- 想打印的数据各种打不出,要么就是打出来一长串看的发晕。
- 为了找某条log是从哪里打出来的,还要花点功夫。
- 即使找到了,怎么知道运行时是在哪个线程?
- 日志去了不再来。在未连接调试的手机上,或者调试中不小心重启App了,日志就没了。
不多说了,光这几个问题就够我们有充分的理由去寻找一个新的Log系统了。先从最常用的下手,从网上能搜到最常用的Android logger有两个。
- https://github.com/orhanobut/logger :简单、漂亮、强大的Android logger,github上3000+ Star
- https://github.com/JakeWharton/timber :基于Android原生Log的logger,小巧易扩展。
看简介帮助不大,我们还是真刀真枪用一下,看看这两个开源库为什么这么受欢迎,有没有解决我们的问题。
好Logger应该长什么样?
动手分析之前,我们要先想想清楚,我们要的好Logger,应该是什么样的?
打印日志是一门传统艺术,历史悠久,打从有编程那年就开始有了。它与单步调试并称程序调试两大神技,程序员们因为拥护不同的调试方法,分裂成了两大阵营:日志派和调试派,两派互相看不起。调试派说打印日志太没技术含量,还要到处做标记,看我们调试派,想停哪里点哪里,想看什么看什么,调试器能带我飞。日志派也不服气,你能离线调试吗?你能调试多线程错误吗?你能xxx调试吗?
好程序员两种技能都要掌握,现在调试工具越来越好用,单步调试没有任何困难。但是打印日志仍然是不可或缺的必杀技,尤其是查活系统(运行中软件)的问题时,如果没有后台日志或者用户手机日志,真是打死也不知道哪里出了问题。
扯完日志的重要性,认真说说我们对日志系统的需求:
- 容易打印:无论什么格式的数据,上到自定义类,下到字节流,都能单行代码给打出来,不用为了打日志写一堆额外的代码逻辑。
- 格式漂亮:对格式化数据做打印美化,必要时适当做点排版。
- 容易筛选:给日志分级和打标签,就是为了达到这个目的。
- 立即定位:每条日志都有两个位置,代码中的位置和运行时位置(所在线程)。这两个位置对快速定位问题很重要。
- 灵活设置:日志数量和日志详细程度是一对矛盾体。大多数情况下,普通的日志就够我们分析问题了。但是某些情况下,如多线程问题,异步问题,需要打印尽量详细的信息,这个要能灵活设置。
- 日志留存:日志打到屏幕上,说没就没。有没有办法屏幕上打一份,SD卡上存一份,崩溃信息网站上留一份?这有点类似linux上的tee命令。
- 容易上手:本来没想写这条,也没想到上面会列出这么多特性,没办法,还是加上个容易上手的指标吧。就是说上边这些特性,
能做到上面几点,我们就认为这个日志系统非常好了。注意,我为什么没提性能要求?因为正式发布版本里,是不会有日志的,起码不会大量存在,所以性能也就无所谓了,别太差就行。尺子有了,我们就用它来衡量一下Timber和Logger。
Logger分析
这个项目在github上有3000+ star,必有过人之处。
- 容易打印:除了普通字符串和含变量字符串,还能直接打印json、xml、异常,通过。
- 格式漂亮:的确漂亮,但是过分漂亮了。本来一行的日志给打成了8行,真超值。结果赠品太多,都找不到我想看的那条了。
- 容易筛选:能分级,能自动打tag,能自定义tag。等等,为什么tag不是类名?难道用类名当tag不是普世价值观吗?明白了,它的类名和方法名都在日志内容中有了,tag中不用再放一个了。但是有Android Monitor依赖症的我表示,这让我怎么筛选一眼望不到头的日志呀,差评。
- 立即定位:能跳转到文件位置,能看函数名、线程号,通过。
- 灵活设置:可以设置,但是设置项似乎不太丰富呀。
- 日志留存:不支持。
- 容易上手:一行代码就能用,通过。
Timber分析
这个库非常简洁,准确讲,它只有一个文件,是Jake Wharton大神自己用的。大神说嫌拷贝来拷贝去太麻烦,才开源成一个库。
- 容易打印:支持普通字符串和含变量字符串。
- 格式漂亮:不支持。
- 容易筛选:自动用类名当tag,也可以自定义。
- 立即定位:不支持。
- 灵活设置:支持,但没什么设置项。
- 日志留存:支持。
- 容易上手:还是吐槽一下,这个库的tree和plant是什么鬼?我是读完它的代码才明白的。其实跟树、种树、木头没一毛钱关系,大神只是借种树这个形象的方法,说日志可以写到各种地方去。想写哪里写哪里,自己plant一个自己实现的Tree就可以了。不种树就没有日志。大神太幽默了。
总结
从总评价看,显然Logger更好,特性更丰富。但是它的排版我实在接受不了。所以项目实践中,我还是会用Timber。全剧终。
我去,这个结局太不能让人满意了,选了半天选了个不好用的,这世界怎么了?
改进
权衡之下,还是改造一下Logger吧。在github上fork了Logger的代码,针对Logger不满的地方,加入我的改动。为了保持Logger自身的特点,新改动通过Settings的形式加入,我给Settings加入mode设置。默认是pretty模式,一切用法与输出结果与原Logger保持一致,可以通过单元测试。如果对PRETTY模式下日志过多有意见,可以启用brief模式,去除无用的分割线,把默认日志从8行减为4行,保持可读性和所有信息。如果还嫌多,可以启动single模式,默认日志从8行压缩到1行,保持必要信息。代码库见https://github.com/oreofish/logger
对这个改进的版本重新评估如下:
- 容易打印:同原作。
- 格式漂亮:可以方便的在8行的pretty模式,和4行的简洁模式,和1行的单行模式中切换。
- 容易筛选:能分级,能自动打tag,能自定义tag。单行模式下用Android Monitor过滤日志很方便。通过。
- 立即定位:同原作,而且重点保持了"能跳转到文件位置"这个特性,通过。
- 灵活设置:可以设置。
- 日志留存:暂不支持(我很喜欢这个特性,有空要加上)。
- 容易上手:一行代码就能用,通过。
- 彩蛋:写代码时经常会加上一些临时的日志,例如一大串相同的字符,只是为了在日志堆里容易看到。改进版本中加入了预定义的表情字符串IAMHERE1到IAMHERE6,就是为了容易看到。
开源大法好。这,就是我想要的日志系统。我会尝试提交代码给Logger官方,虽然由于思路不同,他们可能不会合并我的代码:)
结论
- 如果对日志要求不高,简单用用而已,Android自带的Log就不错。
- 如果厌烦了Android Log,觉得用着不方便,Timber和Logger都是好选择,Timber只要一个文件。
- 如果你觉得日志很重要,特别推荐的我的改进版Logger。
- 还觉得不好?把你的需求说出来,或者自己动手改进,都欢迎。