Vue 3 与 Sentry 错误监控

概述

Sentry 是一款强大的错误监控和性能监控平台,用于实时捕获和分析应用中的错误和异常。它可以帮助开发者快速定位问题、了解错误发生的上下文、监控应用性能,并提供详细的错误报告。与 Vue 3 结合使用,可以全面监控 Vue 3 应用的运行状态,及时发现并修复问题,提高应用的可靠性和用户体验。本集将深入探讨 Sentry 的使用方法和最佳实践,帮助你构建可靠的 Vue 3 应用。

核心知识点

1. Sentry 基本概念

Sentry 提供了多种监控功能,包括:

  • 错误监控:捕获和分析应用中的错误和异常
  • 性能监控:监控应用的性能指标,如页面加载时间、API 请求时间等
  • 事务追踪:追踪请求的完整生命周期,包括前端和后端
  • 用户反馈:收集用户反馈,关联到具体的错误
  • 发布管理:跟踪错误与代码发布的关系
  • 警报:当错误发生时发送警报

2. Vue 3 与 Sentry 集成

2.1 安装 Sentry SDK

# 安装 Sentry SDK
npm install --save @sentry/vue @sentry/tracing

2.2 初始化 Sentry

// src/main.ts
import { createApp } from 'vue'
import { createRouter } from 'vue-router'
import * as Sentry from '@sentry/vue'
import * as Tracing from '@sentry/tracing'
import App from './App.vue'
import router from './router'

const app = createApp(App)

// 初始化 Sentry
Sentry.init({
  app,
  dsn: 'YOUR_SENTRY_DSN', // 替换为你的 Sentry DSN
  environment: import.meta.env.MODE, // 环境名称
  release: 'my-app@' + import.meta.env.VITE_APP_VERSION, // 版本号
  integrations: [
    // Vue 集成
    new Sentry.BrowserTracing({
      routingInstrumentation: Sentry.vueRouterInstrumentation(router),
      tracingOrigins: ['localhost', 'my-app.com', /^https:\/\/yourserver\.io\//]
    }),
    // 错误追踪集成
    new Sentry.Replay({
      maskAllText: false,
      blockAllMedia: false
    })
  ],
  // 性能监控采样率
  tracesSampleRate: 1.0,
  // 错误监控采样率
  sampleRate: 1.0,
  // 启用崩溃监控
  enableCrashes: true,
  // 启用调试模式
  debug: false
})

app.use(router)
app.mount('#app')

3. 错误捕获和处理

3.1 自动捕获错误

Sentry 会自动捕获以下类型的错误:

  • JavaScript 运行时错误
  • 未处理的 Promise 拒绝
  • 资源加载错误
  • Vue 组件错误

3.2 手动捕获错误

// src/utils/errorHandler.ts
import * as Sentry from '@sentry/vue'

// 手动捕获错误
export function captureError(error: Error, context?: any) {
  Sentry.captureException(error, {
    extra: context
  })
}

// 捕获消息
export function captureMessage(message: string, level?: Sentry.SeverityLevel) {
  Sentry.captureMessage(message, level)
}

// 设置用户信息
export function setUser(user: {
  id: string
  name?: string
  email?: string
}) {
  Sentry.setUser(user)
}

// 清除用户信息
export function clearUser() {
  Sentry.setUser(null)
}

// 设置标签
export function setTag(key: string, value: string) {
  Sentry.setTag(key, value)
}

// 设置上下文
export function setContext(name: string, context: any) {
  Sentry.setContext(name, context)
}

3.3 Vue 错误处理

// src/main.ts
import { createApp } from 'vue'
import * as Sentry from '@sentry/vue'

const app = createApp(App)

// 自定义 Vue 错误处理器
app.config.errorHandler = (err, vm, info) => {
  // 捕获 Vue 组件错误
  Sentry.captureException(err, {
    extra: {
      component: vm?.$options.name || 'anonymous',
      info
    }
  })
}

// 未处理的 Promise 拒绝处理
app.config.warnHandler = (msg, vm, trace) => {
  // 捕获 Vue 警告
  Sentry.captureMessage(`Vue Warning: ${msg}`, 'warning', {
    extra: {
      component: vm?.$options.name || 'anonymous',
      trace
    }
  })
}

4. 性能监控

4.1 页面加载性能

Sentry 会自动监控页面加载性能,包括:

  • 首次内容ful绘制时间(FCP)
  • 最大内容ful绘制时间(LCP)
  • 首次输入延迟(FID)
  • 累积布局偏移(CLS)
  • 可交互时间(TTI)

4.2 自定义性能监控

// src/utils/performanceMonitor.ts
import * as Sentry from '@sentry/vue'

// 开始性能追踪
export function startTransaction(name: string, operation: string, options?: any) {
  return Sentry.startTransaction({
    name,
    op: operation,
    ...options
  })
}

// 结束性能追踪
export function finishTransaction(transaction: any) {
  transaction?.finish()
}

// 追踪函数执行时间
export function traceFunction<T>(name: string, fn: () => T): T {
  const transaction = startTransaction(name, 'function')
  try {
    return fn()
  } finally {
    finishTransaction(transaction)
  }
}

// 异步函数追踪
export async function traceAsyncFunction<T>(name: string, fn: () => Promise<T>): Promise<T> {
  const transaction = startTransaction(name, 'async-function')
  try {
    return await fn()
  } finally {
    finishTransaction(transaction)
  }
}

4.3 API 请求追踪

// src/utils/api.ts
import axios from 'axios'
import * as Sentry from '@sentry/vue'

const api = axios.create({
  baseURL: '/api'
})

// 请求拦截器
api.interceptors.request.use(config => {
  // 开始 API 请求追踪
  const transaction = Sentry.startTransaction({
    name: `${config.method?.toUpperCase()} ${config.url}`,
    op: 'http.request'
  })
  
  // 将 transaction 存储到请求配置中
  config.headers['X-Sentry-Transaction'] = transaction
  
  return config
})

// 响应拦截器
api.interceptors.response.use(
  response => {
    // 结束 API 请求追踪
    const transaction = response.config.headers['X-Sentry-Transaction']
    if (transaction) {
      transaction.finish()
    }
    
    return response
  },
  error => {
    // 结束 API 请求追踪并捕获错误
    const transaction = error.config?.headers['X-Sentry-Transaction']
    if (transaction) {
      transaction.finish()
    }
    
    // 捕获 API 错误
    Sentry.captureException(error, {
      extra: {
        url: error.config?.url,
        method: error.config?.method,
        status: error.response?.status,
        data: error.response?.data
      }
    })
    
    return Promise.reject(error)
  }
)

export default api

5. 发布管理

5.1 配置发布版本

// package.json
{
  "name": "my-app",
  "version": "1.0.0",
  "scripts": {
    "build": "VITE_APP_VERSION=$(npm pkg get version | sed 's/\"//g') vite build"
  }
}

5.2 与 GitHub 集成

  1. 在 Sentry 中配置 GitHub 集成
  2. 启用发布自动化
  3. 在 GitHub Actions 中添加 Sentry 发布步骤
# .github/workflows/deploy.yml
name: Deploy

on: [push]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm install
      - run: npm run build
      - name: Create Sentry release
        uses: getsentry/action-release@v1
        env:
          SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
          SENTRY_ORG: your-org
          SENTRY_PROJECT: your-project
        with:
          environment: production
          sourcemaps: ./dist
          set_commits: 'auto'
      - name: Deploy to production
        # 部署步骤

6. 错误分组和优先级

Sentry 会自动将相似的错误分组,称为 "Issues"。你可以:

  • 为错误设置优先级
  • 分配错误给团队成员
  • 添加标签和注释
  • 设置解决状态
  • 创建自定义规则来自动处理错误

7. 自定义错误和事件

7.1 自定义错误类型

// src/utils/customErrors.ts
export class CustomError extends Error {
  constructor(message: string, public code: string, public metadata?: any) {
    super(message)
    this.name = 'CustomError'
  }
}

// 使用自定义错误
try {
  throw new CustomError('Something went wrong', 'ERR_CUSTOM', {
    additionalInfo: 'some info'
  })
} catch (error) {
  Sentry.captureException(error)
}

7.2 自定义事件

// src/utils/customEvents.ts
import * as Sentry from '@sentry/vue'

// 发送自定义事件
export function sendCustomEvent(eventName: string, data: any) {
  Sentry.captureEvent({
    message: eventName,
    level: 'info',
    extra: data
  })
}

// 跟踪用户交互
export function trackUserInteraction(action: string, data?: any) {
  sendCustomEvent(`user.interaction.${action}`, data)
}

// 跟踪页面视图
export function trackPageView(page: string, data?: any) {
  sendCustomEvent(`page.view.${page}`, data)
}

8. 环境和版本管理

8.1 环境配置

// src/main.ts
Sentry.init({
  environment: import.meta.env.MODE, // 开发、测试、生产等
  // ...
})

8.2 版本配置

// src/main.ts
Sentry.init({
  release: 'my-app@' + import.meta.env.VITE_APP_VERSION, // 版本号
  // ...
})

9. 与 CI/CD 集成

9.1 GitHub Actions 集成

# .github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm install
      - run: npm run test
      - name: Run Sentry CLI
        uses: getsentry/action-cli@v1
        env:
          SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
          SENTRY_ORG: your-org
          SENTRY_PROJECT: your-project
        with:
          command: "sourcemaps inject --org your-org --project your-project ./dist"

9.2 GitLab CI 集成

# .gitlab-ci.yml
build:
  stage: build
  script:
    - npm install
    - npm run build
    - npx @sentry/cli releases new $CI_COMMIT_TAG
    - npx @sentry/cli releases files $CI_COMMIT_TAG upload-sourcemaps ./dist
    - npx @sentry/cli releases finalize $CI_COMMIT_TAG
  only:
    - tags

最佳实践

1. 只在生产环境启用完整监控

在开发环境可以启用调试模式,但在生产环境应该优化采样率,减少性能开销:

Sentry.init({
  tracesSampleRate: import.meta.env.PROD ? 0.1 : 1.0,
  sampleRate: import.meta.env.PROD ? 0.1 : 1.0,
  // ...
})

2. 合理设置采样率

根据应用的流量和性能需求,合理设置采样率:

Sentry.init({
  tracesSampleRate: 0.1, // 10% 的性能追踪采样率
  sampleRate: 1.0, // 100% 的错误捕获采样率
  // ...
})

3. 关联用户信息

关联用户信息,便于定位和解决问题:

// 用户登录后
Sentry.setUser({
  id: user.id,
  name: user.name,
  email: user.email
})

// 用户登出后
Sentry.setUser(null)

4. 添加上下文信息

添加额外的上下文信息,便于分析错误:

Sentry.setContext('app', {
  version: import.meta.env.VITE_APP_VERSION,
  environment: import.meta.env.MODE
})

Sentry.setContext('user-agent', {
  browser: navigator.userAgent
})

5. 使用标签和优先级

使用标签对错误进行分类和过滤:

Sentry.setTag('component', 'UserProfile')
Sentry.setTag('feature', 'authentication')

6. 定期审查错误报告

定期审查 Sentry 中的错误报告:

  • 修复高频错误
  • 关注新出现的错误
  • 分析错误趋势
  • 跟踪错误解决进度

7. 与其他工具集成

将 Sentry 与其他工具集成,如:

  • Slack 或 Microsoft Teams 用于实时警报
  • Jira 或 GitHub Issues 用于错误跟踪
  • CI/CD 工具用于自动化发布管理

8. 优化性能开销

  • 减少采样率
  • 避免在生产环境启用调试模式
  • 优化自定义事件的发送频率
  • 使用 beforeSend 钩子过滤不必要的事件
Sentry.init({
  beforeSend(event) {
    // 过滤掉开发环境的错误
    if (event.environment === 'development') {
      return null
    }
    // 过滤掉特定类型的错误
    if (event.exception?.values?.[0]?.type === 'NetworkError') {
      return null
    }
    return event
  },
  // ...
})

常见问题和解决方案

1. Sentry 未捕获错误

问题:Sentry 未捕获到预期的错误

解决方案

  • 检查 Sentry DSN 是否正确配置
  • 检查浏览器控制台是否有 Sentry 相关错误
  • 确保 Sentry.init() 被正确调用
  • 检查采样率设置
  • 检查 beforeSend 钩子是否过滤了错误

2. 性能开销过大

问题:启用 Sentry 后应用性能下降

解决方案

  • 降低采样率
  • 禁用不必要的集成
  • 避免在生产环境启用调试模式
  • 优化自定义事件的发送频率

3. 错误信息不完整

问题:Sentry 报告的错误信息不完整

解决方案

  • 确保正确上传了 source maps
  • 检查 release 配置是否正确
  • 添加足够的上下文信息
  • 手动捕获错误时添加额外信息

4. 重复的错误报告

问题:Sentry 报告了大量重复的错误

解决方案

  • 检查错误分组规则
  • 优化错误处理逻辑,避免重复抛出相同的错误
  • 使用 ignoreErrors 配置过滤已知错误
Sentry.init({
  ignoreErrors: [
    'NetworkError',
    'Script error.',
    /^Error: Request failed with status code 401$/
  ],
  // ...
})

5. 本地开发环境无法连接到 Sentry

问题:本地开发环境无法连接到 Sentry

解决方案

  • 检查网络连接和防火墙设置
  • 确保 Sentry DSN 配置正确
  • 检查 CORS 配置
  • 在开发环境启用调试模式查看详细日志

进阶学习资源

  1. 官方文档

  2. 工具和库

  3. 最佳实践指南

  4. 学习案例

实践练习

练习 1:基础集成

  1. 创建一个 Vue 3 项目
  2. 集成 Sentry SDK
  3. 配置 Sentry 基本选项
  4. 测试错误捕获功能

练习 2:错误处理

  1. 实现自定义错误类型
  2. 手动捕获错误和消息
  3. 配置 Vue 错误处理器
  4. 测试不同类型的错误捕获

练习 3:性能监控

  1. 启用性能监控
  2. 配置事务追踪
  3. 实现 API 请求追踪
  4. 测试性能监控功能

练习 4:发布管理

  1. 配置版本管理
  2. 上传 source maps
  3. 与 GitHub Actions 集成
  4. 测试发布流程

练习 5:高级配置

  1. 配置采样率和环境
  2. 实现自定义事件
  3. 集成用户反馈
  4. 配置警报规则

总结

Sentry 是一款强大的错误监控和性能监控平台,与 Vue 3 结合使用可以全面提升应用的可靠性和用户体验。通过正确配置和使用 Sentry,你可以实时捕获和分析应用中的错误,监控应用性能,快速定位和修复问题。从基础集成到高级配置,Sentry 提供了丰富的功能和灵活的配置选项,帮助你构建可靠的 Vue 3 应用。

下一集我们将学习 Vue 3 与 LogRocket 用户行为分析,敬请期待!

« 上一篇 Vue 3与Lighthouse性能审计 - 全面性能评估与优化解决方案 下一篇 » Vue 3与LogRocket用户行为分析 - 全面用户体验优化解决方案