客户端log日志系统

背景

我们在开发过程中出现了个别bug,而我们往往很难定位到问题所在,这个不仅仅局限于移动端,只是移动端不容易定位问题。我们常见的实现方式可能是,

1. 创建一个带队列的线程。

2. 把要上报的数据抛入线程队列中。

3. 数据过多本地写入文件。

4. 线程异步开始上报。

5. 上报完成后删除本地文件。

但这个实现方案经常会有一些问题:

1. 上层写入数据过快,写文件线程来不及写入文件,此时应用发生crash或app被杀,导致上报数据丢失。

2. 多业务场景很难复用。

3. 文件序列化经常出现问题,导致数据丢失。

4. 不跨平台,安卓和iOS通常出现不同的实现,总是各自出现不同的问题,不容易定位,统一解决。

因为我们对数据要求很高,完全不允许数据出现丢失。所以针对上面这种方案的实现是不允许的。所以我们想针对这种不允许数据丢失的需求,开发一套准实时数据上报组件,感兴趣的同学可以一块研究研究。

我们希望有以下功能:

1. 数据不丢失,app发生crash或者异常被杀,数据不丢失,下次启动会再次被上报

2. 数据上报有序性,上报数据会保证与push进来的数据顺序是一致的,不会造成数据乱序

3. 上报效率高,可配置单次上报数量,当缓存数据过多时,可进行一次上报多条数据,减少链接次数

4. 多业务服用,多业务可创建不同实例,进行上报,互不影响

5. 跨平台,c++实现,Android/iOS共用一套代码,逻辑完全统一, 不会存在出现不同异常现象

5. 效率高,底层采用c++实现,同时采用单线程模型进程上报,多业务共用一个线程,有效节省开销。当上报数据为空时线程进入休眠。

6. 异常兼容好,在最恶劣的情况,手机系统突然挂掉或异常关机,(正常关机不受影响)。若此时正在写入数据,可能导致数据的不完整性,对常规的序列化方式,整个数据会导致不可用。

这里推荐2款个人比较看好的log日志系统:

DataReporter

git地址:

https://github.com/luojilab/DataReporter

原理

为了保证数据在app未被卸载和手机异常关机的情况下,能够100%不丢失。这套方案我们参考了目前比较流行的。mmap。因为mmap可以创建一块内存,把内存映射到文件。这块内存的管理由操作系统来维护。只要操作系统不出现异常挂掉。该内存的数据是不会丢失的。即使当前的App已经被杀死后者发生crash。下次app启动,用之前的文件映射去调用系统接口,还是能换出之前crash之前的内存数据。这样就保证了数据在app crash或者异常被杀掉的情况下,数据不丢失。因为最早mmap是用来进程间传递数据使用,所以具有这种进程挂掉数据不丢失的特点。

目前采用mmap作为数据缓冲的项目已经呈雨后春笋般。像腾讯的xlog和MMKV都采用了mmap技术。

原理图

如图:DataReporter大致原理如图所示, 业务调用主要接口只有一个push。上层调用push接口,把数据push到PushBuffer中,然后唤起上报方法Report。Report方法,copy PushBuffer中数据到UploadBuffer,这样做是为了保证上报数据和push数据独立,同时不block数据的push。上层可以畅通的调用push。UploadBuffer中的数据通过,上层实现的Upload接口进行上报。上报成功后通过UploadSuccess接口通知底层组件。底层根据上传成功后条数,开始上报下一批数据。当某批次数据上报失败。通过UploadFiald接口通知,底层组件,底层开始进行delay之后再次上报。因为如果一直进行错误尝试,会导致上报尝试过频繁。导致服务器压力过大。所以上报失败一次,进行了5秒的delay。再次失败,时间累计。如果上层想马上再次尝试,可以使用reaWaken接口,立马开始错误重报。

当PushBuffer数据过多。开始触发写文件操作。写文件方法WriToFile方法,开始把PushBuffer数据拷贝到WriteBuffer,并开始写入磁盘。当上报方法Reporter发现磁盘有文件时,先进行文件的上报,再进行PushBuffer内存的上报。保证上报的顺序性。

这里还是要提一下腾讯的xlog,这个代码在进行数据写文件时,没有使用mmap作为buffer,而是直接使用的普通内存。所以在拷贝文件过程中,如果出现crash。拷贝buffer中的数据就会丢失,所以还是存在很大风险的。希望后面他们能改进。

数据组织方式:

本地数据的序列化DataReporter采用了强纠错的结构。

数据结构

如图:每条数据都保存数据crc。当某条数据写入一半时,发生crash,单条数据损坏。这时不应该整个数据丢弃,而只应该丢弃单条,这种如果用平台实现,就很难实现这么细的粒度。但是我们用c++独立设计数据存储结构。实现单条数据损坏,只丢弃单条数据。整体数据稳定性要稳健很多。

注意:

在调用Release之后,其他方法都不能再被调用。一个好的处理方式,是方法的调用都放在ui线程。不用担心会导致ui线程耗时。底层没有任何耗时或者io的操作,io都是异步的io。不会有任何block操作。

多业务多接口:

对于多业务 多接口可以创建不同的实例。只要不同实例配置的缓存路径不同即可。不同业务的上报互不影响。但是共用一个线程。所以不用担心性能损耗,已经控制的非常细致了。

Logan

git地址:

https://github.com/Meituan-Dianping/Logan

原理:

Logan是美团点评集团移动端基础日志组件,这个名称是Log和An的组合,代表个体日志服务。同时Logan也是“金刚狼”大叔的名号,当然我们更希望这个产品能像金刚狼大叔一样犀利。

Logan已经稳定迭代了一年多的时间。目前美团点评绝大多数App已经接入并使用Logan进行日志收集、上传、分析。近日,我们决定开源Logan生态体系中的存储SDK部分(Android/iOS),个人感觉比者成熟很多,各位可以参考参考。

这里就不做详细介绍了。

文档地址:

https://tech.meituan.com/logan_open_source.html

长按(或扫码)识别二维码,关注~

陈不二
博客地址:
http://www.chenbu2.com
简书地址:
https://www.jianshu.com/u/f4874eb81c5b
GitHub地址:
https://github.com/ChenBu2
爱学啊合作讲师:
http://www.ixuea.com/
公众号:
陈不2
技术交流QQ群:
858499698

欢迎一块交流学习~

喜欢的朋友记得点赞转发分享哦!

作者: chenbu2

陈不二,喜欢技术,欢迎一块交流学习~ 大家可以关注我的个人博客: www.chenbu2.com 简书地址: https://www.jianshu.com/u/f4874eb81c5b 公众号: 陈不二 技术交流QQ群: 858499698

《客户端log日志系统》有一个想法

发表评论

电子邮件地址不会被公开。 必填项已用*标注