sentry升级及告警接入

661 阅读4分钟

sentry 升级

因为在sentry的22.10.0的版本中存在告警无法被错误事件trigger的bug,(上报的错误和告警关联不起来,导致告警无法触发)。因此需要更换sentry版本

  • 1: 运行一下命令
  • git clone github.com/getsentry/s…
  • git checkout 21.12.0
  • ./install.sh
  • docker-compose stop
  • docker-compose build
  • docker-compose up -d
  • 2: 配置sentry邮箱
  • 首先申请一个sentry用的邮箱
  • 找到sentry/config.yml配置申请的邮箱 image.png
  • 3: 配置邮箱中错误邮件点击的跳转路径
  • 找到sentry/config.yml配置申请的邮箱 image.png
  • 4: 重启sentry
  • docker-compose stop
  • docker-compose build
  • docker-compose up -d

线上错误类型分类

  • Js 执行错误
  • 加载网络资源报错报错

1: 项目自身资源加载错误

2: 第三方资源(sdk等)加载错误

  • Ajax请求报错

1: 网络层面或服务层面的错误(404, 503等)

2: 业务层面的响应错误(比如response返回的success为false)

  • Promise错误
  • Try catch 错误
  • 框架层面错误

sentry能覆盖到的错误

  • Js 执行错误(可以搜集到)
  • 加载网络资源报错报错(可以搜集到)
  • Ajax请求报错

1: 网络层面或服务层面的错误(404, 503等)(待研究,配置还没有生效)

2: 业务层面的响应错误(需要引入sentry sdk进行自定义上报)

  • Promise错误

1: 被catch的错误无法捕获(需要引入sentry sdk进行自定义上报)

2: 未被catch的错误可以捕获

  • Try catch 错误 (捕获不到,需要引入sentry sdk进行自定义上报)
  • 框架层面错误
  • vue
  • Vue.config.errorHandler,@sentry/vue默认开启Vue.config.errorHandler的错误上报
  • react
  • componentDidCatch
  • static getDerivedStateFromErrorgetDerivedStateFromError更多用于监控页面白屏)*

总结:有5种情况需要使用sentry sdk进行自定义上报

1: 网络层面或服务层面的错误(404, 503等)

2: 业务层面的响应错误(需要引入sentry sdk进行自定义上报)

3: 被promise catch的错误(sentry监控不到,需要引入sentry sdk进行自定义上报)

4: 被Try catch 捕获的错误 (sentry监控不到,需要引入sentry sdk进行自定义上报)

5: 框架内部执行错误 (根据配置,默认不需要引入sentry sdk进行自定义上报)

报错后如何跟踪请求链路

  • 初始化sentry.init时开启traceFetch和traceXHR会在每个请求上带上traceId,便于整个请求链路的跟踪
integrations: [
    new BrowserTracing({
      routingInstrumentation: Sentry.vueRouterInstrumentation(router),
      tracingOrigins: [
        'localhost',
        'localhost:3000',
        'api.***.com',
        'api-test.****.com',
        /^\//,
      ],
      traceFetch: true,
      traceXHR: true,
    }),
  ],

sourcemap如何上传

  • 1: 生成authToken

image.png

  • 2: 以vite打包为例
import type { ViteSentryPluginOptions } from 'vite-plugin-sentry'
import viteSentry from 'vite-plugin-sentry'

  const env = loadEnv(mode, process.cwd())
  const isProduction = env.VITE_PROJECT_SERVER === 'production'

  const sentryConfig: ViteSentryPluginOptions = {
    url: 'https://sentry.xxx.xx', // 私有部署的sentry服务域名
    authToken: '******', // sentry中生成的api密钥,上一步中生成的authToken
    org: 'org-name', // sentry中的组织名称
    project: 'project-name', // sentry中的项目名称
    release: env.VITE_PROJECT_RELEASE, // 当前发布的版本号(注意:需要与sentry.init中的版本号保持一致)
    deploy: {
      env: 'production',
    },
    skipEnvironmentCheck: true,
    setCommits: {
      auto: true,
    },
    sourceMaps: {
      include: ['./dist/assets'],
      ignore: ['node_modules'],
      urlPrefix: '~/assets',
    },
  }
  return defineConfig({
    plugins: [
      isProduction ? viteSentry(sentryConfig) : null,
    ],
    build: {
      sourcemap: 'hidden',
    },
  })

sentry sdk接入

import * as Sentry from '@sentry/vue'
import { BrowserTracing } from '@sentry/tracing'

Sentry.init({
  app,
  release: import.meta.env.VITE_PROJECT_RELEASE, // 必须和vite构建时viteSentry传入的版本号一致
  dsn: 'https://****@sentry.****.****/1', // sentry服务中项目的
  environment: import.meta.env.VITE_PROJECT_SERVER,
  // enabled: import.meta.env.VITE_PROJECT_SERVER === 'production',
  enabled: true,
  integrations: [
    new BrowserTracing({
      routingInstrumentation: Sentry.vueRouterInstrumentation(router),
      tracingOrigins: [ // ajax请求是允许sentry跟踪添加traceId的域名
        'localhost',
        'localhost:3000',
        'api.***.com',
        'api-test.****.com',
        /^\//,
      ],
      traceFetch: true,
      traceXHR: true,
    }),
  ],
  tracesSampleRate: 1.0,
})

使用sentry sdk实现自定义上报

很多情况下我们需要对上报的告警做分类,所以可以引入sentry 的sdk进行自定义上报,并给不同类型的报错打标签

import * as Sentry from '@sentry/vue'
import type { SeverityLevel } from '@sentry/vue'
import type { CaptureContext, Contexts } from '@sentry/types'
import { getRealName } from './index'

export enum Tags {
  netError = 'net-error', //  网络错误
  frameError = 'frame-error', // 框架内部执行错误
  promiseError = 'promise-error', //  promise catch捕获的错误
  tryCacheError = 'try-cache-error', //  try catch捕获的错误
  httpBusinessError = 'http-business-error', // 接口响应错误
}

Sentry.setTags({
  netError: Tags.netError,
  frameError: Tags.frameError,
  promiseError: Tags.promiseError,
  tryCacheError: Tags.tryCacheError,
  httpBusinessError: Tags.httpBusinessError,
})

interface PARAMS_TYPE {
  data: any
  tag: Tags
  error: any
  url: string
  status: number
  baseURL: string
  statusText: string
  level?: SeverityLevel
}

export const pointerLog = (params: PARAMS_TYPE) => {
  const {
    baseURL,
    url,
    status,
    statusText,
    tag,
    level = 'error',
    data = {},
  } = params || {}
  Sentry.captureException(
    new Error(`${baseURL}${url} (${statusText}${status})`),
    (scope) => {
      const userName = getRealName() || ''
      scope.clear()
      // 设置用户信息:
      scope.setUser({ user: userName })
      // 给事件定义标签:
      scope.setTag(tag, tag)
      // 设置事件的严重性:
      scope.setLevel(level)

      // 设置附加数据:
      scope.setExtra('data', { data })

      return scope
    },
  )
}

在需要使用自定义上报错误的地方引入pointerLog,并给不同的错误打上标签

创建告警

  • 1: 根据自定义标签创建告警

image.png 在if中过滤中需要告警的标签,发送到webhook

  • 2: 也可以自己定义指标搜集告警

image.png

将告警推送到飞书机器人(webhook)

注意

若是上传sourcemap遇到413的错误,则说明nginx限制了上传文件的大小

  • 修改nginx配置文件client_max_body_size 100M,或更大重启nginx就行。

因为nginx也是sentry安装包中集成的,都是用docker部署,所以重启sentry也可以

  • 重启sentry
  • docker-compose stop
  • docker-compose build
  • docker-compose up -d