《从零开始搭建前端监控平台》
作者 陈辰 (贝壳) 出版社 人民邮电出版社
ISBN 9787115532626 出版时间 2020-04
豆瓣网址 豆瓣图书 是否有电子版 异步社区
阅读日期 2020-05-30 更新日期 2020-05-30
相关链接 https://github.com/LianjiaTech/fee 备注

从GMTC了解到贝壳的本书作者,后续知道出书了,电子书买了正版,公司图书角申购了实体书,权当支持了。

image.png

书籍《从零开始搭建前端监控平台》 - 图2书中开源项目 Fee 网址是 https://github.com/LianjiaTech/fee

书籍细节

很多细节已经提前了解了,比如使用 performance api来监控页面性能,使用 onerror addEventListener unhandledrejection 等方式完成错误监控,可以使用开源的监控平台、也可以使用阿里云的日志服务来完成数据的管理。

这次着重看看贝壳开源监控平台的技术细节。

1 前端监控平台解决的问题

  • 稳定性,错误监控
  • 性能监控

书中提到的 fee 项目 https://github.com/LianjiaTech/fee

收集到了数据可以怎么用?

  • 分析用户画像,合理区分浏览器兼容版本
  • 了解用户实际场景是如何使用你的功能
  • 针对性性能优化
  • 还可以保证技术产出

从数据展开,还是值得思考的。

2 我们就是产品经理

3 上报数据

上报数据的SDK架构可设计如下:

书籍《从零开始搭建前端监控平台》 - 图3

做一个SDK似乎很不错的样子。

错误类型数据

产生报错的原因很多:JS引擎报错、 Vue React 框架报错、js解析报错等。

普通的 Error 对象 有三个属性 name message stack

  1. var error = new Error('这里报错了')
  2. console.dir(error)
  3. // 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事件收不到错误信息。

  1. // 监听资源加载错误(JavaScript Scource failed to load)
  2. window.addEventListener('error', function (event) {
  3. // 过滤target为window的异常,避免与上面的onerror重复
  4. var errorTarget = event.target
  5. var errorName = errorTarget.nodeName.toUpperCase()
  6. if (errorTarget !== window && errorTarget.nodeName && LOAD_ERROR_TYPE
  7. [errorName]) {
  8. handleError(formatLoadError(errorTarget))
  9. } else {
  10. // onerror会被覆盖,因此转为使用Listener进行监控
  11. let { message, filename, lineno, colno, error } = event
  12. handleError(formatRuntimerError(message, filename, lineno,
  13. colno, error))
  14. }
  15. }, true)

然后,处理未捕捉到的 Promise.reject

  1. // 监听浏览器中捕获到未处理的Promise错误
  2. window.addEventListener('unhandledrejection', function (event) {
  3. handleError(event)
  4. }, true)

针对 vue的console.error 报错准备重写,做个拦截。这里

  1. // 针对vue报错重写console.error
  2. // TODO
  3. console.error = (function (origin) {
  4. return function (info) {
  5. var errorLog = {
  6. type: ERROR_CONSOLE,
  7. desc: info
  8. }
  9. handleError(errorLog)
  10. origin.call(console, info)
  11. }
  12. })(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字节

  1. var img = new Image()
  2. img.src=xxx

4 总体设计

做了一个整体设计,大致分层,分层设计好,可以划分职责:

  • 展示层,用于数据的展示,比如图标、列表等
  • 服务层,数据的管理
    • api系统层,负责api的实现
    • api权限层,权限判断
    • 公共组件层,服务基础插件,比如日志 数据库 定时任务等
  • 支撑层,也就是数据层,数据的清洗,加工等

5 数据处理

服务器日志:

  • 用户产生数据
  • 日志搜集、消费、清洗
  • 数据流转

访问日志可以通过 nginx 来实现。

  • 每次都会产生 access.log 日志

原本的格式 + 图片带来的数据

消息系统:

如果数量较大,不好管理,单机也不好维护海量数据,这里引入了 kafka ,它是一个可以在多个应用质检可靠地传输实时数据的管道。

书籍《从零开始搭建前端监控平台》 - 图4

看起来是,前端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集群,效果较好
  • 错误的多样性,改成用户自己选择错误类型

简单读后感

快速翻阅了一遍,对比之前看到的利用阿里云日志服务来做数据支撑,这本书细节更多,可供参考。

但大量的代码,让人看着头疼。