公司目前在線上運行着一款小程序,為了能監控小程序的運行情況,自行開發了一個參數搜集的SDK,名稱為 shin.js,放置在 utils 目錄中。
目前只搜集了打印、通信和錯誤,其中打印不是 console.log() 而是 shin.log()。
在小程序的管理后台,開發管理中,目前也有一個錯誤日志列表,其中也有比較詳盡的錯誤信息,可配合監控系統使用。
一、SDK
1)log
在 Shin 類的構造函數中,聲明了 log() 方法,主要就是將傳入的數據解析成JSON格式的字符串,然后傳遞給后台。
options 是可配置的參數,包括參數的發送地址,以及項目 token。injectApp() 方法修改了原生的 App 方法並且注入了監控邏輯,具體會在后面講解。
class Shin { constructor(options) { this.options = options; this.injectApp(); // 將打印的日志推送到監控后台 ['log'].forEach((type) => { this[type] = msg => { this.send({ category: 'console', data: { type, desc: JSON.stringify(msg) } }) }; }); } }
為了與之前的數據結構兼容,需要整理成指定的格式后,再發送。
2)發送
send() 方法用於發送,其中 identity 是一個身份標識,存在於全局對象 globalData 中,而它是通過 getIdentity() 方法生成的。
getIdentity() { return Number(Math.random().toString().substr(3, 3) + Date.now()).toString(36); } send(params) { //日志通用數據配置 params.identity = getApp().globalData.identity; params.token = this.options.token; params.data = Object.assign(params.data, { network: this.network, url: this.getActivePage().route }); //錯誤日志還需要記錄設備信息 if(params.category == 'error') { params.data.system = this.system; } wx.request({ url: this.options.src, method: "GET", data: { m: JSON.stringify(params) } }); }
代碼中的 getActivePage() 用於讀取當前頁面,調用了getCurrentPages();getNetworkType()讀取當前網絡類型;getSystemInfo()讀取當前設備信息。
getActivePage() { // 獲取當前頁面棧 const curPages = getCurrentPages(); if (curPages.length) { return curPages[curPages.length - 1]; } return {}; } getNetworkType() { wx.getNetworkType({ success: (res) => { this.network = res.networkType; }, }); } getSystemInfo() { wx.getSystemInfo({ success: (res) => { this.system = res; }, }); }
3)錯誤
在構造函數中調用了 injectApp() 方法,為 App 注入自定義的監控行為。
在觸發onLaunch事件時記錄網絡類型和設備信息,在觸發 onError 事件時將具體的錯誤信息發送到后台。
injectApp() { const originApp = App; const self = this; App = function (app) { ['onLaunch', 'onError'].forEach((methodName) => { const customMethod = app[methodName]; //暫存自定義的方法 if (methodName === 'onLaunch') { self.getNetworkType(); //記錄網絡 self.getSystemInfo(); //記錄設備信息 } app[methodName] = function (options) { if(methodName === 'onError') { const params = { category: 'error', data: { type: 'mini', desc: options, //錯誤信息 } }; self.send(params); //錯誤上報 } return customMethod && customMethod.call(this, options); }; }); return originApp(app); }; }
4)通信
我們自己封裝了一個通信庫,為了操作簡便,就定義了一個方法,在通信完成時調用此方法。
formatRequest({ res, url, method, data }) { // 響應 const ajax = { type: method, status: res.statusCode, url, data } // 過濾掉數據量大的響應 if(JSON.stringify(res.data).length <= 300) { ajax.response = res.data; } const params = {}; if(res.statusCode >= 400) { params.category = 'error'; params.data = { type: 'promise', desc: ajax }; }else { params.category = 'ajax' params.data = ajax; } this.send(params); }
它接收的參數包括 res(響應數據),url(請求地址),method(請求方法),data(請求參數)。
其中 res 包括狀態碼和響應內容,狀態碼囊括了4XX和5XX。
5)初始化
在啟動文件 app.js 引入 shin.js文件,並初始化,在 globalData 中添加 shin 和 identity。
import Shin from './utils/shin'; const shin = new Shin({ src: 'https://127.0.0.1:3000/ma.gif', token: 'mini' }); globalData: { shin, identity: shin.getIdentity(), }
6)監控后台
參數搜集的 api 不需要做任何修改,在監控后台的頁面中也只是加幾個過濾選項即可,而這些選項都已經寫成了常量,修改起來很方便,例如:
export const MONITOR_PROJECT = [ { key: 'backend', value: '管理后台' }, { key: 'h5', value: 'H5活動' }, { key: 'mini', value: '小程序'} ];
二、Source Map
目前還不能在監控后台直接通過 SourceMap 自動映射(未來的一個優化點)。
需要先從小程序后台下載 SourceMap 文件,下載完后導入小程序開發編輯器中查看映射條件。
具體過程:
1)首先小程序開發器的版本必須得是 1.03.2012152 以上。
2)選擇"設置-通用設置-擴展-調試器插件",進入插件下載頁面,添加sourcemap匹配調試插件。
3)在開發管理中的錯誤日志(參考教程)中,可下載線上版本的 SourceMap 文件或者,或者在上傳完代碼后,會提示你下載該文件。
4)最后可在控制台調試器中出現 sourcemap 標簽,在此處加載映射文件以及輸入行號和列號,完成映射。
參考: