本文将结合工做,描述一下前端监控系统Sentry搭建过程当中,背景、设计、实现、思考四个方面的感悟及问题。javascript
监控从字面含义来看包含两方面内容:监,监测的是代码;控,控制的是质量。监控是工具而不是目的,不是为了具备功能而监控,而是要经过监控,真正了解页面运行状况,以达到代码运行质量可控的目的。html
监控不一样于统计,统计关注的是一段时间内访问状况的一个总和,对于实时性要求并不那么高,能够延迟上报、累计上报;监控则偏偏相反,关注的是页面运行时的状况。前端
整个大前端角度来说,监控的场景不少。好比:服务端监控接口的稳定性和性能;客户端监控crash和APP性能;对Web前端来说,更加关注线上运行时的性能和报错。java
监控对于线上线下来讲都是有意义的,线下咱们能够支持自动化测试,上线前就发现代码运行时的一些明显错误,这个能够作为线下防退化的参考依据。线上环境则更加复杂,不一样的地域、设备、网络、浏览框架等诸多因素,致使一样的代码不一样环境中运行时,结果可能会参差不齐。咱们但愿了解这些状况,评估页面哪里须要优化。node
公司内部现有统计平台,如thunder,spy等通用的平台,便可以收集性能指标,也能够收集前端异常信息,可是收集的异常信息大多作统计用途,关注有多少报错信息,或者某类错误有多少类别,通常不会包含具体报错的详细信息。sql
前端还有一个特色,静态资源会混淆后压缩,若是运行错误,拿到的报错堆栈信息没有太大含义,只会报第一行报了xx错误,假设有sourcemap,咱们也只能借助Chrome Devtools来看具体是哪儿错误,但每每线上的报错,咱们很难复现。docker
经过前面提到的两个问题的收集:统计平台报错信息收集不够详细,没法根据报错反解源码错误行数,咱们选择基于开源Sentry在百度云上搭建了一套前端异常监控服务。数据库
Sentry是一个集中式日志管理系统。能够作如下事情,并且是相比于其余系统作的不错的地方。promise
首先提一下当下流行的Docker(是一个开源的应用容器引擎),Docker有一句口号:Build Once , Run Anywhere. 也就是说一个环境能够经过一次编译发布,在任何支持Docker的环境中能够快速跑起来,这解决咱们平常部署环境的痛苦。可是你们实践的时候发现,若是想要将Docker应用于具体的业务实现,是存在困难的——编排、管理和调度等各个方面,都不容易。因此K8S(全称:kubernetes,基于容器的集群管理平台)应运而生,应用于广大的实际项目中安全
广告一波自家的提供的云服务平台:百度云。百度云提供了丰富的基础服务支持,好比强大的容器服务CCE,域名解析分发服务ITM,数据分析服务Sugar等。咱们能够基于百度云提供的服务快速达成想要实现的内容。
自己Sentry支持源码部署和容器(Docker、K8S)部署两种方式,考虑到稳定性,想要实现多机器多机房部署、负载均衡、智能调度等实际问题,基于百度云提供的K8S服务,容器化部署了Sentry,如图1。
图1 :Sentry 百度云部署架构
结合业务,继续看一下Senty在总体项目中地位置,如图2。
图2 :项目总体架构图
这种架构下的Sentry服务,有几个优点:
平台在梳理清楚了上面流程的基础上,很快就搭建了起来。可是在平台试运行活成中,监控的每一个环节,不一样程度的暴露除了一些问题。针对监控的每一个流程环节,再次作了进一步的分析和优化。下面针对主要环节进行说明。
监控信息上报,主要依赖于SDK。之前端为例,Sentry自己提供了一个SDK,须要在页面加载过程当中,优先加载,进而实现尽量多的错误捕获。
<html> <head> <title>监控报警</title> <script src="https://xx/sentry.js"></script> </head> <body> ...... <body> </html>复制代码 |
实践过程当中,发现打包后的sentry.js 有20K左右,若是放到顶部,对于追求页面性能的页面来说,是灾难性的,由于JS放在顶部加载会阻塞页面的渲染。因而这对这种状况,进行了SDK后置优化。
<html> <head> <title>监控报警</title> <script> let estack = err => { return win[ers].length < 10 ? win[ers].push(err) : false; }; win.onerror = (a, b, c, d, error) => { estack(error); return true; }; win.addEventListener('unhandledrejection', error => { error.preventDefault(); estack(error); return true; }); <script> </head> <body> <script src="https://xx/sentry.plus.js" async ></script> <body> </html>复制代码 |
经过SDK的改造,大大减小了页面对于性能方面的担心,更加放心的使用Sentry服务。
SDK集成以后,日志采集经过一个POST接口请求实现。页面运行时,若是报错,会自动触发经过接口发送数据。
这时候是否须要支持采样,成了一个须要考虑的问题。由于若是没有采样,同时遇上较大的业务量,极大几率触发日志采集功能,大量日志上报,而有用信息较少。这时候采样就解决了这个问题。SDK自己是支持采样的,初始化的时候,只须要进行简单的配置
Sentry.init({ dsn:'xxx', sample: 0.5 });复制代码 |
这个抽样,指的是项目运行时,每次触发报错后,是否要进行错误上报的一个几率。可是对于追求页面性能的页面来说,一般每每但愿的是,SDK小流量接入。尽量少的去影响全部页面。咱们目前页面基于Php的Smarty模板进行的首屏渲染,因此改造了上报采集的方法:
{%assign var="random" value="{%math equation=rand(1,100)/100%}"|string_format:"%.2f"%} {%assign var="sample" value="0.5"|string_format:"%.2f"%} {%if $random < $sample%} <script type="text/javascript" src="https://xx/sentry.plus.js?v={%$smarty.now%}" crossorigin="anonymous"></script> {%/if%}复制代码 |
经过改造,又跟进一步减小了监控代码对业务的影响,业务更加方便的接入。
自己Sentry使用的是PostgreSQL,K8S部署时,数据库这里经过配置,使用百度云提供的数据库服务。
postgresql: enabled: false nameOverride: sentry-postgresql postgresqlDatabase: sentry postgresqlHost: 192.168.1.1 postgresqlPassword: xxx123 postgresqlPort: 3306 postgresqlUsername: sentrydb复制代码 |
数据库的费用也是挺贵的,占据了总体1/3资源的消费。业务接入的越多,存储数据量越大,一开始买的50G空间,很快就满了。
数据到底要不要,我分析了一下:对于报错自己的数据,尤为是每一个错误的详细信息,不必存储那么久,可是对于报表性质的内容,如报错整体状况的同环比,须要存储更早之前结果的。
第一种方法,土豪的作法:数据库扩容,继续增长投入购买。这种就是资金预算投入;
第二种作法:根据现有,收集错误的内容,把须要作报表的结果计算后单独存储,而后按期数据库清理,好比能够起一个脚本,进行按期请里10天前数据。
这里有一个小插曲,Sentry官方其实提供了清理数据库的API,能够经过命令进行清理:
// 进入容器 docker exec -ti xxxx /bin/bash // 清理 sentry cleanup --days 0复制代码 |
数据虽然清理了,可是发现PG数据库的容量没有释放,这是由于cleanup的使用delete命令删除postgresql数据,但postgrdsql对于delete, update等操做,只是将对应行标志为DEAD,并无真正释放磁盘空间。经过如下命令,完全清空。
sudo -u postgres vacuumdb -U postgres -d sentry -t nodestore_node -v -f --analyze复制代码 |
前面也提到过,Sentry提供了简单友好的后台管理系统。项目概况中,能够体现数据的报表展示。如图3。
图3:大盘展示
实践过程当中,尤为是给老板汇报的时候,发现只有这样的一个展示报表是不够的。通过调研发现百度云提供Sugar服务。能够直接连接数据库,对想要的数据自定义进行数据聚合,产出对应报表。这个产出需求还在调研中,不过产出的效果是很是使人期待的。配置内容如图4,预期效果如图5。
图4:配置内容
图5:预期效果
作为监控的闭环,咱们能够在Sentry后台中,根据不一样的规则,设置邮件报警。Sentry官方建议的邮件服务也不停在变动,最初的Exim4改成了mailgun,综合考虑费用的问题,咱们最终仍是选择docker搭建Exim4,而后邮件内容经过申请公司邮件安全组,白名单放开发送邮件的机器。最终实现了错误信息及时通知业务的功能。效果如图6。
图6:监控效果
以上就是在具体实践过程当中,关键路径遇到的一些问题,分享给你们。
公司的目的是盈利。一方面公司要控制成本,咱们能够看到投入QA人力日益削减,另外一方面又须要咱们线上运行的代码更加稳定,有什么办法能够作到呢?一个高效的方法就是增强监控。
经过监控,能够快速自主地发现问题。
能够将收集上来的数据进行分类筛选,而后设置报警告知。根据咱们监控内容,设定不一样的阈值,当达到阈值的时候,第一时间有效的通知到对应的研发人员,进行分析和修复。
经过监控,能够全方位了解页面运行状况。
经过信息收集,能够获取到用户访问的区域、机型、APP版本等基础用户信息,同时也可收集到页面运行时的性能,要知道性能就是金钱(打开速度必定程度上会影响用户的去留)。
经过监控,能够指导后期项目开发。
通过一段时间的沉淀,咱们收集过的错误,能够绘制出一个报表,统计出咱们某段时间内问题产生的缘由、报错、解决方案。
从研发流程上来看(以下图所示),咱们的项目不是完成上线就万事大吉。须要监控页面线上运行状况,根据监控的数据及时进行复盘,循环迭代优化,造成持续的研发闭环生态。
以上这些监控的意义,是往后流程机制的指南,是研发同窗的行为准则,也是老板、高工某些关键时刻作决策的参考内容之一。经过监控,更加直观地、全方位立体化地了解产品。
中台是公司内部最近技术方面的战略方向。在我看来:监控能够输出一个中台的方案,各部门基于中台服务进行定制化扩展。
其实咱们这里分享的Sentry系统,就能够做为公司内部的一个中台服务进行输出。各部门能够根据业务去定制SDK,也能够根据数据需求,自定义报表和报警。整个Sentry黑盒对外提供API服务,由于K8S带来的便利性,只须要对应部门提供预算,申请机器,往K8S上面增长缩减便可。
市面上其实已经存在不少不一样种类的监控工具。好比:frontjs、arms、岳鹰等,可是很遗憾,发现大可能是收费的。公司层面的产品,数据体量相对较大(但这方面的投入每每是值得的),有时数据产出较慢,结果每每阶段性地被新产品替代,厂内如今有一些针对前端的监控平台,诸如:天幕等,可能数据的采集、存储、过滤、展示、报警等监控过程当中的每一个环节,都须要须要耗费的人力和财力,这些都还缺乏一些中台的思路。
经过搭建和实现监控的整个过程,一方面充分体会到了云服务提供的技术给产品带来的便利,必定是将来的方向;另外一方面,脱离业务的技术是不靠谱的,技术服务于业务,咱们实现的技术必定要在业务中进行验证,才会促进技术更加完善,更加解决业务的实际问题。