Skip to content

Latest commit

 

History

History
182 lines (134 loc) · 6.58 KB

03-observability.md

File metadata and controls

182 lines (134 loc) · 6.58 KB

可观测性:Sentry 与 Web Vitals

文档简介: 为上线后的应用装上仪表盘:Sentry 捕获并聚合运行时错误,Web Vitals 量化真实用户体验,并把 Query 错误流接入统一上报。

目标读者: 应用已上线或即将上线、需要线上问题预警的开发者

前置知识: Vercel 部署、SaaS 后台的错误处理

文档信息(用途、难度与维护记录)

📚 文档元数据

属性 内容
模块 03-tanstack-stack
象限 操作指南
难度 ⭐⭐⭐
标签 #sentry #web-vitals #监控 #可观测性
更新日期 2026年9月

🎯 完成后你将能够

  • 接入 Sentry:错误自动聚合、版本标注、source map 还原
  • 把 Query 的失败率变成可告警的指标
  • 采集 Core Web Vitals 并回传分析

1. Sentry 接入

npm install @sentry/react
// src/main.tsx(入口最上方,先于任何业务代码)
import * as Sentry from '@sentry/react'

Sentry.init({
  dsn: import.meta.env.VITE_SENTRY_DSN,
  environment: import.meta.env.MODE, // production / preview
  release: __APP_VERSION__,          // vite.config.ts 里 define 注入 package.json version
  integrations: [
    Sentry.browserTracingIntegration(),
    Sentry.replayIntegration({ maskAllInputs: true }), // 会话回放,输入脱敏
  ],
  tracesSampleRate: 0.2,  // 性能采样 20%,控制成本
  replaysSessionSampleRate: 0.01,
})
// vite.config.ts —— 注入版本号,让错误能对上发布的版本
export default defineConfig({
  define: {
    __APP_VERSION__: JSON.stringify(process.env.npm_package_version),
  },
})

source map:构建时生成、上传后从产物中删除——npx @sentry/wizard@latest -i sourcemaps -p vite 一条命令配置完成;错误堆栈即可还原到源码行。


2. Query 错误流接入上报

2.1 全局兜底

// src/shared/query-client.ts
import { QueryCache, MutationCache, QueryClient } from '@tanstack/react-query'
import * as Sentry from '@sentry/react'

export const queryClient = new QueryClient({
  queryCache: new QueryCache({
    onError: (error, query) => {
      // queryKey 是定位问题的关键上下文
      Sentry.captureException(error, {
        tags: { queryKey: JSON.stringify(query.queryKey), layer: 'query' },
      })
    },
  }),
  mutationCache: new MutationCache({
    onError: (error, _vars, _ctx, mutation) => {
      Sentry.captureException(error, {
        tags: { mutationKey: JSON.stringify(mutation.options.mutationKey ?? []), layer: 'mutation' },
      })
    },
  }),
})

注意:这是监控上报,与 SaaS 后台 中的用户提示(toast)互补——onError 里可以同时做 toast 与 captureException,但建议收敛到一个 reportError() 工具避免重复上报。

2.2 错误边界兜住渲染异常

import * as Sentry from '@sentry/react'

// 提供现成的 ErrorBoundary:渲染期异常自动上报
export const RouteErrorBoundary = Sentry.withErrorBoundary(PageComponent, {
  fallback: <ErrorPage />,
})

三层防线:queryCache.onError(数据请求失败)→ ErrorBoundary(渲染崩溃)→ window.onerror(全局残留),覆盖面才完整。


3. Web Vitals 采集

npm install web-vitals
// src/shared/vitals.ts
import { onCLS, onINP, onLCP, onTTFB, type Metric } from 'web-vitals'

function report(metric: Metric) {
  // 方案 A:发给自有分析端点
  navigator.sendBeacon?.('/api/vitals', JSON.stringify({
    name: metric.name,       // CLS | INP | LCP | TTFB
    value: metric.value,
    rating: metric.rating,   // good | needs-improvement | poor
    path: location.pathname,
    version: __APP_VERSION__,
  }))
}

onCLS(report); onINP(report); onLCP(report); onTTFB(report)

关注指标与 Query 的关系:

指标 与数据层的关联
LCP 首屏查询是否被 loader 预取覆盖
INP 交互后是否有意外的大范围 refetch 阻塞主线程
CLS placeholderData 缺失导致的表格塌陷抖动

4. 告警与复盘闭环

  • 告警规则:Sentry Alert 上配置"同 fingerprint 10 分钟内 > 5 次"通知(Slack/邮件);Web Vitals 的 poor 占比周环比上涨 20% 触发 review
  • 发版对照:每次 release 后观察 24h 新增 issue 数,回归错误立刻可见
  • 复盘路径:Sentry issue → 回放视频 → 复现 queryKey → 本地 Devtools 重放

🎨 最佳实践速查

错误记录要能定位到实际发布产物,因此 release 标识、构建产物和对应 source map 应一起归档。先制造一个可控错误,确认能还原到正确版本的源码位置,再认为错误采集已经接通。

采样率由流量、预算和排障需求决定,不预设所有项目必须使用某组百分比。客户端 DSN 通常是公开接入标识,但仍需防滥用与控制上报内容;会话回放尤其需要脱敏。一个错误可以同时有用户提示和诊断记录,但要集中管理,避免多个回调重复上报。


🔗 相关文档

练习与验收:区分一次业务失败与多次尝试

让一个查询前两次失败、第三次成功,记录 Network 请求数、Query 最终状态与上报事件数。预期界面最终恢复,不会为每次底层重试弹一个用户错误。再让全部尝试失败,确认上报含版本与可诊断上下文但不含秘密查询参数。验收还包括关闭采集服务后业务继续运行、上传对应 source map 后定位正确行;阈值应按自己的流量建立,不能直接复制示例数字。

以上是在个人或隔离测试环境中的练习,不是本轮已执行记录;实际运行范围见仓库文档质量报告。

阅读导航

本模块理解地图 · 完整目录与版本 · 通用术语