譚倚靖 譚智文 張亮 韋通明 蘇萬德
【摘? 要】本文研究一種Android客戶端日志采集系統(tǒng)的整體解決方案,實(shí)現(xiàn)終端日志的“全量滾動(dòng)緩存+動(dòng)態(tài)配置上報(bào)”,保證日志信息的完整存儲(chǔ),并減少無用日志上報(bào)。
【關(guān)鍵詞】日志系統(tǒng);客戶端;Android系統(tǒng);日志采集
中圖分類號(hào):U463.6? ? 文獻(xiàn)標(biāo)志碼:A? ? 文章編號(hào):1003-8639( 2023 )08-0040-03
Research on Log Collection System of Android Client
TAN Yi-jing,TAN Zhi-wen,ZHANG Liang,WEI Tong-ming,SU Wan-de
(SAIC GM Wuling Automobile Co.,Ltd.,Guangxi Laboratory of New Energy Automobile,
Guangxi Key Laboratory of Automobile Four New Features,Liuzhou 545007,China)
【Abstract】This paper studies an overall solution of Android client log collection system to achieve the“full rolling cache+dynamic configuration reporting”of terminal logs,ensure the complete storage of log information,and reduce the reporting of useless logs.
【Key words】log system;client;Android system;log collection
日志是操作系統(tǒng)或應(yīng)用程序在運(yùn)行時(shí)的事件記錄,為開發(fā)人員提供程序運(yùn)行過程中的狀態(tài)變化信息,用于處理和觀察分析系統(tǒng)或程序的運(yùn)行是否符合預(yù)期的結(jié)果。
1? 客戶端系統(tǒng)的多樣性問題
服務(wù)端的日志系統(tǒng)較為成熟,目前主流的日志系統(tǒng)使用ELK作為日志的分布式存儲(chǔ),使用skywalking作為微服務(wù)架構(gòu)中的分布式鏈路解決方案,使得開發(fā)者能夠便捷地收集和查詢?nèi)罩?,協(xié)助處理系統(tǒng)問題。而客戶端與服務(wù)端不同,相較于服務(wù)端穩(wěn)定的網(wǎng)絡(luò)架構(gòu),客戶端需要面對(duì)更多的多樣性問題。
1)客戶端平臺(tái)的多樣性。云平臺(tái)上的服務(wù)器、每個(gè)人手里的手機(jī)以及物聯(lián)網(wǎng)設(shè)備等終端都可以作為客戶端,不同的客戶端通常使用不同的操作系統(tǒng),這就要求客戶端的日志系統(tǒng)需要在多平臺(tái)實(shí)現(xiàn),或者具備跨平臺(tái)的能力。
2)客戶端場(chǎng)景的多樣性??蛻舳藶橛脩羲?,用戶在客戶端進(jìn)行業(yè)務(wù)交互時(shí),其是否同意采集并上傳日志、產(chǎn)品應(yīng)用是否希望用戶感知到日志的采集與回傳操作、流量的消耗是否合理……這些問題都需要基于具體的應(yīng)用場(chǎng)景來設(shè)計(jì),場(chǎng)景需求的多樣性則要求客戶端日志系統(tǒng)需要具備較高的可配置能力,同時(shí),日志采集需要盡量低消耗與無感知。
3)客戶端網(wǎng)絡(luò)環(huán)境的多樣性。互聯(lián)網(wǎng)有多種接入方式,常見的有:WIFI接入、移動(dòng)蜂窩網(wǎng)絡(luò)接入、有線寬帶接入、USB橋接網(wǎng)絡(luò)接入……多種網(wǎng)絡(luò)可能隨時(shí)切換,也隨時(shí)可能出現(xiàn)網(wǎng)絡(luò)不穩(wěn)定、短時(shí)離網(wǎng)等異常情況。為保證日志數(shù)據(jù)不因?yàn)榫W(wǎng)絡(luò)問題而丟失,要求客戶端的日志系統(tǒng)需要具備數(shù)據(jù)緩存、數(shù)據(jù)壓縮、斷點(diǎn)續(xù)傳、超時(shí)重連等機(jī)制,以保證日志系統(tǒng)在復(fù)雜網(wǎng)絡(luò)條件下能夠正常運(yùn)作。
2? Android客戶端的日志采集系統(tǒng)現(xiàn)狀
客戶端系統(tǒng)種類甚多,對(duì)于實(shí)現(xiàn)復(fù)雜業(yè)務(wù)場(chǎng)景的客戶端系統(tǒng),在出現(xiàn)系統(tǒng)異常時(shí),常常難以為每個(gè)問題提供場(chǎng)景復(fù)現(xiàn)與復(fù)測(cè)條件,因此需要日志收集系統(tǒng)的支持。當(dāng)前,在復(fù)雜業(yè)務(wù)客戶端系統(tǒng)中,開源的Android應(yīng)用最為廣泛,故本文主要探討Android客戶端的日志采集系統(tǒng)如何實(shí)現(xiàn),并解決客戶端日志系統(tǒng)面臨的主要難點(diǎn)問題。
在Android系統(tǒng)的應(yīng)用中,日志級(jí)別分為錯(cuò)誤日志(Error)、警告日志(Warn)、信息日志(Info)、調(diào)試日志(Debug)、詳細(xì)日志(Verbose)。日志級(jí)別用于篩選日志內(nèi)容時(shí),使用者可根據(jù)實(shí)際需要來選擇查看不同級(jí)別的日志。
目前,常見的Android日志收集方式主要有以下3種。
1)日志僅本地存儲(chǔ),用戶主動(dòng)回傳。在客戶端出現(xiàn)嚴(yán)重問題時(shí),引導(dǎo)用戶主動(dòng)操作上報(bào)日志壓縮文件。通常作為操作系統(tǒng)方的實(shí)現(xiàn)方式,例如:手機(jī)系統(tǒng)、車機(jī)系統(tǒng),采集的日志類型包含系統(tǒng)日志、應(yīng)用日志、內(nèi)核日志、外部設(shè)備日志等,日志內(nèi)容全,覆蓋范圍廣。由于操作系統(tǒng)的重要性,在發(fā)布正式版本前大多經(jīng)過了一層層的嚴(yán)格測(cè)試,線上問題較少。采用這種日志收集形式,便于更針對(duì)性地解決特定用戶的特定問題,并最大程度減少對(duì)于網(wǎng)絡(luò)資源以及服務(wù)端資源的消耗。
2)監(jiān)聽系統(tǒng)應(yīng)用程序異常,上傳錯(cuò)誤日志。通常面向應(yīng)用層的軟件,主要由第三方提供服務(wù),在捕獲到App發(fā)生異常時(shí),自動(dòng)采集錯(cuò)誤日志到第三方后臺(tái),主要用于解決應(yīng)用程序崩潰問題以及應(yīng)用無響應(yīng)問題。這種方式接入簡(jiǎn)單高效,能夠快速、便捷地為App開發(fā)者提供錯(cuò)誤統(tǒng)計(jì)以及日志數(shù)據(jù)。缺點(diǎn)則是日志內(nèi)容有限,且只能在嚴(yán)重錯(cuò)誤發(fā)生時(shí)獲取日志信息,而業(yè)務(wù)功能錯(cuò)誤無法收集。
3)實(shí)時(shí)回傳核心業(yè)務(wù)功能的相關(guān)日志。在指定的業(yè)務(wù)代碼位置直接定義日志上傳規(guī)則及內(nèi)容,每當(dāng)產(chǎn)生新日志時(shí)即刻上報(bào),信息冗余量較大,一般僅用于特定核心業(yè)務(wù)功能的狀態(tài)上報(bào)。
3? 研究目標(biāo)
基于Android客戶端的日志采集系統(tǒng)現(xiàn)狀分析可知,前端日志采集的難點(diǎn)主要在于如何解決日志數(shù)據(jù)量大、價(jià)值密度低的問題。若全量日志數(shù)據(jù)盡數(shù)存儲(chǔ)并回傳,會(huì)顯著地占用客戶端設(shè)備的I/O性能、CPU計(jì)算性能、存儲(chǔ)容量以及網(wǎng)絡(luò)流量,且其中能夠直接發(fā)揮作用的有效日志卻可能不足總量的萬分之一,服務(wù)端接收到的數(shù)據(jù)量更與用戶數(shù)量直接相關(guān),這大量的冗余數(shù)據(jù)對(duì)用戶和服務(wù)端的資源都造成了浪費(fèi)。所以,主流的解決方案都會(huì)考慮解決或回避這些問題,例如:僅在發(fā)生程序崩潰時(shí)上傳錯(cuò)誤日志,盡量提高上傳日志數(shù)據(jù)的價(jià)值密度,僅上傳特定用戶的日志數(shù)據(jù),降低服務(wù)端資源消耗,更針對(duì)性地處理用戶問題。
本文研究一種“全量滾動(dòng)緩存+動(dòng)態(tài)配置上報(bào)”的Android客戶端日志采集系統(tǒng)解決方案。①全量滾動(dòng)緩存是指對(duì)系統(tǒng)中所有的日志進(jìn)行本地持久化存儲(chǔ),并加入數(shù)據(jù)隊(duì)列的處理模式,當(dāng)日志內(nèi)容超出存儲(chǔ)池大小的時(shí)候,依次存儲(chǔ)新的日志和刪除最舊的日志內(nèi)容,以保證存儲(chǔ)完整的日志信息,但不會(huì)超出預(yù)設(shè)的存儲(chǔ)池大?。虎趧?dòng)態(tài)配置上報(bào)是指通過后臺(tái)動(dòng)態(tài)配置的方式,控制日志數(shù)據(jù)是否上報(bào)、上報(bào)的內(nèi)容、上報(bào)的頻率等信息,依據(jù)需求來確定需要上報(bào)的內(nèi)容和方式,減少無用日志上報(bào)。
根據(jù)Android客戶端日志采集系統(tǒng)解決方案的主要思想,可以將設(shè)計(jì)目標(biāo)拆分為以下4個(gè)方面。
1)配置功能:日志采集需要具備動(dòng)態(tài)配置功能,可以通過服務(wù)端配置文件控制日志存儲(chǔ)池大小、日志內(nèi)容上報(bào)的過濾條件、上報(bào)頻率等配置參數(shù)。
2)性能要求:日志采集模塊需要接入方便,穩(wěn)定高效,對(duì)項(xiàng)目的入侵度低,對(duì)目標(biāo)設(shè)備性能影響小。
3)日志存儲(chǔ):日志采集內(nèi)容可以進(jìn)行本地持久化,不擠兌應(yīng)用的存儲(chǔ)空間,日志內(nèi)容滾動(dòng)更新,應(yīng)用意外停止時(shí)具備防止日志內(nèi)容丟失的機(jī)制。
4)數(shù)據(jù)安全性:日志采集內(nèi)容需要保證安全性,對(duì)內(nèi)容進(jìn)行加密,防止信息泄露。
本文設(shè)計(jì)的日志采集系統(tǒng)在適用范圍方面,只要是具備數(shù)據(jù)存儲(chǔ)能力和網(wǎng)絡(luò)傳輸能力的設(shè)備,都符合本文設(shè)計(jì)的系統(tǒng)要求,而市面上運(yùn)行Android系統(tǒng)的主要設(shè)備有智能手機(jī)、平板電腦、汽車的車載車機(jī)模塊、智能電視或機(jī)頂盒等,都具備存儲(chǔ)與網(wǎng)絡(luò)傳輸?shù)幕A(chǔ)能力。
4? 數(shù)據(jù)模型定義
數(shù)據(jù)模型中的數(shù)據(jù)結(jié)構(gòu)采用JSON格式,主要原因是Android依賴庫(kù)自帶JSON庫(kù),無需增加其他第三方依賴,且性能穩(wěn)定,并提供了很好的可讀性。主要的數(shù)據(jù)模型有“日志數(shù)據(jù)模型”和“配置文件數(shù)據(jù)模型”。日志數(shù)據(jù)模型示例見表1,配置文件數(shù)據(jù)模型示例見表2。
5? 系統(tǒng)架構(gòu)詳細(xì)設(shè)計(jì)
系統(tǒng)的架構(gòu)設(shè)計(jì)分為日志管理控制模塊、本地存儲(chǔ)模塊、加密模塊、網(wǎng)絡(luò)請(qǐng)求模塊、自動(dòng)化日志插樁模塊、Crash與ANR日志收集模塊,整體架構(gòu)設(shè)計(jì)如圖1所示。
1)日志管理控制模塊:整個(gè)日志采集系統(tǒng)的主要業(yè)務(wù)邏輯模塊。用于管理日志系統(tǒng)的整體調(diào)度,控制是否開始日志收集、日志文件的緩存大小、緩存時(shí)間、日志上報(bào)時(shí)間間隔等信息。配置信息的獲取時(shí)機(jī)是在系統(tǒng)的初始化過程中,即在系統(tǒng)每次啟動(dòng)時(shí)請(qǐng)求最新的配置信息。為了進(jìn)一步保證配置信息的及時(shí)更新,對(duì)需要更新的配置信息,將會(huì)在每次上報(bào)日志的響應(yīng)體中進(jìn)行跟隨返回指向性配置。日志管理配置信息獲取流程如圖2所示。
若使用長(zhǎng)鏈接或消息推送協(xié)議的方式來更新配置信息,會(huì)更高效與及時(shí),但這樣無疑會(huì)增加整個(gè)系統(tǒng)的復(fù)雜度,也需要付出更多的性能代價(jià),故本文建議的配置更新方式為請(qǐng)求伴隨的方式。
2)本地存儲(chǔ)模塊:日志系統(tǒng)的核心模塊。日志信息通常數(shù)據(jù)量龐大,讀寫I/O本就是比較消耗性能的操作,如果調(diào)度寫入日志信息存儲(chǔ)到本地,會(huì)太過消耗系統(tǒng)的I/O資源,若日志采集系統(tǒng)會(huì)從性能上影響到業(yè)務(wù)功能的流暢性,則是得不償失的。因?yàn)榇鎯?chǔ)部分是整個(gè)系統(tǒng)中的主要性能模塊,所以需要盡可能地對(duì)其進(jìn)行性能優(yōu)化。Android系統(tǒng)的應(yīng)用運(yùn)行采用的是java虛擬機(jī)的執(zhí)行機(jī)制,內(nèi)存的分配與回收由虛擬機(jī)自行調(diào)度,面對(duì)大量的日志數(shù)據(jù)持續(xù)處理的條件下,硬件配置較低的宿主設(shè)備會(huì)頻繁觸發(fā)GC,而表現(xiàn)到頂層應(yīng)用的現(xiàn)象就是卡頓,可通過Android的NDK工具集,使用C++的原生代碼實(shí)現(xiàn)整個(gè)日志的存儲(chǔ)調(diào)度。同時(shí)還可以利用linux的mmap內(nèi)存映射方法,省去寫入存儲(chǔ)前需經(jīng)過buffer內(nèi)存空間的過程,直接映射內(nèi)存地址,當(dāng)發(fā)生應(yīng)用意外中斷和I/O資源滿載等異常情況時(shí),能夠大大降低數(shù)據(jù)丟失風(fēng)險(xiǎn)。
3)加密模塊:日志內(nèi)容反映了系統(tǒng)或軟件的運(yùn)行狀態(tài),輸出的參數(shù)甚至可能包含一些關(guān)鍵涉密信息,需要對(duì)日志內(nèi)容進(jìn)行加密,保證信息安全。對(duì)日志的內(nèi)容進(jìn)行加密時(shí),由于日志數(shù)據(jù)量龐大,需要使用高效的數(shù)據(jù)加密方式,并保證日志內(nèi)容不被破解。加密方案主要參考https協(xié)議的數(shù)據(jù)傳輸加密模式,對(duì)日志內(nèi)容使用對(duì)稱加密方式進(jìn)行加密,同時(shí)對(duì)密鑰文件使用非對(duì)稱加密方式進(jìn)行加密。日志信息加密存儲(chǔ)流程如圖3所示。
4)網(wǎng)絡(luò)請(qǐng)求模塊:用于與服務(wù)端的網(wǎng)絡(luò)數(shù)據(jù)傳輸,包含日志系統(tǒng)的控制信息獲取,以及日志文件上報(bào)??蛻舳瞬捎藐?duì)列形式的單一請(qǐng)求,使用Android系統(tǒng)自帶的HttpURLConnection請(qǐng)求類,HttpURLConnection是對(duì)于http協(xié)議的封裝,底層通過Socket通信實(shí)現(xiàn)。其優(yōu)點(diǎn)是作為系統(tǒng)庫(kù)類較為穩(wěn)定,也不需要增加其他的網(wǎng)絡(luò)封裝庫(kù),使得日志采集系統(tǒng)盡量輕量化,同時(shí)可以避免對(duì)于外部庫(kù)的依賴而產(chǎn)生的沖突與版本兼容問題。
5)自動(dòng)化日志插樁模塊:輔助功能之一,以可選插件的形式添加到系統(tǒng)中,對(duì)于一些無輸出日志的功能模塊,可為其增加日志。
6)Crash與ANR日志收集模塊:輔助功能之一,以可選插件的形式添加到系統(tǒng)中,監(jiān)聽系統(tǒng)是否出現(xiàn)Crash與ANR,自動(dòng)獲取系統(tǒng)內(nèi)的Crash堆棧日志和ANR線程日志文件上報(bào)。
6? 數(shù)據(jù)安全與用戶隱私
日志輸出的內(nèi)容可能是業(yè)務(wù)應(yīng)用中的各項(xiàng)數(shù)據(jù),數(shù)據(jù)內(nèi)容甚至可能包含用戶行為數(shù)據(jù)和隱私數(shù)據(jù)。因此,對(duì)于日志采集系統(tǒng)來說,一方面需要符合隱私協(xié)議與用戶手冊(cè)的內(nèi)容,是否開啟日志采集,采集哪些內(nèi)容需要完全可控,這一點(diǎn)可以通過日志采集系統(tǒng)中的日志管理控制模塊實(shí)現(xiàn);另一方面需要保證傳輸?shù)臄?shù)據(jù)安全,不能被黑客入侵手機(jī)獲取應(yīng)用內(nèi)的核心信息,也不能被抓包或中間人攻擊的方式獲取到日志數(shù)據(jù)信息,這一方面則通過日志采集系統(tǒng)的加密模塊來實(shí)現(xiàn)對(duì)數(shù)據(jù)的保護(hù)。
7? 應(yīng)用與拓展
本文所論述的是如何在Android客戶端實(shí)現(xiàn)一個(gè)高效、穩(wěn)定、可控的日志采集系統(tǒng),雖然未對(duì)后端服務(wù)設(shè)計(jì)進(jìn)行詳細(xì)說明,但其后端服務(wù)對(duì)于前端的Android日志采集系統(tǒng)的功能有著重要的關(guān)聯(lián)與影響。一方面,其能夠控制日志配置的管理下發(fā),另一方面,后端服務(wù)保存所有上傳的日志數(shù)據(jù)。
現(xiàn)階段后端的日志系統(tǒng)較為成熟,一般使用skywalking管理微服務(wù)請(qǐng)求調(diào)用鏈,記錄整條鏈路的調(diào)用詳情;通過trackID貫穿整條鏈路;使用logstash來過濾有效的日志信息;使用elasticsearch來存儲(chǔ)logstash過濾后的日志信息和skywalking的鏈路數(shù)據(jù);使用kibana來讀取日志并展示統(tǒng)計(jì)信息頁面。在存儲(chǔ)和管理Android前端時(shí)的日志信息時(shí),只要對(duì)日志的數(shù)據(jù)模型進(jìn)行設(shè)計(jì)整合,即可對(duì)前后端的日志數(shù)據(jù)進(jìn)行統(tǒng)一管理,降低后端服務(wù)資源消耗。此外,對(duì)于應(yīng)用程序中的異步方法和多線程方法來說,日志信息的記錄會(huì)呈現(xiàn)為亂序,不便于將同一調(diào)用鏈下的日志進(jìn)行整合排查,而通過在前端請(qǐng)求中也加入trackID,打通前后端日志的調(diào)用鏈關(guān)系,可以實(shí)現(xiàn)更高效的全鏈路日志排查。
8? 總結(jié)
本文從控制能力、終端性能、數(shù)據(jù)安全性以及前后端整合的角度,論述了在Android平臺(tái)下對(duì)于客戶端日志采集系統(tǒng)的整體設(shè)計(jì)。在實(shí)際應(yīng)用場(chǎng)景中,可以結(jié)合業(yè)務(wù)需求,對(duì)日志的配置文件和日志模型進(jìn)行調(diào)整,也可以根據(jù)現(xiàn)有的后端日志系統(tǒng)進(jìn)行適配性調(diào)整。
參考文獻(xiàn):
[1] 趙書慧. Android日志過濾器中正則表達(dá)式的應(yīng)用[J]. 電子測(cè)試,2021(2):84-85.
[2] Meng Zhaoyi,Xiong Yan,Huang Wenchao,etc. AppAngio:Revealing Contextual Information of Android App Behaviors by API-Level Audit Logs[J]. IEEE TRANSACTIONS ON INFORMATION FORENSICS AND SECURITY,2021(16):1912-1927.
[3] 徐永新. 高性能分布式日志系統(tǒng)研究與設(shè)計(jì)[J]. 工業(yè)控制計(jì)算機(jī),2020,33(12):44-46.
[4] 鄭仕元,劉軍. 不可信環(huán)境下的客戶端日志保護(hù)機(jī)制[J]. 計(jì)算機(jī)工程,2011,37(23):138-140.
[5] 王祥雒,李毅. Linux中基于mmap()的共享存儲(chǔ)實(shí)現(xiàn)研究[J]. 計(jì)算機(jī)應(yīng)用,2006(S2):307-309,320.
[6] 吳云周,程鵬,林飛. JSON在Android客戶端和網(wǎng)頁客戶端的應(yīng)用研究[J]. 電腦編程技巧與維護(hù),2017(18):40-43.
(編輯? 凌? 波)
作者簡(jiǎn)介
譚倚靖(1994—),女,工程師,主要從事大數(shù)據(jù)應(yīng)用相關(guān)工作。