WPS前端监控模块说明文档

@WarpPrism 2018-08-08 10:08:30发表于 WarpPrism/Blog 工程化性能优化

简介

该前端监控模块适用于WPS客户端内的前端项目,且需保证能正常进行双向信号桥通信,模块依赖的接口是:

  • getAppInfo 获取客户端信息
  • getTimeStamp 获取客户端开始加载webview的时间戳,用于性能评估
  • httpGet

使用该模块前,须确保客户端已有上述API。
所有统计数据会发往kibana日志平台,数据标识为 ````type: front``` ,在此平台上可实现数据可视化。

模块结构和配置

监控模块的结构图如下所示:
module contents

整个包是可以以npm模式发布的,其中src/index.js文件是模块入口,其他文件分别是:

  • .babelrc rollup单独打包时的babel配置文件
  • exception.js 异常监控模块,重载window.onerror和console.error方法
  • performance.js 性能监控模块,重载window.onload方法
  • config.js 配置文件
  • utils/bridge.js 前端->客户端信号桥,包含jsAsynCall方法
  • utils/api.js WPS客户端API的抽离,只包含几个方法,需要在其中引入bridge.js的jsAsynCall方法
  • utils/base64.js 用于把统计数据进行base64编码

其中,异常监控器和性能监控器是分开运行的,互不影响,Monitor下面的EMInstance和PMInstance分别对应异常监控和性能监控。

// 
let Monitor =  {
	EMInstance: null,
	PMInstance: null,
	initExceptionMonitor (props = {}) {
		this.EMInstance = null
		this.EMInstance = new ExceptionMonitor(props)
	},
	initPerformanceMonitor (props = {}) {
		this.PMInstance = null
		this.PMInstance = new PerformanceMonitor(props)
	},
	// 运行异常监控器,需要在其他脚本执行前运行
	runExceptionMonitor () {
		this.EMInstance.run()
	},
	// 运行性能监控器,需要在window.onload 或 App.mounted时执行
	runPerformanceMonitor () {
		this.PMInstance.run()
	},
	
	stopExceptionMonitor () {},
	stopPerformanceMonitor() {}
}

模块的统计数据格式

模块向服务器发送数据,地址统一为config.serverUrl,发送的数据是名为sendData的json数据

// 异常监控
this.sendData = {
	type: 'front', // 前端数据标识,front
	errMsg: '', // 报错信息
	fileUrl: '', // 报错文件地址
	pageUrl: '', // 报错页面地址
	lineNo: -1, // 错误行数
	columnNo: -1, // 错误列数
	errStack: '', // 错误栈信息
	platform: '', // 运行平台,windows或其他
	runtime: '', // 浏览器环境,cef或qt内核
	clientName: '', // 客户端类型,wps/wpp/es
	clientVersion: '', // 客户端版本号
	timeStamp: +new Date() // 报错时间戳
}
// 性能监控
this.sendData = {
	type: 'front', // 前端数据标识
	pageUrl: '', // 页面地址
	platform: '', // 运行平台,windows或其他
	runtime: '', // 运行环境,cef或qt
	clientName: '', // 客户端类型,wps/wpp/es
	clientVersion: '' // 客户端版本号
}
// 【重要】webview load时间
let createWebviewStamp = await getCreateWebviewTimeStamp()
this.computedTiming.webviewLoad = loadedStamp - createWebviewStamp

// 如果浏览器支持performance.timing api,则增加:this.sendData.performanceTiming

//【重要】DNS 查询时间
this.performanceTiming.domainLookup = t.domainLookupEnd - t.domainLookupStart
//【一般】TCP 建立连接完成握手的时间
this.performanceTiming.tcpConnect = t.connectEnd - t.connectStart
//【重要】资源请求完成的时间
this.performanceTiming.assertRequest = t.responseEnd - t.responseStart
//【重要】解析 DOM 树结构的时间
this.performanceTiming.domResolve = t.domComplete - t.domInteractive
//【重要】白屏时间 也称ttfb (time to first byte)
this.performanceTiming.whiteScreen = t.responseStart - t.navigationStart
this.performanceTiming.ttfb = this.performanceTiming.whiteScreen
//【重要】domready时间(用户可操作时间节点) 
this.performanceTiming.domReady = t.domContentLoadedEventEnd - t.navigationStart
//【重要】总下载时间
this.performanceTiming.pageLoad = t.loadEventEnd - t.navigationStart

模块的使用方法

如果项目支持Babel ES6+语法转译,则可以直接用import导入模块,然后进行webpack打包。
否则,需进入github/base-components项目,执行npm run build:packages,用rollup打包成基于ES5且兼容AMD、commonjs的模块,然后使用。
module contents

如上图所示,src下为模块源码,lib下面的index.js是打包后的js文件。

下面是在Vue项目中的使用示例,在Vue项目入口main.js上方添加:

import Monitor from './monitor'
// 生产模式才监控,开发模式默认不监控
if (process.env.NODE_ENV === 'production') {
	// 运行监控,在window上重定义onerror,console.error和onload方法
	Monitor.runExceptionMonitor()
	
	let f_load= window.onload
	window.onload = function() {
		if (f_load) {
			f_load.apply(this, arguments)
		}
		Monitor.runPerformanceMonitor()
	}
	// 适配vue框架的错误监听函数
	Vue.config.errorHandler = Monitor.EMInstance.vueErrorHandler
}

关于日志平台Kibana

在左侧discover栏可以看到我们上报的数据,注意在右上角选择合适的统计时间段,下面是一份数据示例:

module contents

数据是json格式的,其中````_source``` 字段是我们主动发送的,其余字段是服务端或平台自动添加的。