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

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

根本介绍

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

Sentry介绍与运用 - Issues模块

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

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

Issue & Event

在 Sentry 的产品逻辑里,一条日志叫 Event,内容相似的 Event 会被聚组成一个 Issue ,也便是咱们在界面上看到的Issues 列表。另外 Sentry 提出了“指纹”的概念,Sentry 会依据日志的仓库信息、异常类型和日志信息等去核算两条日志是否具有相同的指纹,具有相同指纹的 Event 会被聚组成一个 Issue 。

假如你想自行对 Event 进行合并,那么能够尝试以下办法:

  • 在 Issues 界面对 Issue 进行手动合并

Sentry介绍与运用 - Issues模块

  • 自界说指纹规则

[Project] > Settings > Issue Grouping > Fingerprint Rules

Sentry介绍与运用 - Issues模块

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

  • 日志上报时给日志加指纹
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 项目为例子,咱们需求安装的依靠包有:

"dependencies": {
    "@sentry/integrations": "^7.47.0", // 一些集成功用
    "@sentry/vue": "^7.47.0", // 获取sentry实例
}

然后咱们要在项目里界说一份 Sentry 的配置文件:

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

问题分类

Sentry介绍与运用 - Issues模块

  • 一切未处理的 ( 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有:

Sentry介绍与运用 - Issues模块

Sentry介绍与运用 - Issues模块

自界说查找假如存在多对 key:value ,那么只要满足一切 key:value 条件的 Issue 会被查找出来。

另外,自界说查找不能运用 OR 或许 AND 句子,可是能够运用 ! 句子:

Sentry介绍与运用 - Issues模块

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

Sentry介绍与运用 - Issues模块

当然咱们也能够自界说 tag ,然后用这些 tag 来查找:

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

Sentry介绍与运用 - Issues模块

SDK 在上报日志前会露出一个叫 beforeSend 的钩子,咱们能够在这个钩子里添加自界说的 tag 。

问题概况

咱们在 Issues 界面点开一条 Issue 就能够看到当时 Issue 最新上报的那条日志。

纵观整个 Issue 概况页,能够分为以下几个部分:

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

面包屑

启用面包屑的办法:

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

面包屑会主动记载的行为有:

  • console
  • dom 操作(比方点击元素)

Sentry介绍与运用 - Issues模块

  • Fetch 恳求

Sentry介绍与运用 - Issues模块

  • 浏览器路由跳转

Sentry介绍与运用 - Issues模块

  • Sentry 自身的行为(比方上报日志)
  • XHR 恳求

Sentry介绍与运用 - Issues模块

能够看到,网络恳求相关的用户行为,Sentry 只会主动记载 request_body_sizeresponse_body_size 两个字段。可是一般咱们更希望能够看到恳求的呼应头和呼应体,那么这时候咱们能够自行修正面包屑记载的数据:

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介绍与运用 - Issues模块

能够看到 Sentry 主动对回放内容做了敏感信息处理,咱们并不能经过回放看到用户在页面上填写的内容。

回放开始录制的办法:

// 第一种:在配置文件设置采样比例,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:

Sentry介绍与运用 - Issues模块

  1. 依据代码报错仓库定位报错的代码文件

Sentry介绍与运用 - Issues模块

依据报错仓库咱们能够知道是 jrpass-search.vue 文件的 search 办法呈现了过错。

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

  2. 指派修正人

Sentry介绍与运用 - Issues模块

  1. 修正完成后扭转问题状况

Sentry介绍与运用 - Issues模块