異常上報如何選擇通訊方式 動態(tài)創(chuàng)建img標(biāo)簽: 其實上報就是要將捕獲的異常信息發(fā)送到后端。最常用的方式首推動態(tài)創(chuàng)建標(biāo)簽方式。 因為這種方式無需加載任何通訊庫,而且頁面是無需刷新的。 基本上目前包括百度統(tǒng)計 Google統(tǒng)計都是基于這個原理做的埋點。 new Image().src ='http://localhost:7001/monitor/error'+ '?info =xxxxxx' 通過動態(tài)創(chuàng)建一個img,瀏覽器就會向服務(wù)器發(fā)送get請求。 可以把你需要上報的錯誤數(shù)據(jù)放在querystring字符串中,利用這種方式就可以將錯誤上報到服務(wù)器了。 Ajax上報: 實際上我們也可以用ajax的方式上報錯誤,這和我們再業(yè)務(wù)程序中并沒有什么區(qū)別。 上報哪些數(shù)據(jù): 上報哪些數(shù)據(jù): 我們先看一下error事件參數(shù): 其中核心的應(yīng)該是錯誤棧,其實我們定位錯誤最主要的就是錯誤棧。 錯誤堆棧中包含了絕大多數(shù)調(diào)試有關(guān)的信息。其中包括了異常位置(行號,列號),異常信息 上報數(shù)據(jù)序列化: 由于通訊的時候只能以字符串方式傳輸,我們需要將對象進行序列化處理。 大概分成以下三步: 1、將異常數(shù)據(jù)從屬性中解構(gòu)出來,存入一個JSON對象 2、將JSON對象轉(zhuǎn)換為字符串 3、將字符串轉(zhuǎn)換為Base64 當(dāng)然在后端也要做對應(yīng)的反向操作 這個我們后面再說。 異常上報的后端服務(wù)器 搭建eggis工程: 異常上報的數(shù)據(jù)一定是要有一個后端服務(wù)接收才可以。 我們就以比較流行的開源框架eggjs為例來演示 # 全局安裝egg-cli npm i egg-init -g # 創(chuàng)建后端項目 egg-init backend --type=simple cd backend npm i # 啟動項目 npm run dev 編寫error上傳接口: 首先在app/router.js添加一個新的路由 創(chuàng)建一個新的: controller (app/controller/monitor) 看一下接收后的結(jié)果? 記入日志文件: 下一步就是講錯誤記入日志。實現(xiàn)的方法可以自己用fs寫,也可以借助log4js這樣成熟的日志庫。 當(dāng)然在eggjs中是支持我們定制日志那么我么你就用這個功能定制一個前端錯誤日志好了。 在/config/config.default.js中增加一個定制日志配置 在/app/controller/monitor.js中添加日志記錄: ![]() 最后實現(xiàn)的效果: ![]() ![]() Webpack插件實現(xiàn)SourceMap上傳 談到異常分析最重要的工作其實是將webpack混淆壓縮的代碼還原。 創(chuàng)建Webpack插件: /source-map/plugin(文件位置) ![]() 加載webpack插件: webpack.config.js(文件位置) ![]() 添加讀取sourcemap讀取邏輯: 在apply函數(shù)中增加讀取sourcemap文件的邏輯 /plugin/uploadSourceMapWebPlugin.js ![]() 實現(xiàn)http上傳功能: ![]() 服務(wù)器端添加上傳接口: /backend/app/router.js(文件位置) ![]() 添加sourcemap上傳接口: /backend/app/controller/monitor.js ![]() 最終效果: 執(zhí)行webpack打包時調(diào)用插件sourcemap被上傳至服務(wù)器。 ![]() ![]() 解析ErrorStack 考慮到這個功能需要較多邏輯,我們準(zhǔn)備把他開發(fā)成一個獨立的函數(shù)并且用Jest來做單元測試: 先看一下我們的需求? ![]() 搭建Jest框架: ![]() 首先創(chuàng)建一個/utils/stackparser.js文件? ![]() 在同級目錄下創(chuàng)建測試文件stackparser.spec.js 以上需求我們用Jest表示就是 ![]() 整理如下: 下面我們運行Jest npx jest stackparser --watch ![]() 顯示運行失敗,原因很簡單因為我們還沒有實現(xiàn)對吧。 ![]() 下面我們就實現(xiàn)一下這個方法 反序列Error對象: 首先創(chuàng)建一個新的Error對象 將錯誤棧設(shè)置到Error中。 然后利用error-stack-parser這個npm庫來轉(zhuǎn)化為stackFrame ![]() 運行效果如下? ![]() 解析ErrorStack: 下一步我們將錯誤棧中的代碼位置轉(zhuǎn)換為源碼位置 ![]() 我們再用Jest測試一下? ![]() 這時我們再看一下結(jié)果: ![]() 這樣一來測試就通過啦~ 將源碼位置記入日志: ![]() 記錄完成后,我們再來看一下運行效果: ![]() 結(jié)束了這一步,我們的ErrorStack工作就完成了。 ![]() 需要運用的兩種開源框架 Fundebug: Fundebug專注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java線上應(yīng)用實時BUG監(jiān)控。 自從2016年雙十一正式上線,F(xiàn)undebug累計處理了10億+錯誤事件,付費客戶有陽光保險、荔枝FM、掌門1對1、核桃編程、微脈等眾多品牌企業(yè)。 Sentry: Sentry 是一個開源的實時錯誤追蹤系統(tǒng),可以幫助開發(fā)者實時監(jiān)控并修復(fù)異常問題。 它主要專注于持續(xù)集成、提高效率并且提升用戶體驗。 Sentry 分為服務(wù)端和客戶端 SDK,前者可以直接使用它家提供的在線服務(wù),也可以本地自行搭建; 后者提供了對多種主流語言和框架的支持,包括 React、Angular、Node、Django、RoR、PHP、Laravel、Android、.NET、JAVA 等。 同時它可提供了和其他流行服務(wù)集成的方案,例如 GitHub、GitLab、bitbuck、heroku、slack、Trello 等。 目前公司的項目也都在逐步應(yīng)用上 Sentry 進行錯誤日志管理。 總結(jié): 截止到目前為止,我們把前端異常監(jiān)控的基本功能算是形成了一個MVP(最小化可行產(chǎn)品)。 后面需要升級的還有很多,對錯誤日志的分析和可視化方面可以使用ELK。 發(fā)布和部署可以采用Docker。對eggjs的上傳和上報最好要增加權(quán)限控制功能。 關(guān)于這一期的VUE異常處理課程我們就講到這里啦。 |
|