你是否常常碰到業務反饋,線上的小程序某個頁面打不開了,訂單無法結算了,可是你當時測試的時候都是好好的。前端
因爲線上環境複雜,一些問題只會在特定網絡環境或者設備上發生,對於這類問題,異常信息的收集就顯得格外重要了,咱們不但但願收集錯誤的堆棧信息,還須要用戶操做流程,設備信息等,以便復現錯誤。git
小程序App()生命週期裏提供了onError函數,能夠經過在onError裏收集異常信息github
App({
// 監聽錯誤
onError: function (err) {
// 上報錯誤
wx.request({
url: "https://url", // 自行定義報告服務器
method: "POST",
errMsg: err
})
}
})
複製代碼
一些較隱蔽的錯誤若是隻有錯誤棧信息,排查起來會比較難,若是有用戶操做的路徑,在排查時就方便多了。json
方法一:暴力打點方法收集小程序
優勢:簡單直接bash
缺點:污染業務代碼,形成較多垃圾代碼服務器
方法二:函數劫持(推薦使用)網絡
須要在App函數中的onLaunch、onShow、onHide生命週期插入監控代碼,咱們經過重寫App生命週期函數來實現。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); // 把執行對象加入到麪包屑中
})
}
複製代碼
可是這樣寫,會把用戶自定義的內容給覆蓋掉,因此咱們還須要把用戶定義的函數和監控代碼合併。ide
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 // 工具類
複製代碼
https://github.com/zhengguorong/xbossdebug-wechat