Skip to content

错误类型讲解:异常与监控

项目接入

前端

Vue

yarn add @sentry/vue @sentry/tracing 更详细的请查看 官网文档

2.x

javascript
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: 'https://138b35a0c5584646944565b51fa8a3f3@o1064497.ingest.xxxx.io/6055444',
  integrations: [
    new Integrations.BrowserTracing({
      routingInstrumentation: Sentry.vueRouterInstrumentation(router),
      tracingOrigins: ['localhost', 'my-site-url.com', /^\//],
    }),
  ],
  // Set tracesSampleRate to 1.0 to capture 100%
  // of transactions for performance monitoring.
  // We recommend adjusting this value in production
  tracesSampleRate: 1.0,
  // 添加用户崩溃反馈弹窗
  beforeSend(event, hint) {
    // Check if it is an exception, and if so, show the report dialog
    if (event.exception) {
      Sentry.showReportDialog({ eventId: event.event_id })
    }
    return event
  },
})

// ...

new Vue({
  router,
  render: (h) => h(App),
}).$mount('#app')

3.x

javascript
// yarn add @sentry/browser @sentry/tracing

import * as Sentry from '@sentry/browser'
import { Integrations } from '@sentry/tracing'

// init
Sentry.init({
  dsn: 'https://aabfe2180673babf842912aifd3863141519d@sentry.io/3806182',
  // 统计后台接口在前端的响应时间
  integrations: [new Integrations.BrowserTracing()],
})

React

yarn add @sentry/react @sentry/tracing

umijs 创建项目在 app.ts 中初始化 sentry.init 配置 更详细的请查看 官网文档

jsx
import React from 'react'
import ReactDOM from 'react-dom'
import * as Sentry from '@sentry/react'
import { Integrations } from '@sentry/tracing'
import App from './App'

Sentry.init({
  dsn: 'https://138b35a0c5584646944565b51fa8a3f3@o1064497.ingest.sentry.io/6055459',
  integrations: [new Integrations.BrowserTracing()],

  // Set tracesSampleRate to 1.0 to capture 100%
  // of transactions for performance monitoring.
  // We recommend adjusting this value in production
  tracesSampleRate: 1.0,
})

ReactDOM.render(<App />, document.getElementById('root'))

// Can also use with React Concurrent Mode
// ReactDOM.createRoot(document.getElementById('root')).render(<App />);

主动上报错误

有时候我们觉得它是个错误,但是sentry没这么认为,所以需要主动上报,这里sentry提供两个 API(captureException 与 captureMessage)

captureException:主动上报错误,这会触发系统内部钩子(webhooks) captureMessage:可以理解为埋点,不会触发系统内部钩子(webhooks),这里的 level: info

typescript
import * as Sentry from '@sentry/vue'

export type ISentry = typeof Sentry

class TrackError {
  public sentry?: ISentry

  constructor(sentry?: ISentry) {
    this.sentry = sentry
  }

  captureException(exception: any) {
    if (!this.sentry || !exception) return

    this.sentry.captureException(exception)
  }
}

export default TrackError

SourceMap

官网有三种做法如下:

  1. sentry 提供 webpack-plugin (链接)
  2. 脚手架工具 sentry-cli
  3. 直接调用 sentry API(有点麻烦,参数配置有点多)

这里介绍 @sentry/webpack-plugin 方式(方便接入现有 CI/CD)

.sentryclirc

[auth]
token=42b21a34ca654530af08			授权令牌,认证凭证token(Settings/Auth Tokens)

[defaults]
url = https://sentry.io/				上报 sentry 地址
org = ws-ap 										组织名称(Organization)
project = qv-h5									项目名称

vue.config.js

javascript
const SentryCliPlugin = require('@sentry/webpack-plugin')

module.exports = {
  // 开启 source map
  productionSourceMap: true,
  configureWebpack: (config) => {
    config.plugins.push(
      new SentryCliPlugin({
        include: './dist/',
        configFile: 'sentry.properties',
        // 版本(如果没有指定,sentry会自动创建 string 类型版本号),记得跟 init 版本一致sourceMap才会生效
        release: process.env.VUE_APP_PROJECT_RELEASE,
        ignore: ['node_modules'],
        urlPrefix: `${process.env.VUE_APP_COS_URL}/`,
      })
    )
  },
}

Tips

urlPrefix 可以为上传的 map 文件添加前缀,默认是 ~/sentry 需要根据 js 文件的 sourceMappingURL 来解析 map 文件路径,所以 SourceMap 级别不能用 hide-source-map 或者类似的。

很多人反馈错误没有定位到源码,很多就是错在这个配置(urlPrefix),这里解释下, 关于这个,是要看你项目的资源地址,比如,你前端访问页面是:http://test.com.cn/test/login,同时你的资源地址是:http://test.com.cn/test/dist/js/app.ecbb420f.js,那么,配置就应该是(urlPrefix~/test/(注意:非ip地址test)。 怎么看资源地址呢, 例如谷歌浏览器, F12控制台, 或者去 Application 里面找到对应资源打开。例如下图

image.png

再或者, 打开你的项目看看 build 下打的 assetsPublicPath 是什么,如果是:assetsPublicPath: '/test/',那你的 urlPrefix: '~/test/' 就是这个, 如果是 '/' ,那可以不配置,采用默认('~/')的即可。