T 沙龍移動實踐日總結 —— 蜂鳥團隊移動端異常監控體系建設

CodeTShanghai發表於2018-08-30

下面是 T 沙龍小編對分享的一些總結:

PPT 和 視訊

視訊地址
PPT地址

蜂鳥團隊移動端異常監控體系建設

第二個主講人是餓了麼蜂鳥團隊 Android 端負責人 - 潘萬坤。
從事安卓開發 6 年,先後在格瓦拉、餓了麼等公司從事安卓開發工作。目前擔任餓了麼物流移動團隊安卓負責人,主要關注移動端程式碼架構、效能優化等領域,負責保障 App 線上上的高穩定執行。他帶來的是餓了麼正在投入使用的移動端異常監控體系。

問題背景

在公司以往使用的常規 APM 系統及異常上報的資料中,存在以下三種問題:

  • Crash、ANR 等異常情況過於單一,很難進行進一步的分類;
  • 線上環境複雜,多數的 Case 均為測試和開發在日常的業務流程中無法覆蓋的情況,復現難度過高,也具有一定的實效性;
  • 除了對異常情況處理的被動防禦,提高發版質量的要求可以更加主動的解決問題;

於是針對這些問題,餓了麼蜂鳥團隊做了一套移動端異常監控體系來處理所有的問題,下面就是整個體系的結構圖:

T 沙龍移動實踐日總結 —— 蜂鳥團隊移動端異常監控體系建設
)

TimeBomb (自定義異常監控系統)

我們將其起名為TimeBomb,代表著一段時間內連續出現 N 次的異常。這種問題在蜂鳥產品的中暴露的場景有很多,例如登陸異常迭代異常定位異常大圖片申請卡頓等。

T 沙龍移動實踐日總結 —— 蜂鳥團隊移動端異常監控體系建設

我們通過實時監控資料,可以找到集中的上報問題。這裡橫軸反映的是時間區段,縱軸代表上報數目,而且還有很多的 filter 選項來控制是否展示資料曲線,可幫助我們只關注某幾個上報日誌的情況。

另外,對於日常關注打點,我們可以通過後臺配置來控制前端上報曲線的展示情況。其他的,可以根據某一欄位進行查詢,也可對某一個打點進行更深入的探究。

T 沙龍小編注:與 Kibana 系統極為相似;優勢在於可以在配置中增加我們所需要的資料,對 PM 和資料分析人員較為友好,具有資料的實時關注性。

Dogger日誌系統

Dogger 日誌系統 其實和日常的日誌系統關注點一樣,主要有四大關注要素:生命週期-Life點選事件-Click網路請求-Http自定義-Custom。並且在這基礎上,Dogger還有一些更加優勢的特點:

  • 通過 mmap 進行寫檔案,讓打點日誌記錄更加高效;
  • 雲控平臺實現遠端配置,可做到實時配置,及時上傳;
  • 壓縮比高,更加節省使用者端的流量;
  • 對於敏感資訊,採用強大的加密演算法,保障安全性;
  • 可生成自動化指令碼,功能強大;

Talk is cheap,所以蜂鳥團隊開源了 Dogger 日誌系統,詳見我們的 GitHub

T 沙龍移動實踐日總結 —— 蜂鳥團隊移動端異常監控體系建設
(專案即將從 Trojan 更名成 Dogger)

DoggerService

針對於客戶端的強大 Dogger 日誌系統,服務端也對應的推出了一套 DoggerService 來展示 Dogger 系統收集到的日誌資訊,做到很好的歸類。DoggerService 目前正在建設階段,以下列出寄予 DoggerService 的幾個小目標:

  • 可以優雅的展示日誌內容;
  • 對埋點的事件頻率做直觀的展示;
  • 對特定的業務模組有一定的資料分析能力;

目前,我們的 DoggerService 已經完成了大部分內容,下面是一些已經竣工的效果圖:

T 沙龍移動實踐日總結 —— 蜂鳥團隊移動端異常監控體系建設

DoggerMonitor

無論是 Dogger日誌系統 還是 DoggerService 的日誌記錄歸納和資料彙總系統,可以說都是在問題暴露了之後的排查手段。當然作為更加主動的開發者,保證開發和打包質量其實才是我們解決問題更加積極的方法。DoggerMonitor開發監控就是為了滿足這一需求從而誕生出的一個工具。

T 沙龍移動實踐日總結 —— 蜂鳥團隊移動端異常監控體系建設

DoggerMonitor 與業務開發人員的開發體驗息息相關。將其整合在 App 中後,我們可通過懸浮窗來實時檢視 FPS、CPU、記憶體佔用這些經常關注的指標。點選浮窗進入後也有具體的指標監控和歷史記錄曲線。在除錯過程中的堆疊情況也可在客戶端中實時記錄,這一功能對於 QA 測試人員在發現問題上報給研發做 Debug 時具有很好的定位問題的能力。

根據組內開發同學和 QA 同學的需求,我們對 DoggerMonitor 作出了一套適用於這些需求的架構:

T 沙龍移動實踐日總結 —— 蜂鳥團隊移動端異常監控體系建設
總的來看,整合 DoggerMonitor 十分容易,因為是通過 AOP 的無侵入方式來將功能整合。我們為每一種資料採集模組增加了 Dogger-Support 外掛來提供多種資料。

最後所有的資料都放置到了前端資料庫裡。

方法耗時 - Mirror

使用 Mirror 庫在對目的方法計算耗時,並記錄 Class 資訊和引數資訊。

void method(){
    long startTime = System.currentTimeMillis();
    ...
    ...
    long endTime = System.currentTimeMillis();
    MirrorUtils.mirror(endTime - startTime, className + methodName + params);
}
複製程式碼

卡頓 - BlockCanary

卡頓檢測團隊使用了 BlockCanary 這套開源的方案。BlockCanary 對主執行緒操作進行了完全透明的監控,並能輸出有效的資訊,幫助開發分析、定位到問題所在,迅速優化應用。這套方案有以下特點:

  • 非侵入式,簡單的兩行就開啟監控,不需要到處打點,破壞程式碼優雅性。
  • 精準,輸出的資訊可以幫助定位到問題所在(精確到行),不需要像Logcat一樣,慢慢去找。

Android 中有一個16毫秒原則,即在 60Hz 的重新整理頻率下,在 16毫秒之內完成繪製則會有更佳的使用者體驗而不感覺卡頓。

Choreographer.getInstance()
    .postFrameCallback(new Choreographer.FrameCallback() {
        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
        @Override
        public void doFrame(long l) {
            BlockCanaryManager.getInstance().stop(runnable);
            BlockCanaryManager.getInstance().start(runnable , TIME_BLOCK);
        }
    });
複製程式碼

流量統計 - TNet

TNet 一期是對於 HTTP 介面的監控。所以最初我們只對 HTTP 請求做了一個 hook,從而記錄了 request 和 response 的長度。

public class TNetInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
     
        recordHttp(request);
        recordHttp(response);
         
        return response;
    }
}
複製程式碼

對於三方的網路請求,通過 AOP 的方案,okhttp3.OkHttpClient 中將我們的 interceptors 方法 hook 進去,這樣就能統計到所有的 HTTP 請求情況。

@TargetClass("okhttp3.OkHttpClient")
@NameRegex("okhttp3/RealCall")
@Proxy("networkInterceptors")
public List<Interceptor> networkInterceptors() {
    List<Interceptor> interceptors = (List<Interceptor>) Origin.call();
    List<Interceptor> newList = new ArrayList<>(interceptors.size() + 1);
    newList.addAll(interceptors);
    
    newList.add(new TNetInterceptor());
    
    return newList;
}
複製程式碼

在蜂鳥的產品 APP 中,除了 HTTP 請求之外,還有其他的情況。所以二期打算做一個統計完整流量的方案。querySummary 方法可以根據不同的網路型別和開始結束時間具體查詢某一個請求的流量情況。但是這需要使用者的許可權。

BUILD_VERSION >= 23

NetworkStatsManager.querySummary(ConnectivityManager.TYPE_MOBILE,
        uid,
        startTime,
        endTime);
        
BUILD_VERSION < 23
TrafficStats.getUidRxBytes(uid) + TrafficStats.getUidTxBytes(uid);
複製程式碼

大圖片檢測 - ImageWatcher

在打包過程中,ImageWatcher 會檢測工程中的所有圖片。通過 computeSize 換算公式,可以根據不同的檔案目錄去匹配各種的解析度在將圖片載入到手機中 Bitmap 的大小。這樣,在打包時如果發現圖片 Bitmap 大小超出閾值,就可以丟擲一個錯誤,來提醒開發者圖片有問題。

public int computeSize(int targetDensity) {
    if (density == Image.DEFAULT) {
        return width * height * 4;
    } else {
        return (int) ((width * targetDensity / density + 0.5f)
                * (height * targetDensity / density + 0.5f)
                * 4);
    }
}
複製程式碼

另外通過 Hook BitmapFactory 的產生方法,列印出 Bitmap 的資訊,獲取到其使用大小,同樣超過閾值丟擲異常。

T 沙龍移動實踐日總結 —— 蜂鳥團隊移動端異常監控體系建設

總結

通過對蜂鳥團隊移動端異常監控體系的建設,主要解決了在業務人員在開發過程中的以下三個痛點:

  1. 線上異常的及時上報;
  2. 提高問題追查的效率;
  3. 保障開發版本的質量;

全套系統團隊均有開源的計劃,而不只是 Dogger。整個監控系統仍舊在建設中,也希望各位開發者多多提 issue 和 pull request,一起打造更加完善的監控平臺。另外,對於 DoggerService 的展望,可以與 QA 人員協助完成自動化測試流程,從而達到真正的 BDD 行為驅動開發的模式;另外 DoggerService 還需要更加強大的服務端後臺支援,這也是蜂鳥團隊在未來將要完善的元件。

相關文章