Skip to content

异常监控:用 Sentry 给你的应用装个"黑匣子"

· 14 min

说起线上 Bug,那真是每个开发者心中永远的痛。测试阶段明明好好的,一上线就各种妖魔鬼怪冒出来。用户投诉说页面白屏,你本地跑得好好的;说某个功能点不了,你怎么点都没问题。这种时候,你是不是特别想穿越到用户电脑前,看看到底发生了什么?

今天就来聊聊 Sentry 这个”神器”——它就像给你的应用装了个黑匣子,出了问题能第一时间告诉你哪里炸了,怎么炸的,甚至用户当时在干什么。

背景:为什么需要异常监控#

测试覆盖不了的那些事儿#

虽然我们上线前都有测试流程,QA 同学也很给力,但说实话,想要 100% 覆盖所有用户场景,那基本是天方夜谭。用户的使用环境千奇百怪:

这些场景在测试环境里很难完全模拟,所以线上总会有一些”惊喜”等着你。

用户反馈的局限性#

以前没有监控系统的时候,我们主要靠用户反馈来发现问题。但这种方式有几个致命缺陷:

  1. 反馈不及时:用户遇到问题可能不会立即反馈,甚至直接走人
  2. 描述不准确:用户说”页面坏了”,但具体哪里坏了,怎么坏的,一问三不知
  3. 复现困难:没有详细的错误信息和用户操作路径,复现问题就像大海捞针

痛点:线上常见的那些”鬼”#

在实际项目中,我遇到过各种各样的线上问题,总结起来主要有这几类:

1. 页面加载慢#

用户抱怨页面半天打不开,但你本地测试速度飞快。这种问题往往跟网络环境、CDN 节点、资源大小有关。没有监控数据,你只能靠猜。

2. 渲染错乱#

CSS 样式突然不生效,页面布局乱七八糟。可能是某个第三方库的兼容性问题,也可能是浏览器的渲染 Bug。

3. 交互异常#

按钮点了没反应,表单提交失败,这类问题最让用户抓狂。通常是 JavaScript 报错导致的,但没有错误信息,你根本不知道从哪里查起。

4. 白屏问题#

这是最严重的问题,用户看到的就是一片空白。可能是 JavaScript 加载失败,也可能是某个关键组件渲染异常。

5. 卡顿#

页面响应慢,操作不流畅。这种性能问题很难定位,需要详细的性能数据才能分析。

6. 用户行为日志#

想要了解用户是怎么使用你的产品的,哪些功能用得多,哪些功能没人用,这些数据对产品优化很重要。

7. 用户手动上报崩溃#

有时候用户遇到问题,希望能主动反馈给开发者,这时候需要一个便捷的上报机制。

为什么选择 Sentry?#

市面上的错误监控平台不少,为什么我最终选择了 Sentry?主要有几个原因:

1. 免费额度够用#

Sentry 提供了相当慷慨的免费额度,对于中小型项目来说完全够用。每月 5000 个错误事件,对于大部分应用来说都绰绰有余。

2. 部署方式灵活#

你可以直接使用 Sentry 的云服务,也可以自己搭建私有化部署。对于有数据安全要求的企业来说,这个选择很重要。

3. 兼容性强#

支持几乎所有主流的编程语言和框架:JavaScript、Python、Java、Go、React、Vue、Angular…你能想到的基本都支持。

4. 功能全面#

不仅能捕获运行时错误,还支持:

5. 社区活跃#

开源项目,社区很活跃,文档也比较完善。遇到问题基本都能找到解决方案。

接入过程:从零到一的实战#

第一步:安装和初始化#

首先安装 Sentry SDK:

Terminal window
npm install @sentry/vue

然后在应用的入口文件(比如 Vue 的 main.js)中初始化:

import { createApp } from 'vue'
import * as Sentry from '@sentry/vue'
import App from './App.vue'
const app = createApp(App)
Sentry.init({
app,
dsn: "你的DSN地址",
environment: process.env.NODE_ENV,
// 其他配置...
})
app.mount('#app')

这里有个重要的点:Sentry 的配置应该在应用程序生命周期的最早期进行。这样才能确保捕获到所有可能的错误。

第二步:详细配置#

Sentry 的配置项很多,我来说说几个关键的:

Sentry.init({
app,
dsn: "你的DSN地址",
// 环境信息
environment: process.env.NODE_ENV,
// 版本信息,用于追踪哪个版本出现了问题
release: process.env.VUE_APP_VERSION,
// 错误采样率,1.0 表示 100% 上报
sampleRate: process.env.NODE_ENV === 'production' ? 0.1 : 1.0,
// 性能监控采样率
tracesSampleRate: 0.1,
// 会话回放采样率
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
// 捕获行为栈的总量
maxBreadcrumbs: 50,
// 数据结构深度
normalizeDepth: 5,
// 发送 event 前的钩子函数
beforeSend(event, hint) {
// 在这里可以过滤掉一些不需要的错误
if (event.exception) {
const error = hint.originalException
// 过滤掉网络错误
if (error && error.message && error.message.includes('Network Error')) {
return null
}
}
// 添加用户信息
event.user = {
id: getUserId(),
username: getUsername(),
email: getUserEmail()
}
return event
},
// 集成配置
integrations: [
new Sentry.BrowserTracing(),
new Sentry.Replay({
maskAllText: false,
blockAllMedia: false,
}),
],
})

第三步:Source Map 上传#

这一步很关键!没有 Source Map,你看到的错误堆栈都是压缩后的代码,根本看不懂。

首先安装 Sentry 的 Webpack 插件:

Terminal window
npm install @sentry/webpack-plugin --save-dev

然后在 vue.config.js 中配置:

const { sentryWebpackPlugin } = require('@sentry/webpack-plugin')
module.exports = {
configureWebpack: {
plugins: [
sentryWebpackPlugin({
org: "你的组织名",
project: "你的项目名",
authToken: process.env.SENTRY_AUTH_TOKEN,
// 只在生产环境上传
include: './dist',
ignore: ['node_modules', 'webpack.config.js'],
// 上传后删除本地 source map
cleanArtifacts: true,
// 设置 release 版本
release: process.env.VUE_APP_VERSION,
}),
],
},
// 生产环境生成 source map
productionSourceMap: process.env.NODE_ENV === 'production',
}

记得在环境变量中设置 SENTRY_AUTH_TOKEN

.env.local
SENTRY_AUTH_TOKEN=你的认证令牌

第四步:资源加载错误监控#

除了 JavaScript 运行时错误,资源加载失败也是常见问题。可以通过监听 windowerror 事件来捕获:

// 监听资源加载错误
window.addEventListener('error', (event) => {
if (event.target !== window) {
// 资源加载错误
Sentry.captureException(new Error(`Resource load error: ${event.target.src || event.target.href}`), {
tags: {
type: 'resource_error',
element: event.target.tagName.toLowerCase()
},
extra: {
src: event.target.src || event.target.href,
outerHTML: event.target.outerHTML
}
})
}
}, true)
// 监听 Promise 未捕获的错误
window.addEventListener('unhandledrejection', (event) => {
Sentry.captureException(event.reason, {
tags: {
type: 'unhandled_promise_rejection'
}
})
})

实战技巧:让 Sentry 更好用#

1. 合理设置采样率#

不要把采样率设置得太高,特别是在生产环境。100% 的采样率会产生大量数据,不仅消耗配额,还可能影响性能:

const sampleRate = process.env.NODE_ENV === 'production' ? 0.1 : 1.0

2. 过滤无用错误#

有些错误是无关紧要的,比如浏览器插件引起的错误、网络超时等。可以在 beforeSend 中过滤掉:

beforeSend(event, hint) {
// 过滤掉浏览器插件错误
if (event.exception && event.exception.values) {
const error = event.exception.values[0]
if (error.stacktrace && error.stacktrace.frames) {
const frames = error.stacktrace.frames
if (frames.some(frame => frame.filename && frame.filename.includes('extension://'))) {
return null
}
}
}
return event
}

3. 添加上下文信息#

错误发生时,除了错误本身,上下文信息也很重要:

// 设置用户信息
Sentry.setUser({
id: user.id,
username: user.username,
email: user.email
})
// 设置标签
Sentry.setTag('page', 'checkout')
Sentry.setTag('feature', 'payment')
// 设置额外信息
Sentry.setExtra('orderInfo', orderData)
// 添加面包屑
Sentry.addBreadcrumb({
message: 'User clicked pay button',
category: 'ui',
level: 'info'
})

4. 自定义错误上报#

有时候需要主动上报一些业务错误:

// 上报简单错误
Sentry.captureMessage('Something went wrong', 'error')
// 上报异常
try {
riskyFunction()
} catch (error) {
Sentry.captureException(error)
}
// 上报带上下文的错误
Sentry.withScope((scope) => {
scope.setTag('section', 'payment')
scope.setLevel('warning')
scope.setContext('payment', {
amount: 100,
currency: 'USD'
})
Sentry.captureMessage('Payment processing slow')
})

5. 性能监控#

除了错误监控,Sentry 还支持性能监控:

// 手动创建事务
const transaction = Sentry.startTransaction({
name: 'API Call',
op: 'http'
})
try {
const response = await fetch('/api/data')
const data = await response.json()
transaction.setStatus('ok')
} catch (error) {
transaction.setStatus('internal_error')
Sentry.captureException(error)
} finally {
transaction.finish()
}

常见问题和解决方案#

1. Source Map 上传失败#

问题:构建时提示 Source Map 上传失败

解决方案

2. 错误信息不够详细#

问题:收到的错误信息太简单,无法定位问题

解决方案

3. 性能影响#

问题:担心 Sentry 影响应用性能

解决方案

4. 隐私问题#

问题:担心敏感信息被上报

解决方案

监控数据的分析和利用#

1. 错误趋势分析#

通过 Sentry 的仪表板,可以看到错误的趋势变化:

2. 用户影响分析#

了解错误对用户的影响:

3. 性能瓶颈识别#

通过性能监控数据:

4. 发布质量评估#

每次发布后:

团队协作和工作流#

1. 错误分配和处理#

2. 告警配置#

// 配置告警规则
{
"conditions": [
{
"name": "Error rate increase",
"threshold": "10%",
"timeWindow": "1h"
}
],
"actions": [
{
"type": "email",
"targets": ["dev-team@company.com"]
},
{
"type": "slack",
"channel": "#alerts"
}
]
}

3. 与 CI/CD 集成#

在部署流程中集成 Sentry:

写在最后#

Sentry 确实是个好工具,但它不是万能的。监控系统只是帮你发现问题,真正解决问题还是要靠扎实的技术功底和细心的分析。

我的建议是:

  1. 早接入:越早接入,越早受益
  2. 细配置:花时间做好配置,后面省心很多
  3. 勤分析:定期查看监控数据,主动发现问题
  4. 重隐私:注意保护用户隐私,不要上报敏感信息

最后,记住一句话:监控不是为了监控而监控,而是为了让用户有更好的体验。当你的应用稳定运行,用户用得开心的时候,你就知道这些努力都是值得的。

有什么问题欢迎在评论区讨论,大家一起进步!