Sentry 错误监控
本篇文章主要是对最近公司接入前端监控,关于前端错误监控的一些了解。
前言
Sentry 是一项可帮助您实时监控和修复崩溃的服务。它支持前后端移动端等平台,囊括近百种编程语言,Node.js,PHP,Python,Go,JavaScript 等等。拥有了它,我们就能拥有了完整错误收集、监控和管理能力。这篇文章主要介绍了前端错误及 Sentry 的原理。
- 官网:sentry.io
- 社区:forum.sentry.io
前端异常及捕获
在正式了解 Sentry 之前,我们首先要对 JavaScript 中的错误异常有一个清晰的认识。毕竟 Sentry 作为一个异常收集的工具,主要面对的就是前端异常。对于 JS 来说,通常异常的出现并不会直接导致 JS 引擎崩溃,只会使当前执行的任务终止,下面是常见的异常类型:
异常类型

Try-Catch 能捕获什么
try-catch
只能捕获到同步状态下的运行时错误,无法捕获到语法和异步错误。
- 同步状态下的运行时错误:
1 | try { |
- 无法捕获语法错误:(如删除一个单引号)
1 | try { |
语法错误在开发中就能看到,一般不会存活到线上。 但是代码运行在不兼容的环境,也可能存在语法错误,如 IE 浏览器。
- 异步错误:
1 | try { |
可以看到,try-catch
并无法捕获到异步异常。需要借助全局的错误监听了~
GlobalEventHandlers.onerror
混合事件 onerror 属性的触发有两种情况(MDN):
- 当 JavaScript 运行时错误(包括语法错误)发生时,window 会触发一个 ErrorEvent 接口的 error 事件,并执行 window.onerror()。
- 当一项资源(如
<img>
或<script>
)加载失败,加载资源的元素会触发一个 Event 接口的 error 事件,并执行该元素上的 onerror() 处理函数。这些 error 事件不会向上冒泡到 window,不过(至少在 Firefox 中)能被单一的 window.addEventListener 捕获。
window.onerror
window.onerror()
返回 true
,则阻止默认事件处理函数。
1 | /** |
window.addEventListener('error')
1 | /** |
element.onerror
1 | /** |
Promise Catch
没有写 catch 的 Promise 中抛出的错误,无法被 onerror 或 try-catch 捕获到,所以在使用 Promise 的时候,一定要记得 catch 处理抛出的异常。
也可以全局增加一个 unhandledrejection 事件监听,来全局监听 Uncaught Promise Error。
1 | window.addEventListener("unhandledrejection", function (e) { |
iframe 异常
对于 iframe 的异常,我们还需要使用 window.onerror 去监听指定的 iframe:
1 | <iframe src="./iframe.html" frameborder="0"></iframe> |
根据上面的例子可以看出,不同的场景下需要使用不同的错误收集方式。接下来,让我们看看 Sentry 的具体接入流程。
Sentry 接入流程
自动上报
无感知收集,配置 Sentry。主要利用了 Sentry 的 JavaScript SDK。
1 | isBuild && |
手动上报
关键位置手动设置相关参数。
1 | Sentry.captureException('captureException'); |
Sentry 错误捕获原理
捕获流程可以分为全局捕获和单点捕获。
全局捕获
代码集中,易于管理。
- 全局接口
window.onerror
、window.addEventListener('error')
、window.addEventListener('unhandledrejection')
- 框架级别的全局监听
- vue、react 都有自己的错误采集接口
Vue.config.errorHandler
- 如 aixos 中使用
interceptor
进行拦截(全局接口拦截)
- 在全局对函数进行包裹,实现在调用函数时自动捕获异常
setTimeout
、setInterval
、requestAnimationFrame
单点捕获
作为全局捕获的补充,对某些特殊情况进行捕获,但是分散且不利于管理。
- 对单个代码块包裹,在逻辑中大点,有针对性的异常捕获,常使用
try...catch
- 专门的函数,用来收集异常,在异常发生时调用
- 例如在 axios 通过请求,发生错误时候,通过
Sentry.caputureException()
主动上报
- 例如在 axios 通过请求,发生错误时候,通过
- 专门的函数包裹其他函数,在有异常的时候上报
其他功能
性能监控
Sentry 提供了性能监控功能,主要是依靠了 web-vitals 包,想了解具体使用可以看看这篇文章。里面讲解了一下一些 web-vitals 的关键指数及相关的优化策略。这里就不太多展开。
- Largest Contentful Paint (LCP):最大内容绘制,测量加载性能。为了提供良好的用户体验,LCP 应在页面首次开始加载后的 2.5 秒内发生。
- First Input Delay (FID):首次输入延迟,测量交互性。为了提供良好的用户体验,页面的 FID 应为 100 毫秒或更短。
- Cumulative Layout Shift (CLS):累积布局偏移,测量视觉稳定性。为了提供良好的用户体验,页面的 CLS 应保持在 0.1. 或更少。
为了确保您能够在大部分用户的访问期间达成建议目标值,对于上述每项指标,一个良好的测量阈值为页面加载的第 75 个百分位数,且该阈值同时适用于移动和桌面设备。
如果一个页面满足上述全部三项指标建议目标值的第 75 个百分位数,那么评估核心 Web 指标合规性的工具应评判该页面为通过。
录制
Sentry 的屏幕录制主要依靠 rrweb 。大致流程为:
- 首先保存一个一开始完整的 dom 的快照,然后为每一个节点生成一个唯一的 id。
- 当 dom 变化的时候通过
MutationObserver
来监听具体是哪个 DOM 的哪个属性发生了什么变化,保存起来。 - 监听页面的鼠标和键盘的交互事件来记录位置和交互信息,最后用来模拟实现用户的操作。
- 然后通过内部写的解析方法来解析。
- 通过渲染 dom,并用 RAF 来播放,就好像在看一个视频一样。
上传 sourceMap
上传了 sourceMap,能让我们快速定位错误所对应的源码 大致有三种方式
- 官方 cli(sentry-cli)文档
- 调用 HTTP API 文档
- webpack 插件
- sentry/webpack-plugin webpack 的 afterEmit 钩子,获取并上传
- webpack-sentry-plugin 支持上传完毕后删除文档
- vite 插件
- 暂无官方插件
参考
- 本文标题:Sentry 错误监控
- 本文作者:hddhyq
- 本文链接:https://hddhyq.github.io/2021/12/12/sentry-share/
- 版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!