前言 : 在4月25日,我参加了前端早早聊的在线直播话题---前端如何搞监控。 听完以后收获很大。我将把会议总结为前端搞监控的价值、须要监控的内容等方向去描述,并以自研监控SDK的经验为例,进一步了解前端搞监控的技术点所在。前端

一 前端监控系统概览:
1 为何要作一套前端监控系统?
经过用户行为采集分析,当前端及客户端线上出现异常时,能够经过用户行为链及设备环境,快速定位线上环境的问题所在。android
齐次,当功能上线后,用户的使用效果没办法衡量。须要数据指标去衡量,好比功能使用率、性能指标等。数据库
业务方的对业务的创意及需求须要反复不断的调优、开发,相同的组件开发了无数个,极可能明天又得改回去,这就形成了大量的资源浪费。若是没有一个量化体系的话,运营只能经过上次成功的经验来感受。因此须要经过对用户数据的监控,从而获得一个调优策略和量化指标。小程序
以后,咱们须要知道对于界面设计风格及投放的广告资源,哪些手段会更有价值,去作一我的群的细分,提升用户体验。微信小程序
2.前端监控须要监控什么?
前端监控采集的内容主要包括行为分析、异常监控、性能监控等。跨域
其行为分析主要有:页面的进入、离开、点击、滚屏、自定义事件promise
简单作法是在项目的编译过程当中,将项目ID、页面ID等挂载在标签上,当进入页面时,咱们就能够根据这些ID去定位惟一一个页面,这样就能够知道用户的页面进入、离开及按钮的点击等事件服务器



不过用户可能并非完整地去走过了一个页面点击流程,而是从中间的页面进入好比点击了超连接,就须要让收集到的数据更有参考价值,以更准确地反映用户真实状况。 在路径分析里,去查看用户的来源和去向 微信



3.前端监控设计策略
3.1 面向组件设计监控策略
咱们将对网页的埋点分为以下几个级别,从而更好地为后面的分析提供服务网络



为了更方便分析数据。当内网访问时,CDN判断为白名单用户,就会为页面注入数据化分析能力,从而更方便地实时查看数据而无需再打开额外的数据分析平台

3.2 面向业务设计监控策略
对于不一样风格的组件,须要进行一个精准的人群的划分



整个下来须要有一个数据采集、数据存储、数据清洗、数据异常、数据展现的过程。

其中采集方式包括无埋点采集和有埋点采集。 无埋点采集主要是经过在框架层预设SDK,预设通用的事件。 有埋点采集对用户的浏览日志、浏览内容、触发时机等一些自定义事件的一种采集方式



二 自建前端监控体系
做为开发运营者来讲,自建前端监控体系,须要清楚地去分析及追踪,当线上的前端与客户端发生问题时,如何快速定位到这些问题并解决
1 以宋小菜APP为例,针对APP自建前端监控体系
其目前的系统架构以下

首先须要明确要采集哪些错误日志数据,而后去相应的设计SDK

RN SDK



在收集到的错误log里使用kafka进行转发

在日志处理时,能够采用一些策略
- 在向ES写入JSON时,因为数据量大,能够按时或按天创建索引,从而不会查询的时候特别慢
- 要创建一个统一的索引模板,对于索引的保存的数据类型要统一,不然会形成数据保存失败
- 因为上报的类型涉及到了多端,并且又包括自定义的上报内容,因此设计的上报的规范也不能太死。哪些字段变化哪些字段不变须要根据系统衡量

- 有一些字段是某些场景下是没有必要创建索引的,不然会形成字段爆炸,那么就能够以String类型存储下来
在报警监控系统的设计上,咱们能够在监控后台上建立报警任务,而后报警任务经过kafka推送到任务管理中,任务管理器根据不一样的任务分发到任务执行器中

在收集到的错误信息上,都通过TraceKit作一个标准化,以后根据错误类型去作一个归类,以下面这些特征。根据这些特征,来判断信息是否为重复的问题





2 以贝贝自研SDK为例,对数据进行搜集与清洗
在监控平台上,贝贝选择的是自研SDK,缘由是端平台多、项目多,第三方须要去考虑成本,另外在扩展性、支持的平台方面等,在目前的监控方案如Sentry、FundeBug、Bugly,也存在受限。


数据搜集与上报
在前端,能够经过上报上来的错误堆栈去分析应用出现的错误缘由,方便排查问题

上报方式SDK如何设计?
对于上报方式,能够分为自动上报(左)和手动上报(右)

- window.onerror:运⾏时错误捕获
- window.addEventListener(‘unhandledrejection’):promise 没有 catch 错误
- try/catch 处理跨域脚本错误
- 其余技术栈中(Vue、React)的错误捕获
例如在Vue中,咱们能够劫持它的errorHandler,而后在发生错误的时候上报,以后再去执行剩下的操做


SDK又如何去作信息收集?





SDK如何进行数据上报?
使用经过GET方法发送一个1*1的GIF图片及错误信息进行上报


数据清洗与压缩:
SDK获取到的数据量大、没有分类聚合、也没有过滤,因此须要去进行一个数据清洗
首先在存储方案上,选择MySQL做为永久存储,选择ES做为临时存储

对于收集到的数据设置阈值,即规定:
每分钟数据获取上限 10000 条,超过就采样⼊库。同类型错误数量⼤于 200 条,只统计数量
同时,因为ES返回的是String流格式,须要使用JSON.parse()解析出来。 最后将下面的数据去作修正如去掉转义符,忽略非法数据等。最终存到MySQL中。

在聚合的维度上,能够分为业务名、数据类型、错误信息 按照这样的3个维度,作成MD5以用于判断后面发生的错误是否为相同的错误



数据告警
当监控条件知足时,监控平台会将错误发送给相应的开发者

好比对于Android来讲,当错误发生时,先存储到本地的数据库,而后进行尝试地上报。若是上报成功,就将本地数据删除,不然待下次APP启动的时候再上报

3 基于错误日志进行进一步的优化
在系统中,须要对数据日志清洗、辅助分析能力、用户界面展现、错误告警追踪能力进行进一步优化
在错误聚合中可分为通用优化和专用优化

若是本是同一个错误,却由于一些缘由如发生错误的视图信息(红色部分)致使描述不一样,就能够只把相同的部分,错误名和错误堆栈作一个散列

这时能够经过正则去掉系统类对应的行号去掉,再去散列


好比在前端上,能够分析前端的行为链路


监控系统最终还要造成一个错误闭环,当发生错误时,及时交付给相应开发人员,版本成功修复之后再对线上监控进行一个更新


在监控的筛选时间中,还要注意客户端是先将错误保存到本地,以后会尝试性地去上报错误。端侧会累积错误并存在延迟,因此服务器接受到的错误极可能并非最新的错误。
因此对于数据的筛选与告警阈值的设定,就能够有下面这两种策略。
若是按服务端时间来进行筛选,就能够定义一个小时内发生的错误为最近的错误。若是按客户端时间,则看在这一个小时内,哪些错误在一个小时内,其记录的错误里间隔一分钟的时间的错误数量超过了阈值。

4 如何基于堆栈映射去定位问题?
前端问题的定位难在什么地⽅?
前端的日志不像服务端,它是发生在端侧的,因此只能依赖于上报,但上报的话又不可能获取到全部的信息,可能会缺失上下文,另外前端代码会进行混淆,堆栈没法直接使用。

能够在服务端将堆栈作个SourceMap映射到源码上
但会有一些问题,好比可能由于依赖的包的版本变化,致使线上映射后和实际生产环境的代码不对应。SourceMap映射也相对较慢,等映射完再去排查可能浪费了不少时间并且映射时会占用很大内存
给出的解决方案是异步生成SourceMap。首先锁定依赖,避免后面因版本问题致使堆栈对不上,以后将SourceMap映射和正常的版本构建分离开,这样就不会因SourceMap的占用内存过大致使影响正常版本的上线





三 监控系统在实际应用中还存在的问题
1.有些异常是因为手机厂商、第三方注入等致使的,并非实际业务引发的






四 感触
从会议中了解到了前端搞监控的巨大意义和相关技术点,使用监控系统从而更好地提高用户体验和产品开发以及问题排查,这些都是本身以前从未接触过的。特别感谢前端早早聊大会的分享,收获颇多!
五 关于前端早早聊大会
关于前端早早聊大会:前端早早聊大会目标成为用得上、听得懂、抄得走的技术大会,计划 2020年办>= 15期,由前端早早聊与掘金联合举办,前端早早聊大会行程动态、录播视频/PPT/讲稿资料下载请关注 「前端早早聊」 公众号跟进。
