1

背景

当我们开发的系统上线之后,需要对其运行状况进行监控。因为测试往往不可能覆盖所有可能出现的异常,用户也不一定会完全按照理想的方式去操作我们的系统,上游数据返回非预期可能也会导致触发一些异常。

对于后端应用,我们一般会通过日志的方式去发现和定位问题(比如 level 为 ERROR 的日志,响应状态码为非正常状态码的日志)。
对于前端代码,因为运行在用户端,如果出现一些 JS 运行时的异常,如果没有上报措施和用户反馈,那么这个错误可能就永远被忽略了。如果错误已经严重到影响到多数用户的使用,可能会有用户反馈,这时也会出现反复沟通确认,复现过程复杂。

对于系统运行中的异常,我们总是希望能够尽早发现,快速定位和解决,从而让异常影响到更少的用户。Sentry 是一套开源的错误上报和应用性能监控平台,适用于各类主流语言开发的应用。很早之前就听说过 Sentry,20 年下半年尝试在一些应用上进行了使用。本文主要介绍 Sentry 的基本概念、在前后端应用(Vue/Django)中接入的过程,以及它在错误上报、管理和应用性能监控上的基本使用。

Sentry 提供了 SaaS 服务和本地部署两种方式,两种方式主要功能上没有区别(SaaS服务当使用的量大了需要付费)。对于企业应用如果不希望代码外泄那一般采用本地部署方式。

Sentry 接入

Vue 应用接入主要步骤

  1. 创建项目,选择 Browser Tab 选择 Vue 应用。
    image.png
  2. 接下来就有简单的接入指南。

    • 实现错误和性能数据上报需要安装以下三个包,如果不想启用性能监控直接上面两个包即可。

      • @sentry/browser (Sentry's core browser SDK)
      • @sentry/integrations (contains Sentry's Vue integration)
      • @sentry/tracing (instruments performance data)
    • 按照 npm 包之后在main.js 中进行 Sentry 的初始化

      // main.js
      // 配置仅在正式环境中启用
      if (process.env.VUE_APP_ENV === 'production') {
          Sentry.init({
              // data source name
              dsn: 'xxxxx',
              integrations: [
                  new VueIntegration({
                      Vue,
                      // 开启性能监控
                      tracing: true
                  }),
                  new Integrations.BrowserTracing()
              ],
              // 设置性能监控采样率
              tracesSampleRate: 0.2,
              // 我们正式环境又部分了两套,这里用了 vue 的环境变量进行区分
              environment: process.env.VUE_APP_REGION_ENV,
              // 应用的版本,错误上报时会携带,可以区分上报的数据是出于哪个版本的代码
              release: `${process.env.VUE_APP_VERSION}-${process.env.VUE_APP_REGION_ENV}`
          })
      
          Vue.prototype.$sentry = Sentry
      }
    • 我们希望在上报的数据中包含用户信息(可以查看用户操作行为,当出现异常时还可以主动联系用户),在 Vuex actions 中获取到用户信息的逻辑中主动进行设置

      // src/store/modules/user.js
          // 设置sentry中的上下文
          setSentryInfo({ commit, state }) {
              return new Promise((resolve, reject) => {
                  this._vm.$sentry.configureScope(scope => {
                      scope.setUser({
                          username: state.name
                      })
                  })
                  resolve()
              })
          },
          // 获取用户信息
          getUserInfo(...省略) {
              return new Promise((resolve, reject) => {
                  getUserInfo(...省略).then(response => {
                      ...
                      // 当前 vue 实例 sentry 属性,设置 user 信息
                      if (this._vm.$sentry) {
                          dispatch('setSentryInfo')
                      }
                      ...
                      resolve(data)
                  }).catch(error => {
                      reject(error)
                  })
              })
          },
  3. 上传 sourcemap。由于现在前端工程化应用一般会对源代码进行混淆压缩。如果没有 sourcemap,那么上报的错误晦涩难懂,难以定位到源代码中的具体逻辑。

    // vue.config.js 配置 webpack 链式操作
    config
        .when(process.env.VUE_APP_ENV === 'production',
            config => {
                config
                    .plugin('@sentry/webpack-plugin')
                    .use(SentryWebpackPlugin, [{
                        authToken: 'xxxx',
                        org: 'xxx',
                        project: 'xx',
                        url: 'xxxx',
                        // webpack specific configuration
                        include: './dist',
                        // 上传的 sourcemap 的版本,配合 vue 中 sentry 的初始化
                        release: `${process.env.npm_package_version}-${process.env.VUE_APP_REGION_ENV}`
                    }])
                    .end()
            }
        )

实现基本的错误上报和应用性能监控上面的配置就够了。还有其他的一些更加丰富的设置,可以查看文档。Vue 接入文档

Django 应用接入主要步骤

和上面类似创建项目,然后选择 Django 应用。

  1. 安装 sentry_sdk pip包,在 setting.py 中初始化

    import sentry_sdk
    from sentry_sdk.integrations.django import DjangoIntegration
    sentry_sdk.init(
        dsn=os.environ.get('SENTRY_DSN'),
        integrations=[DjangoIntegration()],
        traces_sample_rate=1.0,
    
        # If you wish to associate users to errors (assuming you are using
        # django.contrib.auth) you may enable sending PII data.
        # 上报数据的使用用户信息,如果使用了 Django 自带的认证,可以开启,如果没有采用那么需要自己再另外配置 default personal identification info
        send_default_pii=True
    )
  2. 配置上报数据的用户信息,如果你是自己实现的认证逻辑,在认证逻辑代码中添加如下代码即可。

    from sentry_sdk import set_user
    set_user({'username': username})

除了在上报数据中添加识别用户信息,还可以丰富其他内容,可以查看 Django Enrich Events

Sentry 使用

基本术语

  • Event:应用端每次触发异常,就是一个 Event,会上报到 Sentry 中
  • Issue:Sentry 会对上报的异常按照一定的指纹算法进行 Group,(具体算法可以查看不同 SDK 的 Issue Group 文档,比如 Django Issue Grouping)相同的异常 event 会被归类到一个 Issue 下。

了解这两个基本概念之后,主要介绍一下 Sentry 的 Issue 和Performance。

Sentry Issue

Issue 列表和详情

下面以前端应用上报的数据举例。

  • Issue 列表

在异常列表,我们可以看到异常类型、异常名称、触发位置、首次触发时间、最近一次触发时间、最近 24/14d 该类异常触发图标走势、总触发此处、总触发的人数、该 Issue 指派跟进人
image.png

  • Issue 详情

在 Issue 详情页面,我们可以查看到这个 Issue 最近触发的 event 的具体信息,比如触发的环境、用户、报错的具体位置。同时如果这个 issue 触发了多次,可以在右上角点击进行该 Issue 下多次上报 event 数据的切换。
image.png
在详情的下方,我们还可以看到该 event 的时间的 Breadcrumbs。Breadcrumbs 是该异常触发之前的一些事件线索,我们可以参考该数据从而对该操作触发前的一些操作行为进行模拟,从而可以更加快速的复现和定位问题。(后端应用的话则是异常触发前的一些代码逻辑,如请求外部接口、查询数据库等)
image.png

我们还可以对Issue 进行管理,如指派跟进人、标识解决的版本、忽略,同时在该 Issue 的 Activity Tab 下也可以看到该 Issue 的一些动态。

报警

当异常触发后,我们希望可以尽快收到异常的相关告警。这个时候我们就可以设置 Alert。比如设置邮件或者 IM 告警(Github 有 DingDing 的插件),如果是企业内部的 IM 也可以去开发响应的插件。
image.png

Sentry Performance

除了错误上报,Sentry 也可用作应用的性能监控。
这里以后端应用为例。
image.png
在 Performance 列表我们可以看到不同接口的加载时长,TPM、50 线、95 线等数据,可以按照响应时长进行排序,从而可以评估我们不同接口的性能,对响应比较慢的接口进行优化。
在性能监控上报的 event 数据,可以查看到接口中代码的调用栈,发现其中各个步骤的调用时长。
image.png

其他常用高级使用方法

  1. 主动补货并上报错误
    有时我们可能需要自己去主动去触发一些错误上报,比如一些特定操作、某些已经被弃用的接口被调用了、捕获一些线上运行数据去排查问题。可以利用 Sentry 提供过的 captureException 或者 captureMessage 去上报错误或者文本信息。
  2. 丰富上报数据上下文
    除了刚刚我们介入过程中提到的 user 用户信息,还可以有tags、level、fingerprint、extra data。
    比如添加一些 tags,可以使用 scope.setTags(前端,不同语言语法不一样,如 Django 为 sentry_sdk.set_context) 可以给事件定义不同的键/值对。我们在后台查找的时候,筛选条件选项会多出来一些选项,就是通过 setTags 来设置的这些键值对。

总结

image.png
Sentry 为一套开源的错误上报和应用监控的解决方案。可以接入各类主流语言开发的应用提供,在异常上报之后,会进行过滤、按照一定的算法进行归类、集成丰富的环境和上下文信息,可以方便我们对异常的触发进行复现还原。

它不是传统日志、监控系统的替代品,它专注于应用的异常信息,从而让我们更快地发现问题、定位问题、解决问题,将异常尽早解决,从而影响更少的用户。同时性能监控数据,也可以为我们的应用优化提供方向。


Guixian
6 声望1 粉丝