线上出问题的时候,最难受的不是修不好,是不知道出了什么问题。用户截了张白屏的图发过来,你问他点了什么、什么浏览器、什么时候发生的,他说不清楚。你本地怎么点都复现不了。
Sentry 解决的就是这件事。它把线上抛出的每一个异常连同发生时的上下文一起收集回来,报错堆栈、用户操作路径、浏览器版本、当时的路由,全都有。配上 sourceMap 之后,压缩过的 a.b.c is not a function 能还原到你源码的具体某一行。
这篇是我把 Sentry 从零落到项目里的完整记录。包括自己在服务器上私有化部署整套服务,以及 Vue2、Vue3 加 Vite、React 加 umi 三套项目分别怎么接入、sourceMap 怎么传。踩过的坑我都标出来了,尤其是 sourceMap 那部分,配错一个字符就前功尽弃。
在本篇文章中,我们将从浅入深,和大家一起学习以下知识:
- Sentry 的架构长什么样,为什么它比自己写个
window.onerror上报强 - 官方 SaaS 和私有化部署怎么选,各自的代价是什么
- 用
onpremise一键脚本部署整套 Sentry 的完整流程和前置条件 - Vue2 项目接入
@sentry/vue,以及tracesSampleRate该设多少 - sourceMap 上传的两条路,以及
urlPrefix为什么是最容易配错的那一项 - sourceMap 传完之后必须从生产产物里删掉,三种删法
- Vue3 加 Vite 和 React 加 umi 两套配置的差异
setUser、错误边界、rrweb 录屏回放、报警规则这几个进阶能力
# 一、先搞清楚 Sentry 是什么
Sentry是一套开源的实时的异常收集、追踪、监控系统。这套解决方案由对应各种语言的 SDK 和一套庞大的数据后台服务组成,通过 Sentry SDK 的配置,还可以上报错误关联的版本信息、发布环境。同时 Sentry SDK 会自动捕捉异常发生前的相关操作,便于后续异常追踪。异常数据上报到数据服务之后,会通过过滤、关键信息提取、归纳展示在数据后台的 Web 界面中
这段介绍里最值得展开的是「自动捕捉异常发生前的相关操作」。
很多团队做异常监控的第一版都是自己在入口挂个 window.onerror 加 unhandledrejection,把错误信息 POST 到自家接口。这套东西能跑,但你拿到的只有一条错误消息和一个堆栈,然后就没了。用户在报错前点了哪几个按钮、发了哪几个请求、路由从哪跳到哪,全是空白。
Sentry 的 SDK 会在后台记录这些行为,叫做面包屑(Breadcrumbs)。异常发生的那一刻,它把最近的一串操作记录和错误一起打包上报。你在后台看到的不是一个孤立的错误,而是一条完整的时间线。这是自研方案很难补齐的部分。
我一直觉得,前端监控这件事真正的门槛不在采集,在于把采集到的东西组织成能定位问题的形态。Sentry 值钱的地方在后面这一半。
支持如下语言

这张图看一眼就行,重点是 Sentry 不只是前端工具。同一套后台可以同时接前端 JS、Node 服务、Python、Java、移动端,错误按项目区分。前后端在同一个平台看错误,联调时对时间线会方便很多。
sentry功能架构

功能层面从左到右是采集、处理、存储、展示、告警这几块。你在前端只需要关心最左边那一段,SDK 负责采集和上报,剩下的都是服务端的事。
sentry核心架构

这张图才是私有化部署要看的。图里那些 relay、kafka、ClickHouse、Postgres 就是后面部署时会拉起来的一堆容器。先看一眼有个印象,等下 docker-compose ps 打出来二十多个服务的时候就不会懵。
# 二、用官方 SaaS 还是自己部署
# 官方 Sentry 服务
sentry是开源的,如果我们愿意付费的话,sentry给我们提供了方便。省去了自己搭建和维护 Python 服务的麻烦事
登录官网 https://sentry.io 注册账号后接入sdk即可使用

注册完直接创建项目、拿 DSN、接 SDK,五分钟能跑通。官方有免费额度,个人项目和小团队试水完全够用。
那什么时候需要自己部署?我的判断标准就两条。一是数据不能出境,很多公司的合规要求卡这一条,那就只能自建。二是量大到免费额度撑不住,而付费又不划算。
除此之外我会优先选 SaaS。自建的隐性成本比想象中高很多,下面就知道了。
# Sentry 私有化部署
Sentry 的管理后台是基于
Python Django开发的。这个管理后台由背后的 Postgres 数据库(管理后台默认的数据库)、ClickHouse(存数据特征的数据库)、relay、kafka、redis 等一些基础服务或由 Sentry 官方维护的总共 23 个服务支撑运行。可见的是,如果独立的部署和维护这 23 个服务将是异常复杂和困难的。幸运的是,官方提供了基于 docker 镜像的一键部署实现 getsentry/onpremise
23 个服务这个数字要认真对待。它意味着这台机器以后就是专门跑 Sentry 的,别指望顺便再跑点别的。
sentry 本身是基于 Django 开发的,而且也依赖到其他的如 Postgresql、 Redis 等组件,所以一般有两种途径进行安装:通过 Docker 或用 Python 搭建
Python 那条路我劝你别走,依赖版本对齐能耗掉一整天。老老实实用 Docker。
前置环境
需要安装对应版本,否则安装会报错
Docker 19.03.6+Docker-Compose 1.28.0+4 CPU Cores8 GB RAM20 GB Free Disk Space
这四行是硬门槛,尤其是内存那条。8G 是最低要求不是推荐值,我拿 4G 的机器试过,install.sh 能跑完,但启动之后 ClickHouse 和 kafka 会互相抢内存,容器不断被 OOM kill 再重启,后台页面点两下就 502。别省这个钱。
磁盘 20G 也只是起步,Sentry 会持续写事件数据,跑一段时间之后要么加盘要么配数据保留策略。
# 三、私有化部署的完整流程
# 安装 docker 环境
安装工具包
yum install yum-utils device-mapper-persistent-data lvm2 -y

yum-utils 提供了下一步要用的 yum-config-manager 命令,另外两个是存储驱动的依赖。这一步基本不会出问题。
设置阿里镜像源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

执行完会在 /etc/yum.repos.d/ 下生成一个 docker-ce.repo。这里换的是下载 docker 程序的源,跟下一节的镜像加速不是一回事。
安装docker
yum install docker-ce docker-ce-cli containerd.io -y
装完检查一下版本,docker --version 输出必须满足前面说的 19.03.6 以上。CentOS 自带源里的 docker 包版本很老,这也是为什么要先换阿里源再装。
启动docker
systemctl start docker
# 设为开机启动
systemctl enable docker
enable 那行别漏,服务器重启之后 Sentry 全套服务要能自己起来。
# 镜像加速这一步不能跳
docker 镜像加速(重要)
在后续部署的过程中,需要拉取大量镜像,官方源拉取较慢,可以修改 docker 镜像源
原文标了「重要」两个字,我再加重一下。Sentry 这套要拉二十多个镜像,总体积好几个 G。不配加速的话,install.sh 很可能在拉镜像那一步卡到超时然后失败,而失败之后重跑又要从头再来一遍。这是整个部署流程里最耗时间也最容易崩的一环。
登录阿里云官网,打开 阿里云容器镜像服务。点击左侧菜单最下面的 镜像加速器 ,选择 Centos

这个页面会给你一个专属的加速地址,形如 https://xxxxxxxx.mirror.aliyuncs.com,每个账号不一样。别抄别人博客里的地址,那些多半已经失效了。
vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://l6of9ya6.mirror.aliyuncs.com"]
}
把里面那串换成你自己的。这个文件如果原来不存在,直接新建就行;如果已经有内容,注意保持 JSON 合法,多一个逗号 docker 就起不来了。
然后重启docker即可
# 重新加载配置
systemctl daemon-reload
# 重启docker
systemctl restart docker
改完一定要验证。docker info 的输出末尾有一段 Registry Mirrors,你配的地址出现在那里才算生效。这个我踩过,改完没验证直接跑安装脚本,等了四十分钟发现镜像一个都没下下来,回头才看到 JSON 格式写错了 docker 压根没加载。
# 安装 docker-compose
安装docker-compose
# 使用国内源安装
sudo curl -L "https://get.daocloud.io/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
注意这里下的是 1.29.2,前置条件要求 1.28.0 以上,这个版本是满足的。
设置docker-compose执行权限
chmod +x /usr/local/bin/docker-compose
创建软链
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
测试是否安装成功:
$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c
这里要提醒一下,原文这段输出贴的是 1.22.0,跟上面下载的 1.29.2 对不上,应该是从别的笔记里复制过来忘了改。真跑出 1.22.0 的话说明你系统里还有个旧版本抢在 PATH 前面,得先把它清掉,因为 1.22.0 不满足 Sentry 的前置要求,install.sh 会在环境检查那一步直接拒绝。
# 一键部署
git clone https://github.com/getsentry/onpremise
这个仓库名后来改成了 self-hosted,GitHub 会自动重定向,所以上面这条命令现在还能用,但新拉的话建议直接用 git clone https://github.com/getsentry/self-hosted。另外强烈建议 git checkout 到一个明确的版本 tag 再装,直接用主干代码容易碰上尚未稳定的改动。