一、Sentry简介

Sentry 是一套开源的实时异常收集、追踪、监控系统,支持几乎所有的语音和平台。

这套系统由对应各种语言的 SDK 和一套庞大的数据后台服务组成,通过 Sentry SDK 的配置,可以上报错误关联的版本信息、发布环境。同时 Sentry SDK 会自动捕捉异常发生前的相关操作,便于后续异常追踪。最后,异常数据上报到数据服务之后,会通过过滤、关键信息提取、归纳展示在数据后台的 Web 界面中,功能架构如下图所示。

二、环境搭建

2.1 官方Sentry服务

Sentry项目是开源的,但是也提供付费版本,省去自己搭建和维护 Python 服务的麻烦。自己搭建的话,灵活性相对较高,可以做很多的定制化开发。首先,我们打开并登录官网注册账号。

2.2 私有化部署

Sentry 的管理后台是基于 Python Django 开发的。同时,这个管理后台需要用到 Postgres 数据库(管理后台默认的数据库)、ClickHouse(存数据特征的数据库)、relay、kafka、redis 等一些基础服务或由 Sentry 官方维护的总共 23 个服务支撑运行。如果独立的部署和维护这 23 个服务将是异常复杂和困难的,幸运的是,官方提供了基于docker 镜像的一键部署实现 getsentry/onpremise。所以,在私有化部署之前,我们需要在本地搭建Docker 和 Python 环境。需要说明的是,下面的所有私有化部署都是基于Linux系统环境的。下面是安装所需的一些软硬件环境。

  • Docker 19.03.6+
  • Docker-Compose 1.28.0+
  • 4 CPU Cores
  • 8 GB RAM
  • 20 GB Free Disk Space

2.3 安装docker

首先,我们在cenos服务器上安装一些工具软件,安装的命令如下。

yum install yum-utils device-mapper-persistent-data lvm2 -y

然后,我们将镜像源设置阿里的。

yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

接下来,我们使用yum命令安装docker。

yum install docker-ce docker-ce-cli containerd.io -y

然后,使用如下命令启动docker。

systemctl start docker# 设为开机启动systemctl enable docker

此处有一个小的Tip:在后续部署的过程中,需要拉取大量镜像,官方源拉取较慢,可以修改 docker 镜像源。首先,登录阿里云官网,打开 阿里云容器镜像服务。点击左侧菜单最下面的 镜像加速器 ,选择 Centos。

2.3.1 安装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

设置docker-compose执行权限。

chmod +x /usr/local/bin/docker-compose

再创建一个软链接。

sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

最后,测试一下是否安装成功。

$ docker-compose --versiondocker-compose version 1.22.0, build f46880fe

2.4 一键部署

git clone https://github.com/getsentry/onpremise

在 onpremise 的根路径下有一个 install.sh 文件,只需要执行此脚本即可完成快速部署,脚本运行的过程中,大致会经历以下操作:

  • 环境检查
  • 生成服务配置
  • docker volume 数据卷创建(可理解为 docker 运行的应用的数据存储路径的创建)
  • 拉取和升级基础镜像
  • 构建镜像
  • 服务初始化
  • 设置管理员账号(如果跳过此步,可手动创建)

然后在onpremise项目中执行一键部署命令

cd onpremise# 直接运行 ./install.sh 将 Sentry 及其依赖都通过 docker 安装./install.sh

安装的过程如下图所示。

设置管理员账号(如果跳过此步,可手动创建)。

2.5 启动项目

在执行结束后,会提示创建完毕,运行 docker-compose up -d 启动服务。

查看服务运行状态使用命令docker-compose ps。

2.6 访问项目

所有服务都启动成功后,就可以访问sentry后台了。后台默认运行在服务器的9000端口,登录的账户密码就是安装时设置的。

2.7 设置语言和时区

部署成功之后,我们可以进行一些设置。点击头像【User settings】 -【 Account Details】来设置语言何时区等。

三、Vue接入Sentry

3.1 创建Vue项目

首先,使用create命令创建Vue项目,如下所示。

npm i @vue/cli -g# 初始化vue2项目vue create vue2-sentry

3.2 接入sentry

首先,在项目中安装sentry插件。

# Using npmnpm install --save @sentry/vue @sentry/tracing

然后,在入口文件main.js中初始化sentry。

import Vue from "vue";import Router from "vue-router";import * as Sentry from "@sentry/vue";import { Integrations } from "@sentry/tracing";Vue.use(Router);const router = new Router({// ...});Sentry.init({Vue,dsn: "http://xdsdfafda21212@119.75.24.41:9000/2",integrations: [new Integrations.BrowserTracing({routingInstrumentation: Sentry.vueRouterInstrumentation(router),tracingOrigins: ["localhost", "my-site-url.com", /^//],}),],// 不同的环境上报到不同的 environment 分类// environment: process.env.ENVIRONMENT,// Set tracesSampleRate to 1.0 to capture 100%// of transactions for performance monitoring.// We recommend adjusting this value in production//高访问量应用可以控制上报百分比tracesSampleRate: 1.0,release: process.env.SENTRY_VERSION || '0.0.1', // 版本号,每次都npm run build上传都修改版本号});// ...new Vue({router,render: h => h(App),}).$mount("#app");

接着,我们手动模拟一个异常,然后就可以在sentry控制台捕获错误。

3.3 上传sourceMap到sentry

为了方便查看具体的报错内容,我们需要上传sourceMap到sentry平台。一般有两种上传方式:sentry-cli和sentry-webpack-plugin。source-map是什么呢?

  • 是一个文件,可以让已编译过的代码可以映射出原始源;
  • 是一个信息文件,里面储存着位置信息。也就是说,转换后的代码的每一个位置,所对应的转换前的位置。

在正式上传之前,我们需要在Vue项目中集成webpack-plugin插件,安装的命令如下:

npm i @sentry/webpack-plugin -D

接着,我们修改vue.config.js配置文件中的配置,示例如下。

const SentryCliPlugin = require('@sentry/webpack-plugin')module.exports = {// 打包生成sourcemap,打包完上传到sentry之后在删除,不要把sourcemao传到生产环境productionSourceMap: process.env.NODE_ENV !== 'development',configureWebpack: config=> {if (process.env.NODE_ENV !== 'development') {config.plugins.push(new SentryCliPlugin({include: './dist/js', // 只上传jsignore: ['node_modules', 'webpack.config.js'],ignoreFile: '.sentrycliignore',release: process.env.SENTRY_VERSION || '0.0.1', // 版本号cleanArtifacts: true, urlPrefix: '~/js', //线上对应的url资源的相对路径 }),)}},}

为了能够正常的进行上报,我们需要在sentry后台获取TOKEN。

然后再配置org组织名称。并在项目根目录创建.sentryclirc文件,配置如下内容。

# .sentryclirc[auth]token=填入控制台创建的TOKEN[defaults]url=https://sentry.io/org=sentryproject=vue
  • url:sentry部署的地址,默认是https://sentry.io/
  • org:控制台查看组织名称
  • project:项目名称
  • token:生成token需要勾选project:write项目写入权限

当我们再次执行npm run build项目打包命令的时候,就可以把js下的sourcemap相关文件上传到sentry。正确上传过 source-map 的项目,可以看到很清晰的报错位置。进入本地打包的dist,http-server -p 6002 启动一个模拟正式环境部署的服务访问看看效果。

需要说明的是,记得不要把sourcemap文件传到生产环境,因为又大又不安全。通常,在生产环节删除sourcemap有如下三种方式。

// 方式1"scripts": {"build": "vue-cli-service build && rimraf ./dist/js/*.map"}// 方式2 单独生成map// vue.config.jsconfigureWebpack(config) { config.output.sourceMapFilename('sourceMap/[name].[chunkhash].map.js') config.plugin('sentry').use(SentryCliPlugin, [{include: './dist/sourceMap', // 只上传jsignore: ['node_modules'],configFile: 'sentry.properties',release: process.env.SENTRY_VERSION || '0.0.1', // 版本号,每次都npm run build上传都修改版本号cleanArtifacts: true, // 先清理再上传}])}// 方式3 webpack插件清理$ npm i webpack-delete-sourcemaps-plugin -D// vue.config.jsconst { DeleteSourceMapsPlugin } = require('webpack-delete-sourcemaps-plugin')configureWebpack(config) {config.plugin.push(new DeleteSourceMapsPlugin(), // 清理sourcemap)}

3.4 Performance分析

除了捕捉错误外,Sentry还可以收集一些页面性能方面的数据。Sentry.init() 中,new Integrations.BrowserTracing() 的功能就是将浏览器页面加载和导航检测作为事物,并捕获请求和其他性能指标。

常见的性能数据指标有如下一些:

  • TPM: 每分钟事务数;
  • FCP:首次内容绘制(浏览器第第一次开始渲染 dom 的时间点);
  • LCP:最大内容渲染,代表 viewpoint 中最大页面元素的加载时间;
  • FID:用户首次输入延迟,可以衡量用户首次与网站交互的时间;
  • CLS:累计布局偏移,一个元素初始时和消失前的数据;
  • TTFB:首字节时间,测量用户浏览器接收页面的第一个字节的时间(可以判断缓慢来自网络请求还是页面加载问题);
  • USER:uv 数字;
  • USER MISERY: 对响应时间难以忍受的用户指标,由 sentry 计算出来,阈值可以动态修改;

四、React接入Sentry

我们使用umi项目接入sentry进行演示。首先,我们创建一个基于umi的React项目。

mkdir umi-sentry && cdumi-sentryyarn create umi

然后,我们在项目中安装sentry插件。

npm install --save @sentry/react @sentry/tracing

4.1 接入sentry

首先,我们在React项目的入口文件index.ts中初始化sentry,示例如下。

import * as Sentry from "@sentry/react";import { BrowserTracing } from "@sentry/tracing";Sentry.init({dsn: "https://xdfa@o1334810.ingest.sentry.io/121",integrations: [new BrowserTracing()],release: '0.0.1',tracesSampleRate: 1.0,});

接着,我们手动触发一个异常,看是否能正确上报到sentry。

4.2 上传sourcemap

首先,在根目录创建配置文件 .sentryclirc,然后配置如下选项。

[auth]token=TOKEN控制台获取,TOKEN需要勾选project:write写入权限[defaults]url=https://sentry.io/ // 默认地址org=组织名称,控制台获取project=react // 项目名称

接着,我们再安装sourcemap配置上传插件。

npm i @sentry/webpack-plugin -D

然后,在.umirc.ts文件中添加如下配置。

const SentryPlugin = require('@sentry/webpack-plugin');export default {devtool: process.env.NODE_ENV === 'production' " />

执行打包上传sourcemap。进入dist文件,启动http-server 本地服务模拟线上效果。

需要说明的是,在执行npm run build打包操作后,不要把sourcemap上传到生产环境,记得删除。

五、其他用法

5.1 识别用户

在上传的 issues 里面,我们可以借助 setUser 方法,设置读取存在本地的用户信息,比如。

Sentry.setUser({id: 'dfar12e31', // userId cookie.get('userId')email: 'test@qq.com', // cookie.get('email')username: 'poetry', // cookie.get('username')})Vue.prototype.$Sentry = Sentry

5.2 错误边界

sentry支持定义错误边界,当组件报错的时候,可以上报相关信息。使用 Sentry.ErrorBoundary添加错误边界,可以把错误定位到组件上面。

5.3 rrweb错误复现

使用rrweb,我们可以复现错误产生的路径。首先,我们需要安装rrweb插件。

npm i @sentry/rrweb rrweb -S

然后,在入口文件中进行如下的一些配置。

import SentryRRWeb from '@sentry/rrweb';// app/main.jsSentry.init({Vue,dsn: "xxx",integrations: [new Integrations.BrowserTracing({routingInstrumentation: Sentry.vueRouterInstrumentation(router),tracingOrigins: ["localhost", "my-site-url.com", /^//],}),new SentryRRWeb({checkoutEveryNms: 10 * 1000, // 每10秒重新制作快照checkoutEveryNth: 200, // 每 200 个 event 重新制作快照maskAllInputs: false, // 将所有输入内容记录为 *}),],... });

接着,我们就可以在sentry后台看到错误的json数据。

5.4 手动报警提示

有时候,我们可以通过提醒等功能来帮助我们即时发现问题,可设置的提醒的选项也有很多。