vue3 vite 项目接入 sentry监控

112 阅读6分钟

Sentry 配置文档

本文档详细说明了项目中 Sentry 错误监控和性能追踪的完整配置。

目录

概述

本项目使用 Sentry 进行错误监控和性能追踪,主要功能包括:

  1. 错误监控:自动捕获和上报 JavaScript 错误
  2. Sourcemap 上传:自动上传 sourcemap 文件,便于调试生产环境错误
  3. Release 管理:自动关联 Git 提交记录
  4. 用户追踪:关联错误与用户信息
  5. 性能监控:追踪应用性能指标

环境变量配置

必需的环境变量

.env.development.env.uat.env.production 等环境配置文件中,需要配置以下变量:

# 是否启用 Sentry(true/false)
VITE_SENTRY_ENABLE=true

# Sentry DSN(数据源名称)
VITE_SENTRY_DSN=https://xxx@sentry.io/xxx

# Sentry 组织名称
VITE_SENTRY_ORG=your-org

# Sentry 项目名称
VITE_SENTRY_PROJECT=your-project

# Sentry 认证 Token(用于上传 sourcemap)
VITE_SENTRY_AUTH_TOKEN=your-auth-token

环境变量说明

变量名说明必需默认值
VITE_SENTRY_ENABLE是否启用 Sentryfalse
VITE_SENTRY_DSNSentry 数据源名称-
VITE_SENTRY_ORGSentry 组织名称是(上传 sourcemap 时)-
VITE_SENTRY_PROJECTSentry 项目名称是(上传 sourcemap 时)-
VITE_SENTRY_AUTH_TOKENSentry 认证 Token是(上传 sourcemap 时)-
VITE_APP_VERSION应用版本号package.json 读取

构建时配置

1. Vite 配置 (vite.config.ts)

import { defineConfig, loadEnv } from 'vite'
import { getPluginsList } from './build/plugins'
import { version } from './package.json'

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), '')
  // 根据环境变量决定是否生成 sourcemap
  const isSentryEnabled = env.VITE_SENTRY_ENABLE === 'true'
  const shouldGenerateSourcemap = isSentryEnabled || mode === 'development'

  return {
    // ... 其他配置

    plugins: getPluginsList({ env, mode }),

    define: {
      // 注入版本号,供运行时使用
      'import.meta.env.VITE_APP_VERSION': JSON.stringify(version),
    },

    build: {
      // 根据环境变量决定是否生成 sourcemap
      // 如果 VITE_SENTRY_ENABLE 为 true,则生成 sourcemap 并上传到 Sentry
      // 开发环境始终生成 sourcemap 以支持断点调试
      // 使用 'hidden' 类型:生成 sourcemap 但不暴露在 JS 文件中(更安全)
      sourcemap: shouldGenerateSourcemap ? 'hidden' : false,
      // ... 其他构建配置
    },
  }
})

关键配置说明:

  • sourcemap: 'hidden':生成 sourcemap 文件但不暴露在 JS 文件中,更安全
  • define:注入版本号到 import.meta.env.VITE_APP_VERSION,供 Sentry 使用
  • shouldGenerateSourcemap:当 VITE_SENTRY_ENABLE=true 或开发环境时生成 sourcemap

2. Sentry 插件配置 (build/sentry.ts)

import type { PluginOption } from 'vite'
import { sentryVitePlugin } from '@sentry/vite-plugin'
import { version } from '../package.json'

interface CreateSentryPluginOptions {
  env?: Record<string, string>
  mode?: string
}

/**
 * 创建 Sentry 插件配置
 * @param options 配置选项
 * @returns Sentry 插件或 null
 */
export function createSentryPlugin(options: CreateSentryPluginOptions): PluginOption | null {
  const { env, mode } = options
  const isSentryEnabled = env?.VITE_SENTRY_ENABLE === 'true'
  if (!isSentryEnabled) return null

  const sentryAuthToken = env?.VITE_SENTRY_AUTH_TOKEN
  const sentryOrg = env?.VITE_SENTRY_ORG
  const sentryProject = env?.VITE_SENTRY_PROJECT

  if (!sentryAuthToken || !sentryOrg || !sentryProject) {
    console.warn(
      'Sentry sourcemap 上传已启用,但缺少必要的环境变量:VITE_SENTRY_AUTH_TOKEN、VITE_SENTRY_ORG 或 VITE_SENTRY_PROJECT',
    )
    return null
  }

  // 生成规范的 release 名称
  // 格式: home@version
  // 例如: home@1.0.0
  const releaseName = `home@${version}`

  return sentryVitePlugin({
    org: sentryOrg,
    project: sentryProject,
    authToken: sentryAuthToken,
    // 设置 release 名称
    release: {
      name: releaseName,
      // dist 用于区分同一 release 的不同部署环境(如 development、uat、production)
      dist: mode || 'unknown',
      // 自动关联 Git 提交信息,使 release 显示提交记录
      setCommits: {
        auto: true,
      },
    },
    // 上传 sourcemap
    sourcemaps: {
      // 上传所有 JS 文件和对应的 sourcemap 文件
      assets: './dist/**/*.{js,map}',
      ignore: ['node_modules'],
      // 上传后删除 sourcemap 文件,避免泄露源码
      // 注意:删除后 Sentry 仍能使用已上传的 sourcemap
      filesToDeleteAfterUpload: './dist/**/*.map',
    },
    // 禁用遥测数据
    telemetry: false,
  })
}

关键配置说明:

  • Release 名称:格式为 home@${version},例如 home@1.0.0
  • Dist:使用构建模式(mode)区分不同部署环境
  • 自动关联 Git 提交setCommits.auto: true 自动关联从上次 release 到当前的所有提交
  • Sourcemap 上传:上传所有 JS 和 map 文件,上传后删除本地 map 文件
  • 遥测数据telemetry: false 禁用遥测数据收集

3. 插件列表配置 (build/plugins.ts)

import { createSentryPlugin } from './sentry'
import type { PluginOption } from 'vite'

interface GetPluginsListOptions {
  env?: Record<string, string>
  mode?: string
}

export const getPluginsList = (options?: GetPluginsListOptions): PluginOption[] => {
  const { env, mode } = options || {}
  const plugins: PluginOption[] = [
    // ... 其他插件
  ]

  // 添加 Sentry 插件(如果启用)
  const sentryPlugin = createSentryPlugin({ env, mode })
  if (sentryPlugin) {
    plugins.push(sentryPlugin)
  }

  return plugins
}

运行时配置

Sentry 初始化 (src/sentry.ts)

import * as Sentry from '@sentry/vue'

export function initSentry(app) {
  const { MODE, VITE_SENTRY_DSN, VITE_SENTRY_ENABLE, VITE_APP_VERSION } = import.meta.env
  // 根据环境变量 VITE_SENTRY_ENABLE 判断是否启用 Sentry
  if (VITE_SENTRY_ENABLE !== 'true') return

  const dsn = VITE_SENTRY_DSN

  // release 名称
  // 格式: home@version
  // 例如: home@1.0.0
  const release = `home@${VITE_APP_VERSION}`

  Sentry.init({
    app,
    dsn,
    // 设置 release 名称,与构建时上传 sourcemap 的 release 保持一致
    release,
    // 设置 dist,与构建时上传 sourcemap 的 dist 保持一致
    // dist 用于区分同一 release 的不同部署环境
    dist: MODE,
    // 不同环境的分类
    environment: MODE,
    // 控制上报的百分比
    tracesSampleRate: 1,
    // Setting this option to true will send default PII data to Sentry.
    // For example, automatic IP address collection on events
    sendDefaultPii: false,
  })
}

/**
 * 设置 Sentry 用户信息
 * @param userInfo 用户信息对象,包含 id 和 username
 */
export function setSentryUser(userInfo?: { id?: string; username?: string }) {
  if (import.meta.env.VITE_SENTRY_ENABLE !== 'true') return

  if (userInfo?.id && userInfo?.username) {
    Sentry.setUser({
      id: userInfo.id,
      username: userInfo.username,
    })
  } else {
    // 清除用户信息
    Sentry.setUser(null)
  }
}

关键配置说明:

  • Release:必须与构建时上传 sourcemap 的 release 名称一致
  • Dist:必须与构建时上传 sourcemap 的 dist 一致
  • Environment:用于区分不同环境(development、uat、production)
  • tracesSampleRate:性能追踪采样率,1 表示 100% 采样
  • sendDefaultPii:是否发送默认 PII 数据(如 IP 地址),设置为 false 保护隐私

应用入口 (src/main.ts)

在应用入口文件中初始化 Sentry:

import { createApp } from 'vue'
import App from './App.vue'
import { initSentry } from './sentry'

const app = createApp(App)

// 初始化 Sentry(必须在其他初始化之前)
initSentry(app)

// ... 其他初始化代码

用户信息设置

用户 Store 集成 (src/stores/user.ts)

在用户登录和登出时自动设置/清除 Sentry 用户信息:

import { setSentryUser } from '@/sentry'

export const useUserStore = defineStore('user', {
  // ... state
  actions: {
    async load() {
      this.isLogin = !!getToken()
      if (this.isLogin) {
        // ... 获取用户信息

        // 设置 Sentry 用户信息
        const userId = (userInfo as UserInfoModel)?.userId
        const username = (userInfo as UserInfoModel)?.username
        if (userId || username) {
          setSentryUser({
            id: userId || '',
            username: username || '',
          })
        }
      } else {
        // ... 清除用户数据

        // 清除 Sentry 用户信息
        setSentryUser()
      }
    },
    async logout() {
      return logout().finally(() => {
        // ... 清除用户数据

        // 清除 Sentry 用户信息
        setSentryUser()

        // ... 其他清理操作
      })
    },
  },
})

使用说明:

  • 登录时:调用 setSentryUser({ id, username }) 设置用户信息
  • 登出时:调用 setSentryUser() 清除用户信息

文件结构

项目根目录/
├── build/
│   ├── sentry.ts          # Sentry 构建时配置(sourcemap 上传)
│   └── plugins.ts         # Vite 插件列表(包含 Sentry 插件)
├── src/
│   ├── sentry.ts          # Sentry 运行时配置(错误监控)
│   ├── main.ts            # 应用入口(初始化 Sentry)
│   ├── stores/
│   │   └── user.ts        # 用户 Store(设置用户信息)
│   └── types/
│       └── vite-env.d.ts  # 环境变量类型定义
├── vite.config.ts         # Vite 配置(sourcemap 生成)
└── package.json           # 项目配置(版本号)

配置说明

Release 命名规范

  • 格式home@${version}
  • 示例home@1.0.0
  • 说明:必须与构建时上传 sourcemap 的 release 名称一致

Dist 配置

  • 用途:区分同一 release 的不同部署环境
  • :使用构建模式(mode),如 developmentuatproduction
  • 说明:必须与构建时上传 sourcemap 的 dist 一致

Sourcemap 配置

  • 生成时机:当 VITE_SENTRY_ENABLE=true 或开发环境时
  • 类型hidden(生成但不暴露在 JS 文件中)
  • 上传:构建时自动上传到 Sentry
  • 删除:上传后自动删除本地 map 文件(避免泄露源码)

Git 提交关联

  • 配置setCommits.auto: true
  • 说明:自动关联从上次 release 到当前的所有 Git 提交
  • 用途:在 Sentry 后台查看 release 时可以看到关联的提交记录

使用指南

1. 启用 Sentry

在环境配置文件中设置:

VITE_SENTRY_ENABLE=true
VITE_SENTRY_DSN=https://xxx@sentry.io/xxx

2. 配置 Sourcemap 上传

在环境配置文件中设置:

VITE_SENTRY_ORG=your-org
VITE_SENTRY_PROJECT=your-project
VITE_SENTRY_AUTH_TOKEN=your-auth-token

3. 构建项目

# 开发环境构建
pnpm build:dev

# 生产环境构建
pnpm build:prod

构建时会自动:

  • 生成 sourcemap 文件
  • 上传 sourcemap 到 Sentry
  • 删除本地 sourcemap 文件

4. 验证配置

  1. 检查 Release:在 Sentry 后台查看是否有对应的 release
  2. 检查 Sourcemap:在 release 详情中查看是否有上传的 sourcemap 文件
  3. 检查提交记录:在 release 详情中查看是否有关联的 Git 提交
  4. 测试错误上报:在代码中手动触发一个错误,检查 Sentry 是否能正确捕获

5. 查看错误

在 Sentry 后台:

  1. 进入项目页面
  2. 查看 Issues 列表
  3. 点击错误查看详情
  4. 如果 sourcemap 配置正确,可以看到原始源代码的堆栈跟踪

常见问题

1. Sourcemap 未正确解析

问题:错误堆栈显示的是压缩后的代码,而不是源代码

解决方案

  • 检查 release 和 dist 是否与构建时一致
  • 检查 sourcemap 是否已上传到 Sentry
  • 检查 Sentry 后台的 release 详情中是否有 sourcemap 文件

2. 用户信息未关联

问题:错误报告中看不到用户信息

解决方案

  • 检查是否在登录时调用了 setSentryUser
  • 检查用户信息是否正确传递

3. 构建时警告

问题:构建时提示缺少环境变量

解决方案

  • 检查环境变量是否已正确配置
  • 如果不需要上传 sourcemap,可以设置 VITE_SENTRY_ENABLE=false

4. 历史错误未显示源代码

问题:上传 sourcemap 后,历史错误仍显示压缩后的代码

说明:这是正常现象,sourcemap 只对上传后的新错误生效

注意事项

  1. 安全性:sourcemap 文件包含源代码,上传后会自动删除本地文件
  2. 版本一致性:确保运行时和构建时的 release、dist 一致
  3. 环境变量:不同环境使用不同的环境变量配置文件
  4. 性能影响tracesSampleRate: 1 会追踪所有性能数据,生产环境建议降低采样率
  5. 隐私保护sendDefaultPii: false 不发送默认 PII 数据,保护用户隐私

相关链接