美团点评移动端基础日志库——Logan
背景
對于移動應用來說,日志庫是必不可少的基礎設施,美團點評集團旗下移動應用每天產生的眾多種類的日志數據已經達到幾十億量級。為了解決日志模塊普遍存在的效率、安全性、丟失日志等問題,Logan基礎日志庫應運而生。
現存問題
目前,業內移動端日志庫大多都存在以下幾個問題:
- 卡頓,影響性能
- 日志丟失
- 安全性
- 日志分散
首先,日志模塊作為底層的基礎庫,對上層的性能影響必須盡量小,但是日志的寫操作是非常高頻的,頻繁在Java堆里操作數據容易導致GC的發生,從而引起應用卡頓,而頻繁的I/O操作也很容易導致CPU占用過高,甚至出現CPU峰值,從而影響應用性能。
其次,日志丟失的場景也很常見,例如當用戶的App發生了崩潰,崩潰日志還來不及寫入文件,程序就退出了,但本次崩潰產生的日志就會丟失。對于開發者來說,這種情況是非常致命的,因為這類日志丟失,意味著無法復現用戶的崩潰場景,很多問題依然得不到解決。
第三點,日志的安全性也是至關重要的,絕對不能隨意被破解成明文,也要防止網絡被劫持導致的日志泄漏。
最后一點,對于移動應用來說,日志肯定不止一種,一般會包含端到端日志1、代碼日志、崩潰日志、埋點日志這幾種,甚至會更多。不同種類的日志都具有各自的特點,會導致日志比較分散,查一個問題需要在各個不同的日志平臺查不同的日志,例如端到端日志還存在日志采樣,這無疑增加了開發者定位問題的成本。
面對美團點評幾十億量級的移動端日志處理場景,這些問題會被無限放大,最終可能導致日志模塊不穩定、不可用。然而,Logan應運而生,漂亮地解決了上述問題。
簡介
Logan,名稱是Log和An的組合,代表個體日志服務的意思,同時也是金剛狼大叔的大名。通俗點說,Logan是美團點評移動端底層的基礎日志庫,可以在本地存儲各種類型的日志,在需要時可以對數據進行回撈和分析。
Logan具備兩個核心能力:本地存儲和日志撈取。作為基礎日志庫,Logan已經接入了集團眾多日志系統,例如端到端日志、用戶行為日志、代碼級日志、崩潰日志等。作為移動應用的幕后英雄,Logan每天都會處理幾十億量級的移動端日志。
設計
作為一款基礎日志庫,在設計之初就必須考慮如何解決日志系統現存的一些問題。
卡頓,影響性能
I/O是比較耗性能的操作,寫日志需要大量的I/O操作,為了提升性能,首先要減少I/O操作,最有效的措施就是加緩存。先把日志緩存到內存中,達到一定大小的時候再寫入文件。為了減少寫入本地的日志大小,需要對數據進行壓縮,為了增強日志的安全性,需要對日志進行加密。然而這樣做的弊端是:
- 對Android來說,對日志加密壓縮等操作全部在Java堆里面。由于日志寫入是一個高頻的動作,頻繁地堆內存操作,容易引發Java的GC,導致應用卡頓;
- 集中壓縮會導致CPU短時間飆高,出現峰值;
- 由于日志是內存緩存,在殺進程、Crash的時候,容易丟失內存數據,從而導致日志丟失。
Logan的解決方案是通過Native方式來實現日志底層的核心邏輯,也就是C編寫底層庫。這樣做不光能解決Java GC問題,還做到了一份代碼運行在Android和iOS兩個平臺上。同時在C層實現流式的壓縮和加密數據,可以減少CPU峰值,使程序運行更加順滑。而且先壓縮再加密的方式壓縮率比較高,整體效率較高,所以這個順序不能變。
日志丟失
加緩存之后,異常退出丟失日志的問題就必須解決,Logan為此引入了MMAP機制。MMAP是一種內存映射文件的方法,即將一個文件或者其它對象映射到進程的地址空間,實現文件磁盤地址和進程虛擬地址空間中一段虛擬地址的一一對應關系。MMAP機制的優勢是:
- MMAP使用邏輯內存對磁盤文件進行映射,操作內存就相當于操作文件;
- 經過測試發現,操作MMAP的速度和操作內存的速度一樣快,可以用MMAP來做數據緩存;
- MMAP將日志回寫時機交給操作系統控制。如內存不足,進程退出的時候操作系統會自動回寫文件;
- MMAP對文件的讀寫操作不需要頁緩存,只需要從磁盤到用戶主存的一次數據拷貝過程,減少了數據的拷貝次數,提高了文件讀寫效率。
引入MMAP機制之后,日志丟失問題得到了有效解決,同時也提升了性能。不過這種方式也不能百分百解決日志丟失的問題,MMAP存在初始化失敗的情況,這時候Logan會初始化堆內存來做日志緩存。根據我們統計的數據來看,MMAP初始化失敗的情況僅占0.002%,已經是一個小概率事件了。
安全性
日志文件的安全性必須得到保障,不能隨意被破解,更不能明文存儲。Logan采用了流式加密的方式,使用對稱密鑰加密日志數據,存儲到本地。同時在日志上傳時,使用非對稱密鑰對對稱密鑰Key做加密上傳,防止密鑰Key被破解,從而在網絡層保證日志安全。
日志分散
針對日志分散的情況,為了保證日志全面,需要做本地聚合存儲。Logan采用了自研的日志協議,對于不同種類的日志都會按照Logan日志協議進行格式化處理,存儲到本地。當需要上報的時候進行集中上報,通過Logan日志協議進行反解,還原出不同日志的原本面貌。同時Logan后臺提供了聚合展示的能力,全面展示日志內容,根據協議綜合各種日志進行分析,使用時間軸等方式展示不同種日志的重要信息,使得開發者只需要通過Logan平臺就可以查詢到某一段時間App到底產生了哪些日志,可以快速復現問題場景,定位問題并處理。
關于Logan平臺是如何展示日志的,下文會再進行說明。
架構
首先,看一下Logan的整體架構圖:
Logan自研的日志協議解決了日志本地聚合存儲的問題,采用先壓縮再加密的順序,使用流式的加密和壓縮,避免了CPU峰值,同時減少了CPU使用。跨平臺C庫提供了日志協議數據的格式化處理,針對大日志的分片處理,引入了MMAP機制解決了日志丟失問題,使用AES進行日志加密確保日志安全性,并且提供了主動上報接口。Logan核心邏輯都在C層完成,提供了跨平臺支持的能力,在解決痛點問題的同時,也大大提升了性能。
日志分片
Logan作為日志底層庫,需要考慮上層傳入日志過大的情況。針對這樣的場景,Logan會做日志分片處理。以20k大小做分片,每個切片按照Logan的協議進行存儲,上報到Logan后臺的時候再做反解合并,恢復日志本來的面貌。
那么Logan是如何進行日志寫入的呢?下圖為Logan寫日志的流程:
性能
為了檢測Logan的性能優化效果,我們專門寫了測試程序進行對比,讀取16000行的日志文本,間隔3ms,依次調用寫日志函數。
首先對比Java實現和C實現的內存狀況:
Java:
C:
可以看出Java實現寫日志,GC頻繁,而C實現并不會出現這種情況,因為它不會占用Java的堆內存。那么再對比一下Java實現和C實現的CPU使用情況:
C實現沒有頻繁的GC,同時采用流式的壓縮和加密避免了集中壓縮加密可能產生的CPU峰值,所以CPU平均使用率會降低,如上圖所示。
特色功能
日志回撈
開發者可能都會遇到類似的場景:某個用戶手機上裝了App,出現了崩潰或者其它問題,日志還沒上報或者上報過程中被網絡劫持發生日志丟失,導致有些問題一直查不清原因,或者沒法及時定位到問題,影響處理進程。依托集團PushSDK強大的推送能力,Logan可以確保用戶的本地日志在發出撈取指令后及時上傳。通過網絡類型和日志大小上限選擇,可以為用戶最大可能的節省移動流量。
回饋機制可以確保撈取日志任務的進度得到實時展現。
日志回撈平臺有著嚴格的審核機制,確保開發者不會侵犯用戶隱私,只關注問題場景。
主動上報
Logan日志回撈,依賴于Push透傳。客戶端被喚醒接收Push消息,受到一些條件影響:
- Android想要后臺喚醒App,需要確保Push進程在后臺存活;
- iOS想要后臺喚醒APP,需要確保用戶開啟后臺刷新開關;
- 網絡環境太差,Android上Push長連建立不成功。
如果無法喚醒App,只有在用戶再次進入App時,Push通道建立后才能收到推送消息,以上是導致Logan日志回撈會有延遲或收不到的根本原因,從分析可以看出,Logan系統回撈的最大瓶頸在于Push系統。那么能否拋開Push系統得到Logan日志呢?先來看一下使用日志回撈方式的典型場景:
其中最大的障礙在于Push觸達用戶。那么主動上報的設計思路是怎樣的呢?
通過在App中主動調用上報接口,用戶直接上報日志的方式,稱之為Logan的主動上報。主動上報的優勢非常明顯,跳過了Push系統,讓用戶在需要的時候主動上報Logan日志,開發者再也不用為不能及時撈到日志而煩惱,在用戶投訴之前就已經拿到日志,便于更高效地分析解決問題。
線上效果
Logan基礎日志庫自2017年9月上線以來,運行非常穩定,大大提高了集團移動開發工程師分析日志、定位線上問題的效率。
Logan平臺時間軸日志展示:
Logan日志聚合詳情展示:
作為基礎日志庫,Logan目前已經接入了集團眾多日志系統:
- CAT端到端日志
- 埋點日志
- 用戶行為日志
- 代碼級日志
- 網絡內部日志
- Push日志
- Crash崩潰日志
現在,Logan已經接入美團、大眾點評、美團外賣、貓眼等眾多App,日志種類也更加豐富。
展望未來
H5 SDK
目前,Logan只有移動端版本,支持Android/iOS系統,暫不支持H5的日志上報。對于純JS開發的頁面來說,同樣有日志分散、問題場景復現困難等痛點,也迫切需要類似的日志底層庫。我們計劃統一H5和Native的日志底層庫,包括日志協議、聚合等,Logan的H5 SDK也在籌備中。
日志分析
Logan平臺的日志展示方式,我們還在探索中。未來計劃對日志做初步的機器分析與處理,能針對某些關鍵路徑給出一些分析結果,讓開發者更專注于業務問題的定位與分析,同時希望分析出用戶的行為是否存在風險、惡意請求等。
思考題
本文給大家講述了美團點評移動端底層基礎日志庫Logan的設計、架構與特色,Logan在解決了許多問題的同時,也會帶來新的問題。日志文件不能無限大,目前Logan日志文件最大限制為10M,遇到大于10M的情況,應該如何處理最佳?是丟掉前面的日志,還是丟掉追加的日志,還是做分片處理呢?這是一個值得深思的問題。
作者簡介
- 白帆,美團點評基礎框架研發組Android技術專家。2015年加入原大眾點評。先后負責客戶端長連網絡SDK、Logan日志SDK等項目。目前主導Logan日志SDK的開發和推廣。
- 立成,美團點評基礎框架研發組Android高級開發工程師。2016年加入美團點評,在Android開發、跨平臺開發、移動端測試等領域有一定的實踐經驗,熱愛新技術并愿意付諸實踐,致力于產出高質量代碼。
招聘信息
點評平臺移動研發中心,base上海,提供美團點評集團大多數移動端底層基礎設施,包含網絡通信、移動監控、推送觸達、動態化引擎、移動研發工具等。同時團隊還承載流量分發,UGC,內容生態,整合中心等業務研發,長年虛位以待有志于專注移動端研發的各路英雄。歡迎投遞簡歷:hui.zhou#dianping.com。
解釋說明
總結
以上是生活随笔為你收集整理的美团点评移动端基础日志库——Logan的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里最全Java面试100题汇总:涵盖天
- 下一篇: 细说ReactiveCocoa的冷信号与