Appearance
SDK 介绍
技术选型
- TypeScript
- Webpack
- Babel
- vitest
业务分析
使用原生 js 监控项目的运行情况,包括捕获 各种可能发生的错误、用户行为、网页性能和网站信息等等,并将捕获到的数据提取成一个对象,然后将该对象上报到后端时序数据库。
需要监控的地方:
- 异常数据
- 前端异常
- JS 异常
- Promise 异常
- resource 异常
- console.error 异常
- 跨域异常
- 接口异常
- 超时/未响应异常
- 4xx 请求异常
- 5xx 请求异常
- ...
- 白屏异常
- 前端异常
- 行为数据 - 用户操作路径 - 路由跳转
- 性能数据
- 白屏时间、首屏渲染时间等页面关键信息
- 其他
- PV、UV
项目代码介绍
目录
大纲:
说明:
Project
|—— example # 存放用于测试当前开发 sdk 的项目
|—— lib # 存放 rollup 打包后的文件
|—— src # 主要代码目录
| |—— test # vitest 单元测试
| |—— type # 存放 TypeScript 类型
| |—— util # 工具类,用于存放各种处理函数
关于各种监听函数的实现思路
异常处理
- xhr 异常 实现思路
通过重写 window 上的 XMRHttpRequest 方法,并使用 addEventListener 监听器对各种情况进行判断
timeout => 超时
loadend => 加载结束阶段
- Fetch 异常 实现思路
方法和
xhr异常
同理,也是通过重写 window 上的 fetch 方法,区别在于由于 fetch 的特殊性(只有网络错误或者无法连接时,Fetch 才会报错,其他情况下都不会报错,而是认为 请求成功),因此,我们只能通过
1.Response.status
属性,得到HTTP
回应的真实状态码,才能判断请求是否成功
2.或者判断response.ok
是否为true
,true
=> 请求成功,否则 请求失败
- JS 异常 (资源加载异常,脚本异常) 实现思路
通过
window.addEventListener
事件监听钩子函数的error
事件去获取,我们可以在捕获异常事件的同时去处理这些异常信息,在这里,我们使用了getErrorKey
函数去获取事件的错误类型,包括了Resource 异常
、JS 异常
以及跨域 CORS 异常
,然后我们就可以根据错误类型去获取我们要的信息
- Promise 异常 实现思路
通过
window.addEventListener
事件监听钩子函数的unhandledrejection
去获取,首先判断该Promise
是否跨域, 如果存在跨域异常,就按照跨域的情况来处理信息,否则就是Promsie Error
- console.error 异常 实现思路
我们可以用一个变量consoleError
去等于window.console.error
,然后再通过重写window
上的console.error
方法,将各种错误信息处理完成,最后将consoleError
这个变量的this
绑定到console
上
- 白屏异常 实现思路
白屏异常有很多种的实现方法,可以通过全埋点,十字埋点等,这里我们使用的是 十字埋点,十字就是在当前屏幕的正十字方向,我们可以通过检索这个十字方向上的埋点元素来判断是否白屏。
注意:这里我们需要考虑一个点:判断白屏的时机很显然需要加载完页面之后。
PV 统计
history
路由监听 实现思路
因为 history路由依赖全局对象
history
实现的,所以我们的实现思路就可以依赖pushState
和replaceState
来实现,但是这两个方法不能被popstate
监听到,所以我们需要重写这两个方法来实现数据的采集。
- hash 路由监听 实现思路
因为当
hash 改变会触发 hashchange
,所以我们只需要在全局加上一个 监听函数,在监听函数中实现采集并上报就行了,但是 在React
以及Vue
中,对于hash
路由的跳转并不是通过hashchange
的监听实现的,而是用的pushState
,所以我们还要加个对pushState
的监听。
- 数据上报 实现思路
使用
Navigator.sendBeacon()
发送请求,后端调用co-body
第三方库解析数据;如果浏览器不支持sendBeacon
,则通过new Image()
设置src
属性发送请求。