App技術(shù)選型--Xlog

title: App技術(shù)選型--日志框架--- **版 本 歷 史**| **版本** | **責(zé)任人** | **日期** | **備注** ||----------|------------|------------|------------|| V1.0 | 曾維銘 | 2017-04-12 | 創(chuàng)建文檔。 |日志對于開發(fā)來說是非常重要的,不管是調(diào)試數(shù)據(jù)查看、bug問題追蹤定位、數(shù)據(jù)信息收集統(tǒng)計,日常工作運行維護等等,都大量的使用到。# 功能需求* 線程的信息* 類的信息* 方法的信息* 格式打印JSON、XML等* 點擊鏈接跳轉(zhuǎn)到源碼打印處* 擁有默認(rèn)TAG和自定義TAG* release包中不能泄漏Log* 使用友好,使用高效* 日志持久化到本地* 日志框架的擴展性# [Xlog](https://github.com/Tencent/mars/wiki/Mars-Android-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97)mars 是微信官方的終端基礎(chǔ)組件,是一個使用C編寫的業(yè)務(wù)性無關(guān),平臺性無關(guān)的基礎(chǔ)組件。Xlog是mars中可以獨立使用的日志模塊。**優(yōu)勢:** * 性能好:使用了中間層,減少了讀寫磁盤的次數(shù)。使用mmap進行邏輯內(nèi)存對磁盤文件進行映射,中間只是進行映射沒有任何拷貝操作,避免了寫文件的數(shù)據(jù)拷貝,操作內(nèi)存就相當(dāng)于在操作文件,避免了內(nèi)核空間和用戶空間的頻繁切換。占用內(nèi)存CPU資源少。* 功能豐富:與原生Log使用幾乎一致,但增加了寫入文件功能,同時自帶加密* 穩(wěn)定:騰訊微信團隊正在使用,久經(jīng)考驗。**面臨的問題:*** Xlog是用C寫的,出問題調(diào)試起來不太友好。 * so庫比較大,導(dǎo)入后APK增大1.5M。**解決方案:*** 只能通過 xlog 輸出的信息進行排查。不過日志作為輔助系統(tǒng),出問題可能性低,而且問題影響不大。* 如果很在乎APK包大小的話,可以只集成armeabi的so包。 # 持久化的實現(xiàn)為了提高日志的性能,Xlog引入了 mmap作為中間buff層,當(dāng)buff層滿足一定條件時,才將日志寫到存儲空間。# 日志存儲位置初始化時,寫在logPath中。logPath = Environment.getExternalStorageDirectory().getAbsolutePath()/sdcard/PhiComm/app name/logs# 日志文件命名APP名_日期# 日志格式一般內(nèi)容:[日志級別][日期][PID][TAG(類名)][線程---日志內(nèi)容]方法棧:[日志級別][日期][PID][TAG(類名)][線程---方法棧]# 日志使用策略每次啟動時會刪除過期文件,只保留十天內(nèi)的日志文件(該值定義在appender.cc中的 kMaxLogAliveTime ),所以給 Xlog 的目錄請使用單獨目錄,防止誤刪其他文件。目前不會根據(jù)文件大小進行清理。如若想自定義清理邏輯請自行更改appender.cc中的 __del_timeout_file 函數(shù)。 # 日志使用級別

debugrelease

控制臺持久化控制臺持久化

v程序說明nullnull程序說明

d需要調(diào)試的代碼nullnullnull

i程序正常運行時日志程序正常運行時日志null程序正常運行時日志

w會出現(xiàn)潛在錯誤的情形會出現(xiàn)潛在錯誤的情形null會出現(xiàn)潛在錯誤的情形

ecatch塊中,程序狀態(tài)檢查語句catch塊中,程序狀態(tài)檢查語句nullcatch塊中,程序狀態(tài)檢查語句

# 日志混淆問題類名,方法名等參數(shù)使用的是Java lang包下的StackTraceElement和Throwable獲得。具體混淆策略需要在原型中測試后才能確定。# LogUtils由于Xlog提供的功能有限,為了滿足使用需求,這里對Xlog進行了封裝。實現(xiàn)的功能:* 支持打印字符串,集合,JSON,日志級別,日期,線程ID,線程名,異常信息,堆棧信息,源代碼跳轉(zhuǎn)。* 日志持久化到外部存儲,自動清理過期日志,保存最近十天的日志文件。## 使用指南### 1.添加讀寫權(quán)限``````

### 2.在Application的onCreate中初始化

初始化:

```

LogUtils.init();

```

**注:**

1. 為了不造成混亂,這里初始化時不提供自定義配置。如日志默認(rèn)TAG,保存路徑,日志方法棧打印數(shù)量等在代碼中寫死。

2. 根據(jù)BuildConfig.DEBUG參數(shù),debug下會打印到控制臺,release下控制臺輸出關(guān)閉。

### 3.打印日志

```

? ? public static void d(Object message)

? ? public static void d(Object message, boolean isPrStack)

? ? public static void d(String tag, Object message, boolean isPrStack) {

? ? public static void d(String tag,final String message, boolean isPrStack, final Object... args)

public static void json(String json, boolean isPrStack)

public static void log(int priority, String tag, Object message, boolean isPrStack, @Nullable Throwable throwable, Object...args)

```

**注:**

1. message為打印內(nèi)容,可接收任意參數(shù)。

2. isPrStack控制是否打印堆棧信息。

3. 支持對日志字符串格式化,args為參數(shù)。內(nèi)部會調(diào)用String.format(String format, Object args)。

3. JSON輸出的縮進默認(rèn)為2,可自行修改。

4. 打印異常信息可調(diào)用log,傳入Throwable。

5. 堆棧打印的方法數(shù)通過METHOD_CCOUNT控制,默認(rèn)為8??梢宰孕行薷模赡芤紤]線程安全問題,不過影響也不大)。

打印JSON結(jié)果

```

[I][2017-04-20 +8.0 15:52:40.412][12502, 1*][PhiComm][, , 0][Thread:main---{

? "name": "BeJson",

? "url": "http:\/\/www.bejson.com",

? "page": 88,

? "isNonProfit": true,

? "address": {

? ? "street": "科技園路.",

? ? "city": "江蘇蘇州",

? ? "country": "中國"

? },

? "links": [

? ? {

? ? ? "name": "Google",

? ? ? "url": "http:\/\/www.google.com"

? ? },

? ? {

? ? ? "name": "Baidu",

? ? ? "url": "http:\/\/www.baidu.com"

? ? },

? ? {

? ? ? "name": "SoSo",

? ? ? "url": "http:\/\/www.SoSo.com"

? ? }

? ]

}

```

字符串,堆棧,Throwable打印結(jié)果

```

[D][2017-04-20 +8.0 15:52:40.411][12502, 1*][Throw][, , 0][Thread:main---{i=zwm, love=joyce}

VMStack.java/dalvik.system.VMStack/getThreadStackTrace/-2

Thread.java/java.lang.Thread/getStackTrace/580

LogUtils.java/com.example.weimingzeng.myapplication.LogUtils/getThreadStack/206

LogUtils.java/com.example.weimingzeng.myapplication.LogUtils/log/232

MainActivity.java/com.example.weimingzeng.myapplication.MainActivity/onCreate/31

Activity.java/android.app.Activity/performCreate/6323

Instrumentation.java/android.app.Instrumentation/callActivityOnCreate/1108

ActivityThread.java/android.app.ActivityThread/performLaunchActivity/2385:java.lang.Throwable

at com.example.weimingzeng.myapplication.MainActivity.onCreate(MainActivity.java:31)

at android.app.Activity.performCreate(Activity.java:6323)

at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108)

at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2385)

at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2492)

at android.app.ActivityThread.access$900(ActivityThread.java:153)

at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1358)

at android.os.Handler.dispatchMessage(Handler.java:102)

at android.os.Looper.loop(Looper.java:148)

at android.app.ActivityThread.main(ActivityThread.java:5458)

```

在程序退出時反初始化:

```

LogUtils.unLoad();

```

### 4.解析Log

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

```

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

```

由于使用緩存,日志只有在應(yīng)用退出時才會將日志寫入外部存儲。其中MarsSample.mmap2是緩存文件,不用關(guān)心,我們需要的是.xlog文件,我們把這個文件pull出來,使用Mars提供的Python腳本進行解密。

找到Mars源碼log/crypt/decode_mars_log_file.py下的這個文件,用python執(zhí)行,生成log文件:

```

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

```

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容