你是一个前端程序员,为了业务稳定,给系统接入了监控告警,但接入告警后,你有了几个烦恼:
- 告警不准确。要么频繁误报,导致团队对告警麻木;要么完全漏报,让监控形同虚设;
- 指标难选择。从流程开始到结束,有大量可监控指标,但你不知道哪些指标更关键;
- 信息不实用。虽然你上报了错误信息,但真正排查问题时,却发现这些信息要么用不上、要么很难找到。
存在这些问题,说明你只是"有"监控系统,但这个系统谈不上"有用"。
一个有用的监控告警体系,需要在告警准确性、告警指标和告警信息三方面认真设计。
恰好,我正在完善业务的监控,有些经验想与你分享。
我是印刻君,一位前端程序员,关注我,了解更多有温度的轻知识,有深度的硬内容。
问题分析
为什么告警不准确?
一般告警系统,采用的是阈值告警。也即设定一个临界值,当指标突破临界值时就触发告警。
以页面错误率为例,"当错误率超过 0.02% 时触发告警",这个 0.02% 就是阈值。然而,阈值的设置高度依赖经验,设置不当极易导致误报或漏报。这个问题的具体解决方案,我会在后文讨论。
为什么告警指标难选择?
告警指标难选择,是因为指标太多。之所以指标太多,我认为主要原因是前端的责任边界相对模糊。任何影响用户体验的问题都可能被追溯为"前端监控不完善"。
以接口监控为例,理论上它可以完全由后端负责,但实践中,前端通常需要再建设一套接口监控。因为当接口出现问题时,用户首先感知到的是页面异常,而不是后端服务器异常,于是很容易把责任归咎给前端。
这种"前端兜底"的现象,使得前端监控不得不覆盖更多的环节。解决办法我会在后文讨论。
为什么告警信息不实用?
我认为告警信息不实用主要原因有二:
- 收集信息不完整
收集信息分为业务信息、技术信息,业务信息本文不讨论,技术信息我会在后文提供小技巧。
- 信息展示不合理
即使收集了完整的告警信息,但如果展示不恰当,也会影响排查效率。例如信息分散在多处、重要信息被次要信息淹没,都会增加排查难度。
解决方案
如何提高告警准确性?
告警阈值的设置依赖经验,我建议用"分级告警"来降低依赖。
分级告警的核心思想是,给同一个指标设置不同梯度的阈值,每个阈值对应不同级别的告警。
以错误率监控为例,业务初期,缺乏历史数据参考,你可能无法确定正常的错误率水平。此时可以设置如下告警:
级别 | 错误率(可调整) | 告警方式 |
---|---|---|
P2 | 0.005% | 触发飞书/企业微信等即时通讯工具告警 |
P1 | 0.01% | 触发短信告警 |
P0 | 0.02% | 触发电话告警 |
通过分级告警,既降低对历史经验的依赖,又避免单一阈值带来的"误报"和"漏报",还可以给团队提供合理的相应时间。
后续随着业务运行,你可以根据实际告警频率,逐步调整这些阈值,使告警更加准确。
如何选择告警指标?
前文提到,告警指标难选取,原因是前端责任边界模糊。
我建议"按生命周期分段监控",把前端代码从下载到用户交互的完整过程,拆分为启动、请求、渲染和交互 4 个阶段,每个阶段选择最具代表性的指标进行监控:
- 启动阶段
指标(React Native 适用,H5 不适用) | 定义 | 作用 |
---|---|---|
包下载成功率 | <math xmlns="http://www.w3.org/1998/Math/MathML"> 下载代码包成功的次数 下载代码包的总次数 \frac{下载代码包成功的次数}{下载代码包的总次数} </math>下载代码包的总次数下载代码包成功的次数 | 反映代码包分发基建的稳定性 |
Crash 率 | <math xmlns="http://www.w3.org/1998/Math/MathML"> 代码包导致 A p p 崩溃的次数 A p p 启动的次数 \frac{代码包导致 App 崩溃的次数}{App 启动的次数} </math>App启动的次数代码包导致App崩溃的次数 | 反映代码包的质量 |
- 请求阶段
指标 | 定义 | 作用 |
---|---|---|
网络成功率 | <math xmlns="http://www.w3.org/1998/Math/MathML"> H T T P 请求状态码为 2 x x , 3 x x 的次数 H T T P 请求总次数 \frac{HTTP 请求状态码为 2xx, 3xx 的次数}{HTTP 请求总次数} </math>HTTP请求总次数HTTP请求状态码为2xx,3xx的次数 | 反映后端服务器的稳定性 |
业务成功率 | <math xmlns="http://www.w3.org/1998/Math/MathML"> 业务 c o d e 码为 0 的次数 + 其他预期 c o d e 的次数 H T T P 请求总次数 \frac{业务 code 码为 0 的次数 + 其他预期 code 的次数}{HTTP 请求总次数} </math>HTTP请求总次数业务code码为0的次数+其他预期code的次数 | 反映后端接口的可用性 |
请求次数 | / | 反映业务的访问量 |
- 渲染阶段
指标 | 定义 | 作用 |
---|---|---|
白屏率 | <math xmlns="http://www.w3.org/1998/Math/MathML"> 用户 5 s 内看到的白屏 p v 总 p v \frac{用户 5s 内看到的白屏 pv}{总 pv} </math>总pv用户5s内看到的白屏pv | 反映页面的可用性 |
JS 错误率 | <math xmlns="http://www.w3.org/1998/Math/MathML"> 出错的 p v 总 p v \frac{出错的 pv}{总 pv} </math>总pv出错的pv | 反映前端代码的稳定性 |
图片加载错误率 | <math xmlns="http://www.w3.org/1998/Math/MathML"> 图片加载错误的次数 图片加载的总次数 \frac{图片加载错误的次数}{图片加载的总次数} </math>图片加载的总次数图片加载错误的次数 | 反应 CDN 的可用性 |
- 交互阶段
- 根据业务场景定制的指标,反映业务功能的可用性。
你也可以按需要,在每个阶段增加更多的指标。
按生命周期分段监控后,告警发生时,你可以快速定位问题、明确责任归属。当问题不由前端造成时,你第一时间感知问题、反馈上级,能减少后续的解释成本。
如何让告警信息更实用?
告警信息的实用性,主要取决于两个关键因素:信息收集的完整性和信息展示的合理性。
针对前者,我建议在所有 catch 块都上报错误,且每个块都加上唯一的错误标识。
- 所有 catch 块都上报错误,是因为虽然监控 sdk 全局捕捉了错误,但代码中的 try-catch 会拦截部分错误,导致这些错误没有暴露。
- 每个 catch 块都上报错误,则是为了发现错误后,能及时定位到上报的代码位置。
针对后者,我的建议是,采用"先整体后局部"的展示策略。
- 先整体,是指为每一个核心指标都配置趋势大盘。它可以帮助你快速定位问题的发生时间、发生环节和影响范围。
- 后局部,是指善用大盘图表的下钻分析功能,它从图表逐层深入,更方便分析问题的根本原因。
总结
建设一个"有用"的监控告警体系,不仅是一个技术问题,更是一个系统工程。它需要你在告警准确性、指标选择和告警信息三个维度上进行精心设计和持续优化。
通过"分级告警"、"生命周期分段监控"和"合理的信息收集、展示策略",我相信你可以构建一个真正有用监控告警体系。
我是印刻君,一位前端程序员,关注我,了解更多有温度的轻知识,有深度的硬内容。