下面是 T 沙龍小編對分享的一些總結:html
第二個主講人是餓了麼蜂鳥團隊 Android 端負責人 - 潘萬坤。
從事安卓開發 6 年,前後在格瓦拉、餓了麼等公司從事安卓開發工做。目前擔任餓了麼物流移動團隊安卓負責人,主要關注移動端代碼架構、性能優化等領域,負責保障 App 在線上的高穩定運行。他帶來的是餓了麼正在投入使用的移動端異常監控體系。java
在公司以往使用的常規 APM 系統及異常上報的數據中,存在如下三種問題:git
因而針對這些問題,餓了麼蜂鳥團隊作了一套移動端異常監控體系來處理全部的問題,下面就是整個體系的結構圖:github
)咱們將其起名爲TimeBomb,表明着一段時間內連續出現 N 次的異常。這種問題在蜂鳥產品的中暴露的場景有不少,例如登錄異常、迭代異常、定位異常、大圖片申請、卡頓等。算法
咱們經過實時監控數據,能夠找到集中的上報問題。這裏橫軸反映的是時間區段,縱軸表明上報數目,並且還有不少的 filter 選項來控制是否展現數據曲線,可幫助咱們只關注某幾個上報日誌的狀況。數據庫
另外,對於平常關注打點,咱們能夠經過後臺配置來控制前端上報曲線的展現狀況。其餘的,能夠根據某一字段進行查詢,也可對某一個打點進行更深刻的探究。api
T 沙龍小編注:與 Kibana 系統極爲類似;優點在於能夠在配置中增長咱們所須要的數據,對 PM 和數據分析人員較爲友好,具備數據的實時關注性。安全
Dogger 日誌系統 其實和平常的日誌系統關注點同樣,主要有四大關注要素:生命週期-Life、點擊事件-Click、網絡請求-Http和自定義-Custom。而且在這基礎上,Dogger還有一些更加優點的特色:性能優化
Talk is cheap,因此蜂鳥團隊開源了 Dogger 日誌系統,詳見咱們的 GitHub。
(項目即將從 Trojan 改名成 Dogger)針對於客戶端的強大 Dogger 日誌系統,服務端也對應的推出了一套 DoggerService 來展現 Dogger 系統收集到的日誌信息,作到很好的歸類。DoggerService 目前正在建設階段,如下列出寄予 DoggerService 的幾個小目標:
目前,咱們的 DoggerService 已經完成了大部份內容,下面是一些已經竣工的效果圖:
不管是 Dogger日誌系統 仍是 DoggerService 的日誌記錄概括和數據彙總系統,能夠說都是在問題暴露了以後的排查手段。固然做爲更加主動的開發者,保證開發和打包質量其實才是咱們解決問題更加積極的方法。DoggerMonitor開發監控就是爲了知足這一需求從而誕生出的一個工具。
DoggerMonitor 與業務開發人員的開發體驗息息相關。將其集成在 App 中後,咱們可經過懸浮窗來實時查看 FPS、CPU、內存佔用這些常常關注的指標。點擊浮窗進入後也有具體的指標監控和歷史記錄曲線。在調試過程當中的堆棧狀況也可在客戶端中實時記錄,這一功能對於 QA 測試人員在發現問題上報給研發作 Debug 時具備很好的定位問題的能力。
根據組內開發同窗和 QA 同窗的需求,咱們對 DoggerMonitor 做出了一套適用於這些需求的架構:
總的來看,集成 DoggerMonitor 十分容易,由於是經過 AOP 的無侵入方式來將功能集成。咱們爲每一種數據採集模塊增長了 Dogger-Support 插件來提供多種數據。最後全部的數據都放置到了前端數據庫裏。
使用 Mirror 庫在對目的方法計算耗時,並記錄 Class 信息和參數信息。
void method(){
long startTime = System.currentTimeMillis();
...
...
long endTime = System.currentTimeMillis();
MirrorUtils.mirror(endTime - startTime, className + methodName + params);
}
複製代碼
卡頓檢測團隊使用了 BlockCanary 這套開源的方案。BlockCanary 對主線程操做進行了徹底透明的監控,並能輸出有效的信息,幫助開發分析、定位到問題所在,迅速優化應用。這套方案有如下特色:
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 一期是對於 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 會檢測工程中的全部圖片。經過 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 的信息,獲取到其使用大小,一樣超過閾值拋出異常。
經過對蜂鳥團隊移動端異常監控體系的建設,主要解決了在業務人員在開發過程當中的如下三個痛點:
全套系統團隊均有開源的計劃,而不僅是 Dogger。整個監控系統仍舊在建設中,也但願各位開發者多多提 issue 和 pull request,一塊兒打造更加完善的監控平臺。另外,對於 DoggerService 的展望,能夠與 QA 人員協助完成自動化測試流程,從而達到真正的 BDD 行爲驅動開發的模式;另外 DoggerService 還須要更增強大的服務端後臺支持,這也是蜂鳥團隊在將來將要完善的組件。