掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
背景

創(chuàng)新互聯(lián)建站主營珠海網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,重慶APP軟件開發(fā),珠海h5小程序定制開發(fā)搭建,珠海網(wǎng)站營銷推廣歡迎珠海等地區(qū)企業(yè)咨詢
監(jiān)控是提高故障處理能力和保障服務(wù)質(zhì)量必需的一環(huán),它需要負(fù)責(zé)的內(nèi)容包括:及時上報錯誤、收集有效信息、提供故障排查依據(jù)。
監(jiān)控分類
綜上所述,我們的監(jiān)控平臺強(qiáng)調(diào)實時性和全面性。為了保證實時性,錯誤發(fā)生時就嘗試上報,并且在監(jiān)控面板可以實時的展現(xiàn)出來,以及有及時的告警機(jī)制。全面性是指收集的信息全面,包括用戶信息、環(huán)境信息和錯誤信息等,因此監(jiān)控平臺包括記錄型監(jiān)控和捕捉型監(jiān)控。
頁面訪問記錄:用戶訪問了哪些頁面。
資源加載記錄:頁面中加載了哪些資源。
用戶行為記錄:用戶在頁面上做了哪些操作,目前我們只記錄用戶的點擊行為。
接口調(diào)用相關(guān)記錄:頁面調(diào)用了哪些接口。
DNS劫持:頁面是否被劫持。
資源加載錯誤:哪些資源加載失敗了,為了捕獲跨域JavaScript的錯誤,需要在相應(yīng)資源標(biāo)簽上添加crossorigin屬性。
頁面錯誤:頁面渲染過程中出現(xiàn)的錯誤。
內(nèi)部邏輯錯誤:用戶特定操作出現(xiàn)的錯誤,通過用戶行為定位。
接口錯誤:調(diào)用接口失敗。
場景還原法
當(dāng)捕捉型監(jiān)控捕捉到錯誤后,我們根據(jù)錯誤信息定位用戶,再通過記錄型監(jiān)控還原該錯誤發(fā)生的場景,從而復(fù)現(xiàn)問題并及時定位解決。這個過程我們稱之為場景還原法。
本監(jiān)控平臺就是通過收集監(jiān)控數(shù)據(jù),使用場景還原法來解決問題。它將支撐系統(tǒng)處理過的所有記錄和錯誤按照時間順序展示。通過場景還原的列表,我們可以還原出指定用戶在瀏覽頁面過程中發(fā)生的所有事情及其先后順序,從而判斷問題發(fā)生的時機(jī)和環(huán)境。
假設(shè)以下場景:
在以上這種用戶可能有多種操作的場景中,場景還原法可以針對特定用戶,還原其完整的操作路徑和頁面上發(fā)生的所有事情,幫助復(fù)現(xiàn)問題。
另外,一些非必現(xiàn)的問題,常常是由于不同機(jī)型或環(huán)境引起的,也可以在場景還原中復(fù)現(xiàn)問題的發(fā)生環(huán)境予以判斷。
本文主要介紹點餐終端技術(shù)組監(jiān)控平臺HUNT的前端SDK的實踐經(jīng)驗,仍有許多需要改進(jìn)的地方,歡迎大家拍磚,幫助我們改進(jìn)。
整體設(shè)計
如圖所示,我們的監(jiān)控平臺HUNT,分為前端SDK、Web層支撐系統(tǒng)和監(jiān)控面板三大部分。
前端SDK運行在前端頁面中,收集監(jiān)控數(shù)據(jù)上報到支撐系統(tǒng)里,作為監(jiān)控面板上查詢的數(shù)據(jù)源。
就前端SDK來說,可以分為數(shù)據(jù)模塊、數(shù)據(jù)處理模塊、上報模塊三大部分,其中數(shù)據(jù)模塊包括各具體監(jiān)控數(shù)據(jù)模塊和環(huán)境數(shù)據(jù)模塊:
各監(jiān)控模塊:獲取需要上報的具體內(nèi)容信息(EventData或ErrorData)
DNS劫持檢測
資源完整性檢查
資源加載錯誤
API監(jiān)控
全局錯誤
用戶交互
自定義上報
環(huán)境模塊:獲取環(huán)境數(shù)據(jù)
上報模塊先查看本地緩存數(shù)據(jù),將本地數(shù)據(jù)和新產(chǎn)生的數(shù)據(jù)一起上報,若上報失敗則存入LocalStorage。
詳細(xì)設(shè)計
SDK里采用單例模式,包括各監(jiān)控模塊、環(huán)境模塊和上報模塊。
每個具體監(jiān)控模塊獲取上報模塊實例進(jìn)行上報,上報模塊內(nèi)部保證同時只會有一個上報請求。
事件的監(jiān)聽都在捕獲階段進(jìn)行,防止因為事件冒泡被阻止而遺漏信息。
環(huán)境模塊
環(huán)境模塊收集以下環(huán)境信息:項目配置信息、Web環(huán)境數(shù)據(jù)、JsBridge環(huán)境數(shù)據(jù)。
其它的一些諸如UA、ISP等Web層可以獲取的信息由Web層獲取。
該模塊暴露init和getEnv方法。
上報模塊
采取單請求上報的方式,每個用戶同時只會有一條上報請求,每次將當(dāng)前記錄到的監(jiān)控信息列表一起上報,成功后再繼續(xù)上報。
上報結(jié)束之前的新上報記錄都存在Localstorage,收到成功消息后刪除已上報數(shù)據(jù),繼續(xù)上報,不成功的記錄保留在Localstorage。此處需注意對Localstorage存儲的上限做好控制。
在當(dāng)前沒有數(shù)據(jù)正在上報的情況下觸發(fā)上報,嘗試將當(dāng)前Localstorage的數(shù)據(jù)和新數(shù)據(jù)全部上報,若上報記錄過多,則分條發(fā)送。全部發(fā)送完或上報失敗,本次上報結(jié)束。
各具體監(jiān)控模塊
DNS劫持
HTTPS頁面被劫持后頁面資源無法獲取,劫持者無利可圖的情況下會降低劫持的動力。
若仍被劫持,前端資源未到達(dá)本地,也無法完成上報,只能從網(wǎng)絡(luò)層去監(jiān)控。
由于美團(tuán)點評平臺已經(jīng)全量切了HTTPS,因此該模塊不在本監(jiān)控系統(tǒng)中。
不過之前本團(tuán)隊做過對HTTP域下的劫持檢測,其檢測思路為請求Node層指定域名下的樣本HTML或JavaScript資源,對比返回結(jié)果是否符合預(yù)期。
資源完整性檢查
資源完整性檢查模塊的任務(wù)是記錄頁面加載了哪些資源,并進(jìn)行上報。
當(dāng)我們排查問題時,可以查看當(dāng)前頁面已經(jīng)加載成功了哪些資源及其加載順序,排除因為某些資源沒有加載或者加載順序不當(dāng)而引起錯誤的情況。
資源加載完整性檢查的上報時機(jī)分四類,每次將開始監(jiān)聽到觸發(fā)上報之間所有記錄到的已加載資源一起上報,減少上報請求數(shù):
內(nèi)存中維護(hù)一個已加載資源的數(shù)組,每次上報后刪除已上報的資源記錄。
資源加載錯誤監(jiān)控
Window上error事件代理,過濾Window本身的error。
根據(jù)標(biāo)簽類型判斷資源類型,src或href為資源地址。
為了捕獲跨域JavaScript的錯誤,需要在相應(yīng)資源標(biāo)簽上添加crossorigin屬性。
API錯誤監(jiān)控
同樣采用XMLHttpRequest加hook方式實現(xiàn)。
open時記錄接口URL,send后根據(jù)status判斷,接口調(diào)用失敗時進(jìn)行上報。
- XMLHttpRequest.prototype.open = function open(method, url, bool) {
- monitor.originXHR.open.apply(this, [method, url, bool]);
- // get something...
- // this.ajaxUrl = url;
- }
- XMLHttpRequest.prototype.send = function send(_data) {
- const self = this;
- this.addEventListener('readystatechange', () => {
- if (self.readyState === 4) {
- if (self.status !== 200 && self.status !== 304 && this.ajaxUrl !== REPORT_URL) { // filter urls
- // report error info
- // ...
- // monitor.reporter.report(dataTypes.API_ERROR, error);
- }
- }
- }, false);
- monitor.originXHR.send.apply(this, [_data]);
- };
過濾掉SDK本身的上報地址(防止上報失敗引起循環(huán)上報)和一些其它需要忽略的接口地址。
注意,接口訪問URL時可能是一個相對路徑,建議補全協(xié)議和domain。
全局錯誤監(jiān)控
監(jiān)聽Window上的error事件,過濾事件代理的error。
用戶交互監(jiān)控
監(jiān)聽Window上捕獲階段的click事件,記錄點擊相關(guān)數(shù)據(jù)。
業(yè)務(wù)代碼中可以為比較關(guān)注的元素添加data屬性,每次點擊將會上報被點擊元素的指定屬性、附加信息和DOMPath幫助定位該元素。
記錄用戶交互信息可以明確問題發(fā)生時,該場景下用戶的具體操作路徑,結(jié)合環(huán)境數(shù)據(jù)、資源加載記錄和錯誤數(shù)據(jù),整個問題場景就一目了然了。
接入方式
SDK的接入方式分為以下兩種:
1.先加載SDK
優(yōu)點:可以記錄頁面加載完成前的情況,加載的資源,以及發(fā)生的錯誤。
缺點:影響頁面加載速度,直接拷貝在head中,對業(yè)務(wù)接入不友好。
2.后加載SDK
優(yōu)點:不影響頁面性能。
缺點:只能監(jiān)控加載成功的頁面,但我們需要關(guān)心頁面加載失敗的場景。
為了滿足功能需要,當(dāng)前監(jiān)控平臺v1的引入方式是將壓縮后的SDK代碼直接引入到被監(jiān)控頁面的head中,并由業(yè)務(wù)代碼初始化配置項目名稱等。該步操作可以借助webpack的插件來幫助完成,減輕業(yè)務(wù)組接入的復(fù)雜度。
后續(xù)改進(jìn)方向考慮采用:核心基礎(chǔ)庫+loaders/plugins 的方式,將必須先加載的SDK代碼引入在head中,其余代碼等頁面加載完成后再異步添加。
結(jié)語
HUNT系統(tǒng)上線后,已經(jīng)完全覆蓋點餐終端組的活躍Web項目,進(jìn)行監(jiān)控數(shù)據(jù)的多維度上報。接下來工作重點是對收集到的數(shù)據(jù)進(jìn)行有效的分析和利用。
目前大部分現(xiàn)有的監(jiān)控工具只關(guān)注捕捉型監(jiān)控這部分,記錄型監(jiān)控是缺失的。相應(yīng)的,以記錄型監(jiān)控作為支撐的場景還原功能也是無法做到的。這類型的監(jiān)控系統(tǒng)只能做到發(fā)現(xiàn)錯誤,但是對于錯誤定位幫助甚微。
接入本監(jiān)控系統(tǒng)后,不但能在監(jiān)控面板上實時的看到多種錯誤信息,還能根據(jù)錯誤發(fā)生的上下文,包括頁面加載的過程,其中用戶做了哪些操作,訪問了哪些API等,按時間順序排列來完成場景還原。再結(jié)合該錯誤發(fā)生的環(huán)境數(shù)據(jù),復(fù)現(xiàn)問題和定位問題變的非常容易。
當(dāng)收到故障反饋后,對一些偶發(fā)的問題,或者用戶操作復(fù)雜的問題等,可以直接通過監(jiān)控面板了解情況,省去了大量的溝通成本,我們的故障反饋速度和能力也有極大的提高。
以上就是我們終端團(tuán)隊監(jiān)控平臺前端SDK部分的實踐分享,歡迎大家批評指正,有好的建議也希望能提出來幫助我們改進(jìn)。我們后續(xù)將不斷優(yōu)化,也將繼續(xù)與大家保持討論。耐心看到這里的讀者,表示十二萬分的感謝!

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流