xlog學習記錄

基礎認識

mars 是微信官方的終端基礎組件

  • C++ 編寫(為了兼容多平臺)
  • 業務性無關,平臺性無關的基礎組件
  • 支持接入 Android 或者 iOS/OS X 或者 Windows
    mars架構
  • comm:可以獨立使用的公共庫,包括 socket、線程、消息隊列、協程等;
  • xlog:高可靠性高性能的運行期日志組件;
  • SDT: 網絡診斷組件;
  • STN: 信令分發網絡模塊,也是 Mars 最主要的部分。

優勢

對于終端設備來說,打日志并不只是把日志信息寫到文件里這么簡單。除了流暢性,** 完整性 容錯性,還有一個最重要的是安全性**。基于不怕被破解,但也不能任何人都能破解的原則, 對日志的規范比加密算法的選擇更為重要,所以這里并沒有討論這一點。

一個優秀的終端日志模塊無論怎么設計都必須做到:

  1. 不能把用戶的隱私信息打印到日志文件里,不能把日志明文打到日志文件里。
  2. 不能影響程序的性能。最基本的保證是使用了日志不會導致程序卡頓。
  3. 不能因為程序被系統殺掉,或者發生了 crash,crash 捕捉模塊沒有捕捉到導致部分時間點沒有日志, 要保證程序整個生命周期內都有日志。
  4. 不能因為部分數據損壞就影響了整個日志文件,應該最小化數據損壞對日志文件的影響。

上面這幾點也即一直強調的 安全性 流暢性 完整性 容錯性, 它們之間存在著矛盾關系

  • 如果直接寫文件會卡頓,但如果使用內存做中間 buffer 又可能丟日志
  • 如果不對日志內容進行壓縮會導致 IO 卡頓影響性能,但如果壓縮,部分損壞可能會影響整個壓縮塊,而且為了增大壓縮率集中壓縮又可能導致 CPU 短時間飆高。

mars 的日志模塊 xlog 就是在兼顧這四點的前提下做到:高性能高壓縮率、不丟失任何一行日志、避免系統卡頓和 CPU 波峰。

使用(Android)

gradle 接入我們提供了兩種接入方式:mars-wrapper 或者 mars-core。如果你只是想做個 sample 推薦使用 mars-wrapper,可以快速開發;但是如果你想把 mars 用到你的 app 中的話,推薦使用 mars-core,可定制性更高。

mars-wrapper

在 app/build.gradle 中添加 mars-wrapper 的依賴:

dependencies {
    compile 'com.tencent.mars:mars-wrapper:1.2.0'
}

或者

mars-core

在 app/build.gradle 中添加 mars-core 的依賴:

dependencies {
    compile 'com.tencent.mars:mars-core:1.2.2'
}

或者

mars-xlog

如果只想使用 xlog,可以只加 xlog 的依賴(mars-core,mars-wrapper 中都已經包括 xlog):

dependencies {
    compile 'com.tencent.mars:mars-xlog:1.0.7'
}

接著往下操作之前,請先確保你已經添加了 mars-wrapper 或者 mars-core 或者 mars-xlog 的依賴

Xlog Init

在程序啟動加載 Xlog 后緊接著初始化 Xlog。但要注意如果你的程序使用了多進程,不要把多個進程的日志輸出到同一個文件中,保證每個進程獨享一個日志文件。而且保存 log 的目錄請使用單獨的目錄,不要存放任何其他文件防止被 xlog 自動清理功能誤刪。

System.loadLibrary("c++_shared");
System.loadLibrary("marsxlog");

final String SDCARD = Environment.getExternalStorageDirectory().getAbsolutePath();
final String logPath = SDCARD + "/marssample/log";

// this is necessary, or may crash for SIGBUS
final String cachePath = this.getFilesDir() + "/xlog"

//init xlog
if (BuildConfig.DEBUG) {
    Xlog.appenderOpen(Xlog.LEVEL_DEBUG, Xlog.AppenderModeAsync, cachePath, logPath, "MarsSample", 0, "");
    Xlog.setConsoleLogOpen(true);

} else {
    Xlog.appenderOpen(Xlog.LEVEL_INFO, Xlog.AppenderModeAsync, cachePath, logPath, "MarsSample", 0, "");
    Xlog.setConsoleLogOpen(false);
}

Log.setLogImp(new Xlog());

程序退出時關閉日志:

Log.appenderClose();

如果你想修改 Xlog 的加密算法或者長短連的加解包部分甚至更改組件的其他部分,可以參考這里

Log生成完畢后,會在指定的路徑下生成相應的日志文件:

shell@R7:/sdcard/marssample/log $ ll
-rw-rw---- root     sdcard_r   153600 2016-12-30 17:06 MarsSample.mmap2
-rw-rw---- root     sdcard_r    29633 2016-12-30 17:06 MarsSample_20161230.xlog

其中MarsSample.mmap2是緩存文件,不用關心,我們需要的是.xlog文件,我們把這個文件pull出來,使用Mars提供的Python腳本進行解密。
找到Mars源碼log/crypt/decode_mars_log_file.py下的這個文件,執行:

?  mars_xlog_sdk python decode_mars_log_file.py ~/Downloads/log/MarsSample_20161230.xlog

即可生成對應的log文件,用Sublime即可打開

常用 API 說明

Xlog.java

public static native void appenderOpen(int level, int mode, String cacheDir, String logDir, String nameprefix, int  cacheDays, String pubkey);

初始化日志需要調用的接口。

  • level: 日志級別,變量見 Xlog.java 里 LEVEL_XX, Debug版本推薦 LEVEL_DEBUG, Release 版本推薦 LEVEL_INFO
  • mode : 文件寫入模式,分異步和同步,變量定義見 Xlog.java 里 AppednerModeXX, Release版本一定要用 AppednerModeAsync, Debug 版本兩個都可以,但是使用 AppednerModeSync 可能會有卡頓。
  • cacheDir : 緩存目錄,當 logDir 不可寫時候會寫進這個目錄,可選項,不選用請給 "", 如若要給,建議給應用的 /data/data/packname/files/log 目錄。
  • logDir : 日志寫入目錄,請給單獨的目錄,除了日志文件不要把其他文件放入該目錄,不然可能會被日志的自動清理功能清理掉。
  • nameprefix : 日志文件名前綴,例如該值為TEST,生成的文件名為:TEST_20170102.xlog。
  • cacheDays : 一般情況下填0即可。非0表示會在 _cachedir 目錄下存放幾天的日志。
  • pubkey : 加密所用的 pub_key,具體可參考 Xlog 加密指引

public static native void setConsoleLogOpen(boolean isOpen);
  • 是否會把日志打印到 logcat 中, 默認不打印。
  • isOpen : true 為打印,false為不打印。

Log.java

該文件包含打印日志最常調用的接口。

public static void setLogImp(LogImp imp)

設置 Log 的具體實現,這里必須調用 Log.setLogImp(new Xlog()); 日志才會寫到 Xlog 中。

public static void appenderFlush(boolean isSync) 

當日志寫入模式為異步時,調用該接口會把內存中的日志寫入到文件。

  • isSync : true 為同步 flush,flush 結束后才會返回。 false 為異步 flush,不等待 flush 結束就返回。強制將緩存中的輸出流(字節流,字符流等)強制輸出.
public static void appenderClose()

關閉日志,在程序退出時調用。

public static void f/e/w/i/d(final String tag, final String msg)

寫日志時調用的接口,對應不同級別的日志。

問題

常見問題

重要技術點

技術實現思路:使用流式方式對單行日志進行壓縮,壓縮加密后寫進作為 log 中間 buffer的 mmap 中

技術水準有多牛逼,就看這個

mmap

如果大家對binder的實現有看過就知道,binder就是使用mmap來實現一次拷貝的跨進程的。


mmap 是使用邏輯內存對磁盤文件進行映射,中間只是進行映射沒有任何拷貝操作,避免了寫文件的數據拷貝。操作內存就相當于在操作文件,避免了內核空間和用戶空間的頻繁切換。

等于寫內存的速度:把512 Byte的數據分別寫入150 kb大小的內存和 mmap,以及磁盤文件100w次并統計耗時


xlog實現方案:先壓縮再加密效率比較高,這個順序不能改變。而且在寫入 mmap 之前先進行壓縮,也會減少所占用的 mmap 的大小,進而減少 mmap 所占用內存的大小。就是其他模塊每寫一行日志日志模塊就必須進行壓縮。

壓縮方案


第三種是把整個 app 生命周期作為一個壓縮單位進行壓縮,如果這個壓縮單位中有數據損壞,那么后面的日志也都解壓不出來

但其實在短語式壓縮過程中,滑動窗口并不是無限大的,一般是 32kb ,所以只需要把一定大小作為一個壓縮單位就可以了。這也就是第四個方案, 這樣的話即使壓縮單位中有部分數據損壞,因為是流式壓縮,并不影響這個單位中損壞數據之前的日志的解壓,只會影響這個單位中這個損壞數據之后的日志

使用流式壓縮后,和之前使用通用壓縮的的日志方案進行了對比(耗時為單行日志的平均耗時):


多條日志同時壓縮會導致 CPU 曲線短時間內極速升高,進而可能會導致程序卡頓,而流式壓縮是把時間分散在整個生命周期內,CPU 的曲線更平滑,相當于把壓縮過程中使用的資源均分在整個 app 生命周期內。雖說時間上升了,但是分攤后CPU曲線更為平滑,實際上是性能的提升。

參考內容
github Mars 項目
mars Android 接入指南
聊聊微信 Xlog
【Dev Club 分享】微信mars 的高性能日志模塊 xlog

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,748評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,165評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,595評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,633評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,435評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,943評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,035評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,175評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,713評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,599評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,788評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,303評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,034評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,412評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,664評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,408評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,747評論 2 370

推薦閱讀更多精彩內容

  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom閱讀 2,714評論 0 3
  • 同步地址 本文介紹 MARS xlog 使用以及使用過程中踩過的坑 xlog 是什么 xlog 是微信開源框架 M...
    Noah牛YY閱讀 12,320評論 2 0
  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當在唯一索引所對應的列上鍵入重復值時,會觸發此異常。 O...
    我想起個好名字閱讀 5,375評論 0 9
  • 看完了微信團隊對Xlog的整體介紹,迫不及待開始了研究,理論部分我是完全參考微信終端跨平臺組件 mars 系列(一...
    星期五__閱讀 9,563評論 2 17
  • WinRAR - 最新版本的更新 版本 5.50 1. WinRAR 和命令行 RAR 默認使用 RAR ...
    王舒璇閱讀 2,403評論 0 2