在动手实现之前,首先脑子里要有一个整体脉络,明白搭建前端监控具体的流程步骤有哪些。因为前端监控系统实际上是一个完整的全栈项目,而并不仅仅是前端,甚至主要的实现都是围绕在数据方面的。
当然了,还有一点说明,本篇的实现主要是面对普通业务,面向中小厂自研的方向。我看过大厂做的监控系统,非常复杂能力也非常强,动不动就是亿万级别的数据,最后整还到了大数据的方向。我只介绍如何实现主要功能,如何解决问题。
前端监控的搭建流程分以下几个阶段:
- 采集阶段:数据的采集
- API 阶段:搭建 API 应用,接收采集到的数据
- 数据存储阶段:API 应用对接数据库,将采集到的数据存起来
- 查询统计阶段:对采集到的数据进行查询,统计,分析
- 可视化阶段:前端通过 API 查询统计数据,做可视化展示
- 报警阶段:API 对接报警通知服务,如钉钉
- 部署阶段:应用整体部署上线
下面我就梳理一下每个阶段的关键实现思路。
采集阶段:要采集哪些数据?
做监控的第一步就是采集数据,有了数据才是实现监控的前提。
采集数据的意义就是记录用户在使用产品过程中的真实操作,结合上一篇我们的分析,真实操作产生的数据可以分两大类:
- 异常数据
- 行为数据
我们先分析一下异常数据。项目中的异常总体可以分为两大类,一类是 前端异常 ,一类是 接口异常 。 前端异常 总结起来大概分为:
- js 代码执行异常
- Promise 异常
- 静态资源加载异常
- console.error 异常
- 跨域异常
其中最重要的,也是我们遇到最多的,就是各种各样的 js 代码执行异常。比如类型错误,引用错误等等,这些异常大多是我们编码不严谨导致的,因此收集此类异常有利于我们改进编码质量。
然后就是 Promise 异常,Promise 是 ES6 最重要的属性之一,考验我们的 js 异步编程能力,集中体现在接口请求上面,因此这两部分的异常捕获非常关键。
除此之外,静态资源加载异常,一般指在 html 中引用一些图片地址,第三方 js 地址等,各种原因不能正常加载了,这个也要监听的到。
console.error 异常,一般是在用某个第三方前端框架,他里面自定义了一些错误,会用 console.error 抛出来,这类异常也有捕获的必要性。
至于跨域异常,这个我们常常碰到,一般在前后端开发时的联调阶段就能发现。不过也保不定后端在线上突然改了什么配置,导致前端跨域,为了安全这个也要监听一下。
前端的异常采集大概就这 5 种吧,基本囊括了前端 90% 以上的异常情况。
接口异常属于后端的异常,但是接口异常会直接导致前端页面错误,因此这类异常是我们判断线上问题根源的重要依据。接口异常可以根据响应结果分类:
- 未响应/超时响应异常
- 4xx 请求异常
- 5xx 服务器异常
- 权限不足
有时候因为网络问题或者服务器问题,前端在发起请求之后迟迟未收到响应,请求被挂起,这种时候就属于未响应/超时响应异常。这类异常我们可以设置最大请求时间,超时之后主动断开请求,并添加一条接口超时记录。
除此之外,其他类型的接口异常我们就可以根据 HTTP 状态码 或者后端返回的指定字段如 error_code 来判断。
不管是用状态码还是其他判断方式,只要能区分异常类型就可以,这个不做严格要求。
4xx异常类型是请求异常,一般是前端传递的参数问题,或者接口验证参数的问题。处理这类异常的关键是保存请求参数,可以方便前端排错。
5xx错误是服务器内部处理的异常,这类异常的关键信息是报错时间,以及返回的异常说明,将这些保存下来,可以方便后端去查找日志。
权限不足我觉得也是一类重要的错误。因为现在某些管理系统的权限设计比较复杂,有时候突然莫名其妙的接口调不通,影响用户的下一步操作,这也需要记录和追踪。
虽然这里只列出了最通用三类,但是自研监控系统的一大优点就是灵活。如果你的业务场景有更复杂的异常情况,那么你完全可以自由发挥,从自己业务的实际情况出发,设计出更适合自己的异常分类,只要终极目标是可以帮我们更好的追踪和快速解决问题就可以。
这个阶段非常关键,是监控系统设计的核心,所以我写的比较细,大家在这个阶段关于采集哪些数据也要多多考虑。而后面的阶段,则都是基于此设计的具体实现。
API 阶段:搭建上报数据的 API 接口
上一阶段做好了采集数据的方案,当采集到数据之后,接下来就要将 数据上报 。
数据上报说白了就是通过调用一个 API 接口将这些数据传过去然后存在数据库中,因此本阶段的任务就是搭建上报数据的 API 接口应用。
作为一名光荣的前端工程师,开发接口,自然要选择同属 JS 家族的 Node.js 了。Node.js 目前的框架也比较多,我比较喜欢轻量好简洁的,需要什么自己安装,所以我选择简单经典的 Express 框架。
搭建 API 应用要做的事情有:
- 目录结构设计
- 路由设计
- 鉴权认证
- 参数验证
- 请求响应封装
- 错误处理
还有一些细节的处理。这个阶段对后端基础薄弱的同学来说,是非常好的学习时机。
我非常建议前端小伙伴们掌握一部分后端基本知识,至少在简单的原理方面明白是怎么回事。这个阶段主要是搞明白 API 应用是怎么搭建起来的,每个部分为什么要这么做,能解决什么问题,这样你的后端基础知识就会建立起来了。
框架搭好之后,主要做的就是设计接口 URL 然后写处理逻辑,保证这一步设计的接口能调通,并且能接收到数据。
数据存储阶段:接口对接数据库
上一步我们搭建好了 API 接口,接收到了采集的数据,那么我们这一步就是要对接数据库,将采集到的数据存到数据库里。
数据库的话,就选对前端最友好的,属于 NoSQL 家族的文档数据库 MongoDB 。
这个数据库最大的特点是,存储的数据格式类似于 JSON,操作起来就像在 JS 中调用函数,组合 JOSN 数据一样,对我们前端理解和入门非常容易,在实战过程中你就能体会到它的优雅了。
数据存储阶段,主要介绍数据库的基本信息和操作,包括以下方面:
- 数据库怎么连接
- 怎么设计字段
- 怎么做验证
- 怎么写入
- 怎么查询
这个阶段比较关键的是 数据验证 ,在设计好数据库字段之后,我们希望所有写入的数据都要符合我们想要的数据格式。如果在验证之后不符合,我们可以补充或修改数据字段,或者直接拒绝写入,这样能保证数据的可靠性,也避免了不必要的数据清理。
做好了数据写入的工作,还要加一部分简单的查询和修改功能。因为你写入数据之后要看看执行成功没有,就可以查一个列表看结果了。
修改功能也很必要。前端监控中有一个很常见的需求是: 计算用户的页面停留时间 。我的方案是在用户进入某个页面的时候创建一条记录,然后在离开时,修改这条记录,加一个结束时间的字段,这就需要修改功能了。
最后还要提一下,很多人在聊怎么做 数据清洗 。其实这个就看你前面存储数据的时候验证做的怎么样了。如果确实有可能存入无效的数据,那么就可以写一个清除数据的接口,写自己的清理逻辑,然后定时执行一下。
查询统计阶段:数据查询和统计分析
前面经过一系列准备我们完成了 API 接口和数据写入的功能,假设我们已经采集到了足够的数据并存入数据库,这个阶段就是好好利用这些数据的时候了。
本阶段的主要任务就是对数据进行检索和 统计分析 ,基本上都是“查询”的操作。
这里的查询不单单只是查一下,具体怎么查,关系到了我们搜集的数据能否有效利用。我的思路还是从这两个方面入手:
- 行为数据
- 异常数据
当然了这只是从总体来说。行为数据也会单条查询,比如我要看某个时间某个用户做了什么操作,这就属于精确查找。异常数据也有统计,比如异常接口触发频率的排行等。
行为数据的数据量会非常大,在用户使用系统的过程中会频繁产生然后频繁被写入数据库。因此这类数据绝大多数情况是通过 聚合查询 的方式从页面,时间等多个维度做总体统计,最后得出一些百分比的结论。这些统计值可以大致反应出产品的实际使用情况。
这里有个优化点,因为频繁请求会加重接口负担,因此数据也可以本地先存储一部分,达到一定量之后再请求接口,一次性存入。
异常数据对开发人员来说非常重要,是我们定位和解决 bug 的神辅助。不同于行为数据的多条统计,异常数据我们更关心单独每一条记录的详细信息,方便我们一目了然的看到错误。
异常数据查询也比较简单,和普通的列表查询一样,返回最新的异常数据即可。当然了我们排查问题之后,还应该对处理好的异常标记为已处理,这样可以防止重复排查。
可以看出,这个阶段最主要的还是做统计接口,为下个阶段可视化图表展示做准备。
可视化阶段:最终的数据图表展现
上一个阶段我们开发了统计接口,查出了想要的数据结果,可惜这些结果只能程序员看懂,别人恐怕是看不懂。所以最终为了更直观的反应数据,我们要用前端可视化图表的方式,让这些数据活起来。
在这个阶段,我们终于回到了最熟悉的前端领域。那本阶段的任务相对来说也简单顺手,基于 React 搭建一个新的前端应用,接入上一步的统计接口,再集成前端图表库,将统计结果用图表展现出来。
这个新应用是真正要对外展示的前端监控系统,给团队内部的开发或产品同学使用,这样他们可以实时查看产品生成的数据信息,从而解决自己的问题了。
这一阶段其实没什么关键问题要讲,主要就是选择一个好用的图表库,对接接口。还有图表的种类多种多样,要考虑哪些数据适合哪种图表,结合实际判断一下。
最后,监控系统的前端页面和接口数据肯定不能所有人都看,所以还要有基础的登录页面和功能。做到这里,本阶段的任务就结束了。
报警阶段:发现异常马上报警通知
上一阶段,监控系统前端搭建完成,并将统计数据展现为图表之后,整个监控系统就基本可用了。
但是还有一种情况,就是用户使用我们的产品突然报错了,错误信息也被写入了数据库。如果此时你没有主动刷新页面,事实上你也不可能一直刷新,那么这条错误我们是根本不知道的。
如果这是一个很致命的 bug,影响很广泛,Bug 发生我们竟然不知道,这就会给我们造成很大的损失。
所以呢,为了保证我们及时的解决 Bug,一个报警通知的功能就非常重要了。它的作用是在异常发生时,第一时间推送给开发人员,这样大家才能立即发现问题,然后用最快的速度去解决,避免遗漏。
报警通知,一般现在通用的方案是对接钉钉或者是企业微信的机器人,我们这里使用钉钉。具体用哪个平台还得看你的主体在哪个平台。比如我的团队的主体在钉钉,那么在发送报警通知时,可以直接用手机号来 @ 你的任意组员,实现更精准的提醒。
这一部分是 API 应用的补充,申请钉钉开发者权限之后,在 API 中接入相关代码。
部署阶段:万事俱备只等上线
前面的几个阶段,我们完成了数据采集,API 应用搭建,数据存储,前端可视化展现,以及监控报警,整个前端监控系统的功能就全部完备了。最后一步就是将前后端数据库全部部署上线,供大家访问。
部署这块主要是 nginx 解析,https 配置,数据库安装,和 nodejs 的应用部署等,这个阶段的内容会偏运维一些。不过别担心,这里我也会对关键操作做详细介绍。
当这个系统上线以后,你就可以尝试在你的任意一个前端项目,根据第一篇的采集方法,将采集到的数据通过 API 保存,然后就可以登入监控系统查看真实的使用数据了。
当这一部分完成之后,恭喜你,一个小型的前端监控系统就搭建好了。后续可以基于此不断扩展功能,慢慢让这个自研的监控系统更加强大。
总结
本篇介绍了前端监控系统的搭建过程,将整体流程划分为几个阶段,简述了每个阶段要做什么事情,以及关键问题是什么,帮你理清搭建监控系统的思路。