前言 : 在4月25日,我參加了前端早早聊的在線直播話題---前端如何搞監控。 聽完以後收穫很大。我將把會議總結爲前端搞監控的價值、須要監控的內容等方向去描述,並以自研監控SDK的經驗爲例,進一步瞭解前端搞監控的技術點所在。前端

一 前端監控系統概覽:
1 爲何要作一套前端監控系統?
經過用戶行爲採集分析,當前端及客戶端線上出現異常時,能夠經過用戶行爲鏈及設備環境,快速定位線上環境的問題所在。android
齊次,當功能上線後,用戶的使用效果沒辦法衡量。須要數據指標去衡量,好比功能使用率、性能指標等。數據庫
業務方的對業務的創意及需求須要反覆不斷的調優、開發,相同的組件開發了無數個,極可能明天又得改回去,這就形成了大量的資源浪費。若是沒有一個量化體系的話,運營只能經過上次成功的經驗來感受。因此須要經過對用戶數據的監控,從而獲得一個調優策略和量化指標。小程序
以後,咱們須要知道對於界面設計風格及投放的廣告資源,哪些手段會更有價值,去作一我的羣的細分,提升用戶體驗。微信小程序
2.前端監控須要監控什麼?
前端監控採集的內容主要包括行爲分析、異常監控、性能監控等。跨域
其行爲分析主要有:頁面的進入、離開、點擊、滾屏、自定義事件promise
簡單作法是在項目的編譯過程當中,將項目ID、頁面ID等掛載在標籤上,當進入頁面時,咱們就能夠根據這些ID去定位惟一一個頁面,這樣就能夠知道用戶的頁面進入、離開及按鈕的點擊等事件服務器



不過用戶可能並非完整地去走過了一個頁面點擊流程,而是從中間的頁面進入好比點擊了超連接,就須要讓收集到的數據更有參考價值,以更準確地反映用戶真實狀況。 在路徑分析裏,去查看用戶的來源和去向 微信



3.前端監控設計策略
3.1 面向組件設計監控策略
咱們將對網頁的埋點分爲以下幾個級別,從而更好地爲後面的分析提供服務網絡



爲了更方便分析數據。當內網訪問時,CDN判斷爲白名單用戶,就會爲頁面注入數據化分析能力,從而更方便地實時查看數據而無需再打開額外的數據分析平臺

3.2 面向業務設計監控策略
對於不一樣風格的組件,須要進行一個精準的人羣的劃分



整個下來須要有一個數據採集、數據存儲、數據清洗、數據異常、數據展現的過程。

其中採集方式包括無埋點採集和有埋點採集。 無埋點採集主要是經過在框架層預設SDK,預設通用的事件。 有埋點採集對用戶的瀏覽日誌、瀏覽內容、觸發時機等一些自定義事件的一種採集方式



二 自建前端監控體系
做爲開發運營者來講,自建前端監控體系,須要清楚地去分析及追蹤,當線上的前端與客戶端發生問題時,如何快速定位到這些問題並解決
1 以宋小菜APP爲例,針對APP自建前端監控體系
其目前的系統架構以下

首先須要明確要採集哪些錯誤日誌數據,而後去相應的設計SDK

RN SDK



在收集到的錯誤log裏使用kafka進行轉發

在日誌處理時,能夠採用一些策略
- 在向ES寫入JSON時,因爲數據量大,能夠按時或按天創建索引,從而不會查詢的時候特別慢
- 要創建一個統一的索引模板,對於索引的保存的數據類型要統一,不然會形成數據保存失敗
- 因爲上報的類型涉及到了多端,並且又包括自定義的上報內容,因此設計的上報的規範也不能太死。哪些字段變化哪些字段不變須要根據系統衡量

- 有一些字段是某些場景下是沒有必要創建索引的,不然會形成字段爆炸,那麼就能夠以String類型存儲下來
在報警監控系統的設計上,咱們能夠在監控後臺上建立報警任務,而後報警任務經過kafka推送到任務管理中,任務管理器根據不一樣的任務分發到任務執行器中

在收集到的錯誤信息上,都通過TraceKit作一個標準化,以後根據錯誤類型去作一個歸類,以下面這些特徵。根據這些特徵,來判斷信息是否爲重複的問題





2 以貝貝自研SDK爲例,對數據進行蒐集與清洗
在監控平臺上,貝貝選擇的是自研SDK,緣由是端平臺多、項目多,第三方須要去考慮成本,另外在擴展性、支持的平臺方面等,在目前的監控方案如Sentry、FundeBug、Bugly,也存在受限。


數據蒐集與上報
在前端,能夠經過上報上來的錯誤堆棧去分析應用出現的錯誤緣由,方便排查問題

上報方式SDK如何設計?
對於上報方式,能夠分爲自動上報(左)和手動上報(右)

- window.onerror:運⾏時錯誤捕獲
- window.addEventListener(‘unhandledrejection’):promise 沒有 catch 錯誤
- try/catch 處理跨域腳本錯誤
- 其餘技術棧中(Vue、React)的錯誤捕獲
例如在Vue中,咱們能夠劫持它的errorHandler,而後在發生錯誤的時候上報,以後再去執行剩下的操做


SDK又如何去作信息收集?





SDK如何進行數據上報?
使用經過GET方法發送一個1*1的GIF圖片及錯誤信息進行上報


數據清洗與壓縮:
SDK獲取到的數據量大、沒有分類聚合、也沒有過濾,因此須要去進行一個數據清洗
首先在存儲方案上,選擇MySQL做爲永久存儲,選擇ES做爲臨時存儲

對於收集到的數據設置閾值,即規定:
每分鐘數據獲取上限 10000 條,超過就採樣⼊庫。同類型錯誤數量⼤於 200 條,只統計數量
同時,因爲ES返回的是String流格式,須要使用JSON.parse()解析出來。 最後將下面的數據去作修正如去掉轉義符,忽略非法數據等。最終存到MySQL中。

在聚合的維度上,能夠分爲業務名、數據類型、錯誤信息 按照這樣的3個維度,作成MD5以用於判斷後面發生的錯誤是否爲相同的錯誤



數據告警
當監控條件知足時,監控平臺會將錯誤發送給相應的開發者

好比對於Android來講,當錯誤發生時,先存儲到本地的數據庫,而後進行嘗試地上報。若是上報成功,就將本地數據刪除,不然待下次APP啓動的時候再上報

3 基於錯誤日誌進行進一步的優化
在系統中,須要對數據日誌清洗、輔助分析能力、用戶界面展現、錯誤告警追蹤能力進行進一步優化
在錯誤聚合中可分爲通用優化和專用優化

若是本是同一個錯誤,卻由於一些緣由如發生錯誤的視圖信息(紅色部分)致使描述不一樣,就能夠只把相同的部分,錯誤名和錯誤堆棧作一個散列

這時能夠經過正則去掉系統類對應的行號去掉,再去散列


好比在前端上,能夠分析前端的行爲鏈路


監控系統最終還要造成一個錯誤閉環,當發生錯誤時,及時交付給相應開發人員,版本成功修復之後再對線上監控進行一個更新


在監控的篩選時間中,還要注意客戶端是先將錯誤保存到本地,以後會嘗試性地去上報錯誤。端側會累積錯誤並存在延遲,因此服務器接受到的錯誤極可能並非最新的錯誤。
因此對於數據的篩選與告警閾值的設定,就能夠有下面這兩種策略。
若是按服務端時間來進行篩選,就能夠定義一個小時內發生的錯誤爲最近的錯誤。若是按客戶端時間,則看在這一個小時內,哪些錯誤在一個小時內,其記錄的錯誤裏間隔一分鐘的時間的錯誤數量超過了閾值。

4 如何基於堆棧映射去定位問題?
前端問題的定位難在什麼地⽅?
前端的日誌不像服務端,它是發生在端側的,因此只能依賴於上報,但上報的話又不可能獲取到全部的信息,可能會缺失上下文,另外前端代碼會進行混淆,堆棧沒法直接使用。

能夠在服務端將堆棧作個SourceMap映射到源碼上
但會有一些問題,好比可能由於依賴的包的版本變化,致使線上映射後和實際生產環境的代碼不對應。SourceMap映射也相對較慢,等映射完再去排查可能浪費了不少時間並且映射時會佔用很大內存
給出的解決方案是異步生成SourceMap。首先鎖定依賴,避免後面因版本問題致使堆棧對不上,以後將SourceMap映射和正常的版本構建分離開,這樣就不會因SourceMap的佔用內存過大致使影響正常版本的上線





三 監控系統在實際應用中還存在的問題
1.有些異常是因爲手機廠商、第三方注入等致使的,並非實際業務引發的






四 感觸
從會議中瞭解到了前端搞監控的巨大意義和相關技術點,使用監控系統從而更好地提高用戶體驗和產品開發以及問題排查,這些都是本身以前從未接觸過的。特別感謝前端早早聊大會的分享,收穫頗多!
五 關於前端早早聊大會
關於前端早早聊大會:前端早早聊大會目標成爲用得上、聽得懂、抄得走的技術大會,計劃 2020年辦>= 15期,由前端早早聊與掘金聯合舉辦,前端早早聊大會行程動態、錄播視頻/PPT/講稿資料下載請關注 「前端早早聊」 公衆號跟進。
