《从零开始搭建前端监控平台》 | |||
---|---|---|---|
作者 | 陈辰 (贝壳) | 出版社 | 人民邮电出版社 |
ISBN | 9787115532626 | 出版时间 | 2020-04 |
豆瓣网址 | 豆瓣图书 | 是否有电子版 | 异步社区 |
阅读日期 | 2020-05-30 | 更新日期 | 2020-05-30 |
相关链接 | https://github.com/LianjiaTech/fee | 备注 |
按
从GMTC了解到贝壳的本书作者,后续知道出书了,电子书买了正版,公司图书角申购了实体书,权当支持了。
书中开源项目 Fee
网址是 https://github.com/LianjiaTech/fee
书籍细节
很多细节已经提前了解了,比如使用 performance
api来监控页面性能,使用 onerror
addEventListener
unhandledrejection
等方式完成错误监控,可以使用开源的监控平台、也可以使用阿里云的日志服务来完成数据的管理。
这次着重看看贝壳开源监控平台的技术细节。
1 前端监控平台解决的问题
- 稳定性,错误监控
- 性能监控
书中提到的 fee
项目 https://github.com/LianjiaTech/fee
收集到了数据可以怎么用?
- 分析用户画像,合理区分浏览器兼容版本
- 了解用户实际场景是如何使用你的功能
- 针对性性能优化
- 还可以保证技术产出
2 我们就是产品经理
3 上报数据
上报数据的SDK架构可设计如下:
做一个SDK似乎很不错的样子。
错误类型数据
产生报错的原因很多:JS引擎报错、 Vue
React
框架报错、js解析报错等。
普通的 Error 对象
有三个属性 name
message
stack
栈
var error = new Error('这里报错了')
console.dir(error)
// Error 对象有三个属性 name message stack
贴一下 MDN里 error 部分:
属性 | 含义 | 举例 |
---|---|---|
SyntaxError | 语法错误 | 语法有错 |
TypeError | 类型错误 | 错误地字符串push,使用数组方法 |
RangeError | 范围错误 | 数值范围,比如 array.length-1 |
ReferenceError | 引用错误 | 不var,直接get变量 |
EvalError | eval错误 | 历史遗留问题,忽略。 |
URIError | URL错误 | 调用 decoude encode 等方法时候的错误 |
Failed to load resource | 资源加载错误 | 访问资源错误。 |
可以 <img onerror='handleError'>
,也可以 window.addEventListener('error')
这样。
加载跨域资源不报错,需要 后端允许跨域并且前端script标签添加 crossorigin
具体细节可以看我的仓库:https://github.com/Otto-J/web-error-demo
sdk的基础代码
首先是全局监听 error
,同时避免和script里的onerror重复。这里使用监听而不是等号重写,是为了避免用户自定义了error事件收不到错误信息。
// 监听资源加载错误(JavaScript Scource failed to load)
window.addEventListener('error', function (event) {
// 过滤target为window的异常,避免与上面的onerror重复
var errorTarget = event.target
var errorName = errorTarget.nodeName.toUpperCase()
if (errorTarget !== window && errorTarget.nodeName && LOAD_ERROR_TYPE
[errorName]) {
handleError(formatLoadError(errorTarget))
} else {
// onerror会被覆盖,因此转为使用Listener进行监控
let { message, filename, lineno, colno, error } = event
handleError(formatRuntimerError(message, filename, lineno,
colno, error))
}
}, true)
然后,处理未捕捉到的 Promise.reject
// 监听浏览器中捕获到未处理的Promise错误
window.addEventListener('unhandledrejection', function (event) {
handleError(event)
}, true)
针对 vue的console.error 报错准备重写,做个拦截。这里
// 针对vue报错重写console.error
// TODO
console.error = (function (origin) {
return function (info) {
var errorLog = {
type: ERROR_CONSOLE,
desc: info
}
handleError(errorLog)
origin.call(console, info)
}
})(console.error)
然后封装runtime错误日志,load错误日志
监控性能
使用 performance
对象获取常规性能指标。
网络性能监控,必要的时候把 performance.timing.toJSON()
和当前的 location.href
上报
这里具体的内容专门做一个总结。(to do)
啥时候触发,一般是 window.onload
可以把 …performance.timing 和 host+pathname 上传
环境相关数据
除了性能数据,还要了解用户是什么样的。
通常需要下面的内容
指标 | 描述 | 作用 | 技术实现 |
---|---|---|---|
pid | projectID 产品具体编号 | 方便区分不同产品 | 不同产品规划不同值 |
uid | userID 用户表示 | 识别用户,主要是去重和追踪 | 登录的找cookie,没登录模拟唯一值 |
sid | sessionID 本次登录操作 | 识别用户的本次登录 | cookie session中找 |
version | 产品版本号 | 分析产品迭代的问题 | 版本号 |
ua | userAgent 用户浏览器信息 | ||
开关类数据 | 产品的一些指标开关 | isDev是否是测试数据 |
手动上报数据
自动上报解决通用代码错误。如果遇到逻辑错误,代码写的逻辑不对,就可以使用手动上报,用户有困惑就可以上报
用户行为数据
如何判断平均在线时长,一般是用户点击和下次点击之间的时间做累加。
每5秒打点一次,15分钟不动视为离线
流程错误数据
比如密码错误、验证码错误等。
如何上报
一般还是使用 gif 图片请求。
图片请求比get好防跨域,和其他资源相比,js会阻塞页面
图片使用 new Image
发出,不会阻塞,图片也小 1 x 1 透明
,透明的小,经过对比,gif体积最小。
同样最小体积 bmp74字节,png67字节 gif43字节
var img = new Image()
img.src=xxx
4 总体设计
做了一个整体设计,大致分层,分层设计好,可以划分职责:
- 展示层,用于数据的展示,比如图标、列表等
- 服务层,数据的管理
- api系统层,负责api的实现
- api权限层,权限判断
- 公共组件层,服务基础插件,比如日志 数据库 定时任务等
- 支撑层,也就是数据层,数据的清洗,加工等
5 数据处理
服务器日志:
- 用户产生数据
- 日志搜集、消费、清洗
- 数据流转
访问日志可以通过 nginx 来实现。
- 每次都会产生 access.log 日志
原本的格式 + 图片带来的数据
消息系统:
如果数量较大,不好管理,单机也不好维护海量数据,这里引入了 kafka
,它是一个可以在多个应用质检可靠地传输实时数据的管道。
看起来是,前端a推送给 kafka数据,然后会同步地告诉 其他节点,这是典型的kafka集群:
- 若干消息的生产者
- 若干消息的消费者
- 一个 zookeeper集群
具体的细节先略过,第一次听说。
启动和配置略过,感觉可以通过docker来完成
后面跳过了前端不熟悉的各种配置,甚至还有设计sql表。
watchDog是监控报警的指令
其他的跳过
6 服务搭建
利用node起一个后端服务,这里选的是express
基本的配置experss,分离配置文件,链接数据库
写了一堆接口实现,迅速略过
7 页面展示
这里启动了一个vue项目。
哦,router里可以设置 meata.title 来设置title,回头可以优化项目
使用的第三方开源组件:
- antv/data-set 库
其他迅速略过
8 监控平台的使用
如果实时阅读消息,可以引入邮件,机器人等
监控平台的挑战
- 一开始数据量小,后来数据量大,抽样不合理,只能全量存。
- 数据量撑破数据库,一个表超过3000w数据,后来数据库自己维护,方便控制
- 告警配置读库缓慢,使用redis做二级缓存
- 搜索功能,从sql中抽离,后来上了 es集群,效果较好
- 错误的多样性,改成用户自己选择错误类型
简单读后感
快速翻阅了一遍,对比之前看到的利用阿里云日志服务来做数据支撑,这本书细节更多,可供参考。
但大量的代码,让人看着头疼。