高性能日志框架 Log4a 原理分析
WHY Log4a:
如果覺得還不錯,歡迎 start,fork。
Log4a 使用 mmap 文件映射內存作為緩存,可以在不犧牲性能的前提下最大化的保證日志的完整性。 日志首先會寫入到 mmap 文件映射內存中,基于 mmap 的特性,即使用戶強殺了進程,日志文件也不會丟失,并且會在下次初始化 Log4a 的時候回寫到日志文件中。
對于移動開發者來說,針對一些用戶反饋難以復現的線上問題,分析日志有時候是解決問題的必要手段。 但是日志的收集一直有個痛點,就是性能與日志完整性無法兼得。 要實現高性能的日志收集,勢必要使用大量內存,先將日志寫入內存中,然后在合適的時機將內存里的日志寫入到文件系統中(flush), 如果在 flush 之前用戶強殺了進程,那么內存里的內容會因此而丟失。 日志實時寫入文件可以保證日志的完整性,但是寫文件是 IO 操作,涉及到用戶態與內核態的切換,相比較直接寫內存會更耗時,UI 線程中頻繁的寫文件會造成卡頓,影響用戶體驗。
HOW:
使用方法與 android.util.Log 一致,不同的是你需要進行簡單的配置,當然也預留了豐富的接口供拓展使用,更高級的配置可以查看Sample;
性能測試
性能測試的代碼位于 Sample 中,分別測試了 Log4a, android.util.Log, 直接寫內存(將日志內容保存到 ArrayList 中), 實時寫文件, 使用 Buffer 寫文件 當然也可以自行下載 Sample APK,在你的設備上進行測試。
下面分別是在 Google Pixel 和 Moto X 中寫1w條日志的測試情況:
上圖中 google pixel 的測試數據表格如下(按消耗時間排序):
| Google Pixel | Mem | 13ms | Y | N | N |
| Google Pixel | Log4a | 50ms | Y | Y | Y |
| Google Pixel | File with Buffer | 61ms | Y | Y | N |
| Google Pixel | Android Log | 184ms | N | N | N |
| Google Pixel | File no Buffer | 272ms | Y | Y | Y |
可以看出 Log4a 的寫日志性能僅次于直接寫內存,與使用 BufferOutputStream 寫文件基本保持一致,事實上為了保證多線程安全性, Log4a 在寫 mmap 內存的時候都是加鎖的,在沒鎖的情況下可以更靠近直接寫內存的速度(有興趣的可以自行測試)。
BufferOutputStream 是將先數據緩存在內存中,之后再刷新進文件的,如果在刷新之前斷電了或者強殺了進程,那么內存中的數據就會丟失無法恢復。Log4a 會在下次啟動的時候恢復日志文件保證日志的完整性。
感謝
- Tencent/mars
- XLog
https://toutiao.io/posts/1dr63d/preview
總結
以上是生活随笔為你收集整理的高性能日志框架 Log4a 原理分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于 ELK Stack 和 Spark
- 下一篇: 微信终端跨平台组件 mars 系列(一)