前言
你是否經常碰到業務反饋,線上的小程式某個頁面打不開了,訂單沒法結算了,但是你當時測試的時候都是好好的。
由於線上環境複雜,一些問題只會在特定網路環境或者裝置上發生,對於這類問題,異常資訊的收集就顯得格外重要了,我們不但希望收集錯誤的堆疊資訊,還需要使用者操作流程,裝置資訊等,以便復現錯誤。
簡單收集
小程式App()生命週期裡提供了onError函式,可以通過在onError裡收集異常資訊
App({
// 監聽錯誤
onError: function (err) {
// 上報錯誤
wx.request({
url: "https://url", // 自行定義報告伺服器
method: "POST",
errMsg: err
})
}
})
複製程式碼
使用者操作路徑收集
一些較隱蔽的錯誤如果只有錯誤棧資訊,排查起來會比較難,如果有使用者操作的路徑,在排查時就方便多了。
方法一:暴力打點方法收集
優點:簡單直接
缺點:汙染業務程式碼,造成較多垃圾程式碼
方法二:函式劫持(推薦使用)
需要在App函式中的onLaunch、onShow、onHide生命週期插入監控程式碼,我們通過重寫App生命週期函式來實現。
App = function(app) {
["onLaunch", "onShow", "onHide"].forEach(methodName => {
app[methodName] = function(options) {
// 構造訪問日誌物件
var breadcrumb = {
type: "function",
time: utils.now(),
belong: "App", // 來源
method: methodName,
path: options && options.path, // 頁面路徑
query: options && options.query, // 頁面引數
scene: options && options.scene // 場景編號
};
self.pushToBreadcrumb(breadcrumb); // 把執行物件加入到麵包屑中
})
}
複製程式碼
但是這樣寫,會把使用者自定義的內容給覆蓋掉,所以我們還需要把使用者定義的函式和監控程式碼合併。
var originApp = App // 儲存原物件
App = function(app) {
// .... 此處省略監控程式碼
// .... 此處省略監控程式碼
originApp(app) // 執行使用者定義的方法
}
複製程式碼
記錄結果
可以從下面的json看出,使用者到了detail頁面,執行了onLoad => getDetail => onReady => buy 當執行buy方法的時候報錯。
[{"method":"onLoad","route":"pages/film/detail","options":{"id":"4206"}},
{"method":"getDetail","route":"pages/film/detail","options":{"id":"4206"}},
{"method":"onReady","route":"pages/film/detail","options":{"id":"4206"}},
{"method":"buy","route":"pages/film/detail","options":{"id":"4206"}}]
複製程式碼
上報策略
考慮到在大型應用中,日誌量比較大,我們採取抽樣,合併,過濾三個方法減少日誌的輸出,程式碼實現可以參考lib/report.js
程式碼組織
專案使用rollup作為構建工作,實現ES6轉ES5,模組載入功能。
專案目錄如下:
config.js // 配置檔案
core.js // 劫持小程式核心程式碼
events.js // 監聽自定義事件
report.js // 上報類
utils.js // 工具類
複製程式碼
?喜歡的點個star:
https://github.com/zhengguorong/xbossdebug-wechat