有贊移動Crash平臺建設(shè)
作者:王劍標(biāo)
部門:電商移動
背景 & 痛點 & 價值
某次版本上線之后,沒有及時發(fā)現(xiàn)其隱藏的Crash, 導(dǎo)致故障產(chǎn)生 Crash發(fā)生之后,無法根據(jù)特定規(guī)則分給某位處理人。 某個版本上線灰度時,該版本在特定角色下存在Crash。這個時候沒法中斷灰度版本的下發(fā)
crash平臺建設(shè)的線路規(guī)劃
基礎(chǔ)架構(gòu)搭建。Crash的收集、上報、分類、查看、處理
增加三方平臺沒有的功能。實時監(jiān)控、告警、日報
補齊三方平臺的功能,Crash趨勢統(tǒng)計、Crash符號化
crash平臺的功能集
Crash收集:某次Crash從發(fā)生,保存本地到上報的過程 Crash查看:查看Crash的發(fā)生堆棧,版本分布,發(fā)生頁面,操作頁面路徑,幫助處理人快速定位問題。 Crash處理人以及狀態(tài):將某個Crash分配給指定人,發(fā)送通知。處理人修復(fù)完成之后,修改Crash的狀態(tài)。 Crash分類:根據(jù)上報的Crash將Crash進行分組,不同機型、不同版本可能發(fā)生同一個Crash,某個Crash標(biāo)識某段代碼錯誤。 Crash告警檢測:針對新版本引入的Crash以及因為服務(wù)端變更引起的老版本Crash,增加告警功能,第一時間發(fā)現(xiàn)影響面廣的Crash問題。 Crash報告:每日報告,本日Crash情況,讓團隊的小伙伴能夠清晰的了解到當(dāng)天整體的crash情況,及時解決crash次數(shù)較多的問題。
Crash平臺整體設(shè)計

為了避免crash堆棧的數(shù)據(jù)量過大,crash堆棧等長字段存儲至HBase. Mysql中只要存儲前128預(yù)覽字符與Hbase中的row_key即可
一、實現(xiàn)方案
1.1 Crash發(fā)生時的攔截+上報
Thread.UncaughtExceptionHandler接口,在初始化的時候?qū)⒕€程默認(rèn)的Handler替換為我們攔截的Handler(當(dāng)然別忘了調(diào)用下原先默認(rèn)的handler)。1.2 Crash收集、數(shù)據(jù)整理--分組歸類及自動分配處理人
1.2.1 Crash收集
為什么要用埋點平臺, 而不是用自己上報?
埋點平臺在收到來自客戶端的數(shù)據(jù)后為我們做了哪些工作

前端監(jiān)控用戶行為,收集并通過http請求上報 NIO高并發(fā)日志接收服務(wù)將日志轉(zhuǎn)發(fā)到rsyslog服務(wù)器中 rsyslog服務(wù)器再通過logstash轉(zhuǎn)發(fā)到kafka原始日志中 flink實時ETl任務(wù)將原始日志加工成標(biāo)準(zhǔn)中間層格式,并繼續(xù)落地到kafka 最后消息會到我們的Crash收集flink任務(wù)程序crash-clollection-task
消息:
// 隱去敏感數(shù)據(jù),更改為測試數(shù)據(jù)
{
topic: "topic.log",
servers: "****",
type: "kafka010",
consumerGroup: "crash_collection_task"
}@Override
public boolean filter(String line) {
try {
JSONObject data = JSON.parseObject(line);
String type = data.getString("event_type");
return Objects.equal(type, "crash");
} catch (Exception e) {
System.out.println(String.format("line:[%s]: \n解析發(fā)生錯誤:%s", line, e.toString()));
}
return false;
}1.2.2 分組歸類、自動分配處理人
分組歸類
groupIdprivate String generateGroupId() {
String groupKey = MD5Utils.crypt(bundleId + crashType + crashReason + pageType);
return "Android-v4-" + groupKey;
}
自動分配處理人
配置清單分配
歷史頁面自動分配
配置清單分配
{
"modules": [
{
"name": "xxxxSDK",
"key_stacks": [
"com.youzan.mobile.xxxx"
],
"cas_id": 10086
}
}歷史頁面自動分配
2.2 Crash實時監(jiān)控、每日報告
2.2.1 版本過濾
想要過濾版本就需要知道目前某個App的最新版本多少。目前有贊移動端的打包發(fā)版控制已經(jīng)都使用自研的構(gòu)建發(fā)布平臺。
crash上報之后,只要它的版本號大于等于最新全量的版本號,就實時上報到秒級響應(yīng)群,以便及時發(fā)現(xiàn)最新版本、灰度版本、項目測試包的crash問題。
2.2.2?每日報告
每日報告功能有兩個目的,一是為了讓各個App負(fù)責(zé)人對每天的Crash大致狀況有個大致上的了解。二是為了讓沒時間及時處理的小伙伴,當(dāng)有屬于自己的模塊,發(fā)生次數(shù)、影響面比較大的Crash出現(xiàn)時要引起重視。
基于這樣的目的我們在每日報告中加了每日Crash變化趨勢(與前一日相比)、每日Crash Top N兩大塊。這里主要講下設(shè)計思路。
每日Crash變化趨勢
碰到的坑
起初昨日與今日的Crash次數(shù)是按照自然日取的。這樣有個問題,就是昨日的次數(shù)是一整天的,今天的次數(shù)不是一整天。所以這里對比,應(yīng)該以報告時間往前24小時內(nèi)、48~24小時,這樣來對比。才能正常反饋Crash的變化趨勢。
每日Crash Top N
排序規(guī)則
排序的背后是Crash的影響面大小,影響面大的排在前。這樣讓處理人與管理者能每天及時知曉影響大的Crash有哪些,是否需要及時處理等等目的。
我們?yōu)槭裁催x擇了Top3?
其實開始不是Top3 ,而是Top10。但是運轉(zhuǎn)一段時間后發(fā)現(xiàn),crash問題并不多,每天匯報時都報Top10,會有大部分次數(shù)少的crash,會讓人失焦。無論是管理者還是處理人,都搞不清楚,某個問題是該及時處理還是可以延后處理。再集合運轉(zhuǎn)的這一段時間的平均數(shù)據(jù),最終選擇了Top3。
技術(shù)實現(xiàn)

2.3 Crash反饋平臺--管理后臺
如何快速定位問題
4.47.0改了某塊代碼之后,發(fā)布至線上,因為用戶老數(shù)據(jù)的問題,Crash一直隱藏著帶到了線上。此時根據(jù)發(fā)生過的應(yīng)用版本就能很快定位到Crash就是出現(xiàn)在4.47.0這個版本上。

更詳細(xì)的排查維度

Crash離線日志
總結(jié)
評論
圖片
表情


