Sentry介绍与使用 - Issues模块

这篇文章是我在公司做 Sentry 相关分享的演讲稿。

大家好,现在由我来讲解 Sentry 的 Issues (问题)模块。我会分为三个部分来讲,首先我会介绍 Sentry 一些重要的概念,然后讲一下 Issues 的基本使用方式,最后是 Issues 的基本实践。

基本介绍

在开始讲解前,我们先来眼熟一下 Issues 模块的界面。

当我们在菜单上选中 Issues(问题) 以后,就可以看到 Issues 界面。整个界面可以分为三个部分,分别是:

  • 不同状态 Issues 的 Tab切换
  • 筛选栏,用来筛选 Issues
  • Issues 列表

Issue & Event

在 Sentry 的产品逻辑里,一条日志叫 Event,内容相似的 Event 会被聚合成一个 Issue ,也就是我们在界面上看到的Issues 列表。另外 Sentry 提出了"指纹"的概念,Sentry 会根据日志的堆栈信息、异常类型和日志信息等去计算两条日志是否拥有同样的指纹,拥有同样指纹的 Event 会被聚合成一个 Issue 。

如果你想自行对 Event 进行合并,那么可以尝试以下方法:

  • 在 Issues 界面对 Issue 进行手动合并
  • 自定义指纹规则

[Project] > Settings > Issue Grouping > Fingerprint Rules

例如截图所示,所有错误类型为 ConnectTimeout 的 Event 都会得到一个叫 connect-timeout-type 的指纹,并且这些 Event 会被聚合到一个 Issue 下。

  • 日志上报时给日志加指纹
js 复制代码
Sentry.withScope(function (scope) {
    scope.setFingerprint(['aaatest'])
})
Sentry.init({
  // ...
  beforeSend(event, hint) {
    const error = hint.originalException;
    if (
      error &&
      error.message &&
      error.message.match(/database unavailable/i)
    ) {
      event.fingerprint = ["database-unavailable"];
    }
    return event;
  },
});

Sentry 对日志做 Issue 和 Event 维度的划分,我觉得好处在于:一般我们线上的 bug 会同时影响到很多用户,那么这些用户报上来日志量很大并且内容相似,Sentry 帮我们对相似日志做了一个聚合,这样我们能更快的筛选到我们想看的日志。

SDK的接入与使用

这里以 Web 端的 Vue 项目为例子,我们需要安装的依赖包有:

json 复制代码
"dependencies": {
    "@sentry/integrations": "^7.47.0", // 一些集成功能
    "@sentry/vue": "^7.47.0", // 获取sentry实例
}

然后我们要在项目里定义一份 Sentry 的配置文件:

js 复制代码
import Vue from 'vue'
import * as Sentry from '@sentry/vue'
import { Plugin } from '@nuxt/types'
import { HttpClient as HttpClientIntegration } from '@sentry/integrations'

const plugin: Plugin = (ctx) => {
  const { app, store } = ctx
  Sentry.init({
    // 项目设置里取
    dsn: '', // 如果传空或不传则不会上报任何 Sentry 错误
    Vue,
    environment: process.env.APP_ENV,
    // 上报日志前的钩子
    beforeSend(event: any) {
      return event
    },
    // 用户行为放入面包屑前的钩子
    beforeBreadcrumb(breadcrumb, hint) {
      return breadcrumb
    },
    integrations: [], // 一些集成功能
  })
}

export default plugin

问题分类

  • 所有未解决的 ( is:unresolved):所有未解决的问题
    • 新的(is:new):7天之内被创建的问题
    • 进行中的(is:ongoing):7天之前被创建的问题或者手动标记为已经看过的的问题
  • 待审查 ( is:unresolved is:for_review):还没有查看过的问题,待审查问题是所有未解决问题的子集。
  • 回归 ( is:regressed):解决了再次出现的问题。
  • 不断升级 ( is:escalating):当事件数量明显高于前一周时,sentry将问题定义为不断升级。
  • 已存档 ( is:archived):所有已存档的问题。

问题筛选

Issues 查询有4个筛选项,分别是项目、环境、日期和自定义。自定义通过 key:value 的的形式进行搜索。支持的key有:

自定义搜索如果存在多对 key:value ,那么只有满足所有 key:value 条件的 Issue 会被搜索出来。

另外,自定义搜索不能使用 OR 或者 AND 语句,但是可以使用 ! 语句:

除了上述的 key,Sentry 还内置了一些 tags 用来搜索:

当然我们也可以自定义 tag ,然后用这些 tag 来搜索:

js 复制代码
Sentry.init({
	beforeSend(event: any) {
		event.tags = {
  		...event.tags,
    	language: 'en-US'
  	}
  	return event
	}
})

SDK 在上报日志前会暴露一个叫 beforeSend 的钩子,我们可以在这个钩子里添加自定义的 tag 。

问题详情

我们在 Issues 界面点开一条 Issue 就可以看到当前 Issue 最新上报的那条日志。

纵观整个 Issue 详情页,可以分为以下几个部分:

  • 日志摘要
  • 代码报错堆栈
  • 面包屑
  • 回放(Replays)

面包屑

启用面包屑的方式:

js 复制代码
Sentry.init({
	integrations: [
      // 启用面包屑
      new Sentry.Integrations.Breadcrumbs({
        console: true
      })
  ],
})

面包屑会自动记录的行为有:

  • console
  • dom 操作(比如点击元素)
  • Fetch 请求
  • 浏览器路由跳转
  • Sentry 自身的行为(比如上报日志)
  • XHR 请求

可以看到,网络请求相关的用户行为,Sentry 只会主动记录 request_body_sizeresponse_body_size 两个字段。但是一般我们更希望可以看到请求的响应头和响应体,那么这时候我们可以自行修改面包屑记录的数据:

js 复制代码
Sentry.init({
  // ...
  beforeBreadcrumb(breadcrumb, hint) {
   if (breadcrumb.category === 'xhr' && breadcrumb.data) {
      breadcrumb.data.response = hint?.xhr.response
     	breadcrumb.data.responseHeaders = hint?.xhr.getAllResponseHeaders()
    }
    return breadcrumb;
  },
})

Sentry SDK会暴露一个叫 beforeBreadcrumb 的钩子,我们可以在这个钩子里对 Sentry 即将记录的用户行为做一些更改。beforeBreadcrumb 包含两个参数,第一个参数 breadcrumb 是 Sentry 已经整理好的一条面包屑数据,第二个参数 hint 则是 Sentry 额外采集到的一些数据。比如对于 XHR 请求,我们可以在 hint 参数里拿到 xhr 对象,这样我们就可以获取到请求的响应头和响应体。

回放(Replays)

回放是 Web 端独有的功能。回放并不是视频录制,而是把面包屑里的用户行为串起来,是对用户行为类似于视频的再现。

回放界面如下图所示,整个界面左半部分为回放,右半部分为用户行为列表:

可以看到 Sentry 自动对回放内容做了敏感信息处理,我们并不能通过回放看到用户在页面上填写的内容。

回放开始录制的方式:

js 复制代码
// 第一种:在配置文件设置采样比例,Sentry 自动录制
Sentry.init({
		integrations: [
    	new Sentry.Replay()
    ],
    // This sets the sample rate to be 10%. You may want this to be 100% while
    // in development and sample at a lower rate in production
    // 采样率
    replaysSessionSampleRate: 0.1,
    // If the entire session is not sampled, use the below sample rate to sample
    // sessions when an error occurs.
    // 错误采样率
    replaysOnErrorSampleRate: 1.0,
})

// 第二种:手动开始录制
replay.stary()

回放结束录制的方式:

  • 用户超过15分钟在页面上没有操作,则自动结束录制。
  • 录制时间超过60分钟,则自动结束录制。
  • 手动调用 replay.stop()

最佳实践

前面我们已经介绍了 Issues 模块的基本概念和使用方式,现在我们来看看在实际开发中,我们如何通过 Issues 模块去定位问题和解决问题。

不管是使用哪个监控系统,我们对项目异常的处理流程都是:找到异常对应的日志 --> 根据日志定位问题 --> 分配问题修复人 --> 解决问题。

比如现在我们有一个bug,在首页点击搜索的时候没有跳转到搜索结果页,那么我们需要用 Sentry 做以下事情:

  1. 根据问题发生的大概时间、报错信息以及自定义 tag 等筛选出对应的 Issue:
  1. 根据代码报错堆栈定位报错的代码文件

根据报错堆栈我们可以知道是 jrpass-search.vue 文件的 search 方法出现了错误。

  1. 根据面包屑找到出错数据的获取源头

  2. 指派修复人

  1. 修复完成后扭转问题状态
相关推荐
四岁半儿2 小时前
常用css
前端·css
你的人类朋友2 小时前
说说git的变基
前端·git·后端
姑苏洛言2 小时前
网页作品惊艳亮相!这个浪浪山小妖怪网站太治愈了!
前端
字节逆旅2 小时前
nvm 安装pnpm的异常解决
前端·npm
Jerry3 小时前
Compose 从 View 系统迁移
前端
GIS之路3 小时前
2025年 两院院士 增选有效候选人名单公布
前端
四岁半儿3 小时前
vue,H5车牌弹框定制键盘包括新能源车牌
前端·vue.js
烛阴3 小时前
告别繁琐的类型注解:TypeScript 类型推断完全指南
前端·javascript·typescript
gnip3 小时前
工程项目中.env 文件原理
前端·javascript
JefferyXZF4 小时前
Next.js Server Actions 详解: 无缝衔接前后端的革命性技术(八)
前端·全栈·next.js