一文徹底搞懂前端監控
作者 | 執鳶者 責編 | 歐陽姝黎
前端監控現狀
近年來,前端監控是越來越火,目前已經有很多成熟的產品供我們選擇使用,如下圖所示
有這麼多監控平臺,那爲什麼還要學習自研前端監控?
一方面人家是要錢的
另一方面自己的項目需要定製化的功能。
前端監控的目的
-
提升用戶體驗
-
更快的發現發現異常、定位異常、解決異常
-
瞭解業務數據,指導產品升級——數據驅動的思想
前端監控的流程
3.1 採集
前端監控的第一個步驟就是數據採集,採集的信息包含環境信息、性能信息、異常信息、業務信息。
3.1.1 環境信息
環境信息是每個監控系統必備的內容,畢竟排查問題的時候需要知道來自哪個頁面、瀏覽器是誰、操作用戶是誰……, 這樣才能快速定位問題,解決問題。一般這些常見的環境信息主要包含:
-
url:正在監控的頁面,該頁面可能會出現性能、異常問題。獲取方式爲:
window.location.href -
ua: 訪問該頁面時該用戶的 userAgent 信息,包含操作系統和瀏覽器的類型、版本等。獲取方式爲:
window.navigator.userAgent -
token:記錄當前用戶是誰。通過記錄該用戶是誰。
一方面方便將該用戶的所有監控信息建立聯繫,方便數據分析;
另一方面通過該標識可以查看該用戶的所有操作,方便復現問題。
3.1.2 性能信息
頁面的性能直接影響了用戶留存率,,Google DoubleClick 研究表明:如果一個移動端頁面加載時長超過 3 秒,用戶就會放棄而離開。BBC 發現網頁加載時長每增加 1 秒,用戶就會流失 10%。,Google DoubleClick 研究表明:如果一個移動端頁面加載時長超過 3 秒,用戶就會放棄而離開。BBC 發現網頁加載時長每增加 1 秒,用戶就會流失 10%。所以我們的追求就是提高頁面的性能,爲了提高性能需要監控哪些指標呢?
3.1.2.1 指標分類
指標有很多,我總結爲以下兩個方面:網絡層面和頁面展示層面。
網絡層面
從網絡層面來看涉及的指標有:重定向耗時、DNS 解析耗時、TCP 連接耗時、SSL 耗時、TTFB 網絡請求耗時、數據傳輸耗時、資源加載耗時……, 各個指標的解釋如下表所示:
頁面展示層面
頁面展示層面的指標是針對用戶體驗提出的幾個指標,包含 FP、FCP、LCP、FMP、DCL、L 等,這幾個指標其實就是 chrome 瀏覽器中 performance 模塊的指標(如圖所示)。
各個指標的解釋如下表所示。
3.1.2.2 指標求解
上述這麼多指標該怎麼獲取呢?瀏覽器給我們留了相應的接口——神奇的 window.performance,通過該接口可以獲取一些列與性能相關的參數,下面以 https://baidu.com 爲例來看一下與這些指標相關的參數:
window.performance 中的 timing 屬性中的內容不就是爲了求解上述指標所需要的值嗎?看着上面的屬性值再對應下面的 performance 訪問流程圖,整個過程是不是一目瞭然。
有了上面的值我們就一起求解上述的指標:
網絡層面
頁面展示層面
Google 工程師一直在推動以用戶爲中心的性能指標,所以頁面展示層面的變化較大,求解方式稍有不同:
- FP 和 FCP
通過 window.performance.getEntriesByType(‘paint’) 的方式獲取
-
LCP
-
FMP
-
DCL
domContentLoadEventEnd – fetchStart
- L
loadEventStart – fetchStart
- TTI
domInteractive – fetchStart
- FID
function getFID() {
new PerformanceObserver((entryList, observer) => {
let firstInput = entryList.getEntries()[0];
if (firstInput) {
const FID = firstInput.processingStart - firstInput.startTime;
console.log('FID', FID);
}
observer.disconnect();
}).observe({type: 'first-input', buffered: true});
}
3.1.3 異常信息
對於網站來說,異常信息是最致命、最影響用戶體驗的問題,需要重點監控。對於異常信息可以分爲兩類:運行時錯誤、接口錯誤。下面就分別來嘮一嘮這兩類錯誤。
運行時錯誤
當 JavaScript 運行時有可能會發生錯誤,可歸類爲七種:語法錯誤、類型錯誤、範圍錯誤、引用錯誤、eval 錯誤、URL 錯誤、資源加載錯誤。爲了捕獲代碼錯誤,需要考慮兩類場景:非 Promise 場景和 Promise 場景,因爲兩種場景捕獲錯誤的策略不同。
- 非 Promise 場景
非 Promise 場景可通過監聽 error 事件來捕獲錯誤。對於 error 事件捕獲的錯誤分爲兩類:資源錯誤和代碼錯誤。資源錯誤指的就是 js、css、img 等未加載,該錯誤只能在捕獲階段獲取到,且爲資源錯誤時 event.target.localName 存在值(用此區分資源錯誤與代碼錯誤);代碼錯誤指的就是語法錯誤、類型錯誤等這一類錯誤,可以獲取代碼錯誤的信息、堆棧等,用於排查錯誤。
2.Promise 場景
Promise 場景的處理方式有所不同,當 Promise 被 reject 且沒有 reject 處理器的時候,會觸發 unhandlerejection 事件,所以通過監聽 unhandlerejection 的事件來捕獲錯誤。
export function listenerPromiseError() {
window.addEventListener('unhandledrejection', (event) => {
console.log('這是Promise場景中錯誤', event);
})
}
接口錯誤
對於瀏覽器來說,所有的接口均是基於 XHR 和 Fetch 實現的,爲了捕獲接口中的錯誤,可以通過重寫該方法,然後通過接口返回的信息來判斷當前接口的狀況,下面以 XHR 爲例來展示封裝過程。
function newXHR() {
const XMLHttpRequest = window.XMLHttpRequest;
const oldXHROpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = (method, url, async) => {
// 做一些自己的數據上報操作
return oldXHROpen.apply(this, arguments);
}
const oldXHRSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = (body) => {
// 做一些自己的數據上報操作
return oldXHRSend.apply(this, arguments);
}
}
3.1.4 業務信息
每個產品都會有自己的業務信息,例如用戶在線時長、pv、uv、用戶分佈等,通過獲取這些業務信息才能更加清楚的瞭解目前產品的狀況,以便產品經理更好的去規劃產品的未來方向。由於每個產品業務信息多種多樣,小夥伴本可以按照自己的需求進行撰寫代碼,此處我就不再贅述。
3.2 上報
對於上報的方式無外乎兩種:一種是 Ajax 的方式上報;另一種是通過 Image 的形式進行上報。目前很多大廠採用的上報方式均是通過一個 1*1 像素的的 gif 圖片進行上報,既然人家都採用該種策略,那我們就來嘮一嘮下面兩個問題。
- 爲什麼採用 Image 的方式上報?
-
沒有跨域問題。因爲數據服務器和後端服務器大概率是不同的域名,若採用 Ajax 的方式進行處理還要處理跨域問題,否則數據會被瀏覽器攔截。
-
不會阻塞頁面加載,只需 new Image 對象即可。
- 圖片類型很多,爲什麼採用 gif 這種格式進行上報?
其實歸結爲一個字——小。對於 1*1px 的圖片,BMP 結構的文件需要 74 字節,PNG 結構的文件需要 67 字節,GIF 結構的文件只需要 43 字節。同樣的響應,GIF 可以比 BMP 節約 41% 的流量,比 PNG 節約 35% 的流量,所以選擇 gif 進行上報。
3.3 分析
日誌上報之後需要進行清洗,獲取自己所需要內容,並將分析內容進行存儲。根據數據量的大小可分爲兩種方式:單機和集羣。
1、單機
訪問量小、日誌少的網站可以採用單機的方式對數據進行分析,例如用 node 讀取日誌文件,然後通過日誌文件中獲取所需要的信息,最終將處理的信息存儲到數據庫中。
2、集羣
很多產品的訪問量很大,日誌很多,此時就需要利用 Hadoop 進行分佈式處理,獲取最終處理結果,其處理流程圖如下所示:
根據自己的日誌量級決定自己的分析方式,合適的就是最好的,不用一味追求最優的、最先進的處理方式。
3.4 報警
當異常類型超多一定閾值之後需要進行報警通知,讓對應的工作人員去處理問題,及時止損。根據報警的級別不同,可以選擇不同的報警方式。
-
郵件——普通報警
-
短信——嚴重報警,已影響部分業務
-
電話——特別嚴重,例如系統已宕機
參考
http://www.alloyteam.com/2020/01/14184/#prettyPhoto
https://www.colabug.com/2019/1224/6767570/amp/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/TRpJ0__cS0HcqkcPGEeyIA