AI 参与说明(Agent:Codex):本文以 Sentry 官方 SDK、CLI、MCP 与 Agent Skills 文档为主要依据,并用本机 Sentry CLI 0.41.0 校验文中的命令结构。本文给出的是前端与后端应用共用的配置和排障原则;SDK、CLI、套餐能力与控制台入口可能变化,实施前请按文末来源和当前版本复核,并审查数据采集范围。
先说结论:前端与后端通常建两个 Project#
对于绝大多数同时包含浏览器前端与服务端/后端的应用,推荐在同一个 Sentry Organization中创建两个 Project:一个接收浏览器数据,一个接收后端数据。这里的“后端”可以是 Node 服务、Serverless Function、Cloudflare Worker、BFF 或 SSR runtime;技术栈不改变这个边界。
| Sentry Project | 接收什么 | DSN 放在哪里 |
|---|---|---|
myapp-web(浏览器前端,例如 React) | 浏览器错误、浏览器结构化日志、前端性能数据、可选的 Replay | 浏览器构建时注入的公开配置,例如 VITE_SENTRY_WEB_DSN |
myapp-server(后端) | API/SSR/后台任务异常、服务端日志、服务端 trace | 服务端运行时的环境变量或 binding,例如 SENTRY_SERVER_DSN |
这不是“每个仓库必须有一个 Project”的规则。Sentry 将 Project 定义为错误归属、入站过滤、告警、所有权和 Issue 分组的边界,并明确建议:即使是单体代码库,也应把前端与后端分开;其 DSN 文档还直接以 React 前端与 Express 后端(即使同一 monorepo)为两个 Project、两个 DSN 的例子。Sentry Organization 指南 DSN 说明
flowchart TD B["浏览器\nSPA / hydration"] -->|"web DSN"| W["Sentry Project\nmyapp-web"] C["后端\nAPI · SSR · job"] -->|"server DSN"| S["Sentry Project\nmyapp-server"] B -->|"sentry-trace + baggage"| C W -. "同一 Organization\n同一 release / environment" .- S
两个 Project 不会妨碍浏览器请求与后端请求成为同一条分布式 trace。浏览器只应向自己的 API 域名传递 sentry-trace 和 baggage;跨域时还要在 CORS 中允许这两个 header。后端可以选择启用 strictTraceContinuation;该选项校验的是Organization ID而不是 Project ID,因此两个 Project 只要仍在同一 Organization 中即可安全续接 trace。Sentry 配置选项
何时可以先用一个 Project?#
小型个人项目、PoC,且浏览器和后端由同一人值守、使用同一套告警/脱敏/配额策略时,一个 Project 技术上可行。这是可运行的简化路径,不是项目划分的最佳默认值。
若这样做,至少给事件和日志设置稳定的 service/runtime 属性,分别标识 web 与 server。一旦需要不同的告警、值班人、PII 策略、Issue 分组或 source map 发布流程,就拆成两个 Project。
先配置这些 Sentry 通用边界#
1. DSN、环境与 release#
DSN 是事件上报地址,不是读取数据的凭据:浏览器的 VITE_SENTRY_WEB_DSN 可以公开;SENTRY_AUTH_TOKEN 则是上传 source map 或 release 的构建凭据,必须只存在于 CI/构建环境,不能进入浏览器 bundle 或后端 runtime。每个 Project 使用自己的 DSN。Sentry DSN 说明
不要为 production、staging、preview 再创建一套 Project。它们应使用同一组 Project、同一个 DSN,并通过一致的 environment 值筛选和告警;浏览器与后端应写入相同的、不可变的 release(通常是 Git SHA 或 CI build ID),这样 Sentry 才能把同一版本的错误、trace 和 source map 对齐。只有在数据权限、保留策略、配额或值班归属必须物理隔离时,才应另建 Project,此时才会产生新的 DSN。Sentry Environments
2. Errors、Logs、Tracing 与隐私#
- 错误事件通常保留完整采样;性能 trace、Replay 和日志应按流量、预算与关键路由独立采样,生产环境不要照抄
tracesSampleRate: 1。 enableLogs: true只启用 Sentry Logs。业务代码优先使用Sentry.logger.发送少量结构化日志;已有console.需要显式启用consoleLoggingIntegration,通常仅保留warn/error。- 采集配置是隐私边界。需审查 user、cookie、header、URL query、HTTP body 与日志字段;在
beforeSend/beforeSendLog中删除 token、密码和原始敏感数据。关闭某一类自动采集并不等于不再发送 PII。
3. 先保留原始异常,再转换成用户文案#
错误监控最常见的失效方式,不是 SDK 没有初始化,而是业务代码先把原始异常转换成了通用错误:TypeError、浏览器原生消息、cause 和原始栈在进入 Sentry 前已经丢失。UI 可以显示稳定、可翻译的错误码,但 Sentry 应收到转换前的异常。
try {
return await loadConversation();
} catch (error) {
const originalError =
error instanceof Error
? error
: new Error("Non-Error value thrown", { cause: error });
Sentry.withScope((scope) => {
scope.setTags({
operation: "conversation.history",
boundary: "api-client",
});
Sentry.captureException(originalError);
});
throw toUserFacingError(originalError);
}不要创建一个新的通用 Error(“Network request failed”),再手工复制旧 stack;这样 Sentry 的异常类型与消息仍然是假的。若确实要包装,使用 cause 保留异常链,并只在一个明确的失败边界上报,避免全局 SDK、Router ErrorBoundary 和业务 catch 重复创建三个 Issue。
异常消息也不应只允许少数精确字符串。正确策略是保留所有诊断消息,再对其中的秘密进行替换:Bearer/JWT、cookie、邮箱、URL query、认证 header 和高熵密钥替换为固定占位符;异常类型、清洗后的消息、栈和 cause 保留。清洗器必须集中维护,不能让各业务模块自己拼规则。
严格隐私场景可以直接删除自动附加的 request、extra 和 user,再显式上传少量安全上下文:
Sentry.init({
beforeSend(event) {
event.request = undefined;
event.extra = undefined;
event.user = undefined;
for (const value of event.exception?.values ?? []) {
value.value = sanitizeDiagnosticText(value.value);
}
if (event.logentry?.message) {
event.logentry.message = sanitizeDiagnosticText(event.logentry.message);
}
return event;
},
});推荐的安全关联字段包括 operation、boundary、稳定的 error_code、http_status、Sentry release,以及服务端生成并返回的 request_id。不要上传 Authorization、cookie、请求/响应正文、聊天内容、prompt、附件内容或带 query 的完整 URL。浏览器事件中的 event.request 往往描述当前页面,并不必然等于失败的 fetch;API 关联信息应由 transport 层显式加入规范化 operation/path 与 request ID。
4. SDK 脱敏不是最后一道防线#
浏览器 DSN 可以公开,但仍可能被滥用制造垃圾事件;客户端清洗代码也可能因某次发布失效。因此还应在 Sentry 项目侧配置纵深防御:
- Allowed Domains:限制浏览器事件允许的来源域名;通常位于 Project Settings 的 Client Keys(DSN)设置中。
- Inbound Filters:过滤已知浏览器扩展、旧浏览器、爬虫或无价值错误。
- Security & Privacy:启用 server-side data scrubbing,并按合规要求开启 Prevent Storing of IP Addresses。
- Spike Protection 与配额告警:避免异常流量快速耗尽配额;同时在 Stats 中区分 accepted、filtered 与 rate-limited 事件。
控制台名称可能随版本变化,最终以项目设置页和官方 Project API 返回的 allowedDomains、dataScrubber、scrubIPAddresses 等字段为准。Allowed Domains 不是认证机制,也不能替代服务端清洗;四层配置需要同时存在。Sentry Project API Spike Protection API Sentry Stats
5. Tracing 与 Source Maps#
浏览器的 tracePropagationTargets 仅匹配自有 API;后端 SDK 继续传入/传出的 trace。浏览器 bundle 的 source map 上传到 myapp-web,后端 bundle 的 source map 上传到 myapp-server,两边使用相同 release。Vite 等构建工具应生成 hidden map,并在上传后删除或拒绝公开访问 .map 文件。Sentry JavaScript Logs Sentry Vite source maps
案例:TanStack Start SSR 的后端部署在 Cloudflare Workers#
以下示例假设使用当前 TanStack Start 的 Cloudflare Workers 部署方式:@cloudflare/vite-plugin、wrangler.jsonc 和 nodejs_compat。TanStack Start 的官方 hosting 文档给出了该部署基线;Sentry 的 Cloudflare 专用指南要求将自定义 server entry 用 withSentry 包裹。TanStack Start Hosting Sentry Cloudflare + TanStack Start
1. 安装运行时 SDK#
pnpm add @sentry/cloudflare @sentry/tanstackstart-react@sentry/tanstackstart-react 当前仍标注为 Beta,且其官方包声明 TanStack Start 最低兼容版本为 1.111.12;请将所有 @sentry/* 依赖保持在兼容的同一版本线上,而不是单独升级其中一个包。官方包说明
2. 让 Worker 使用自定义 server entry#
// wrangler.jsonc
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "myapp",
"main": "src/server.ts",
"compatibility_date": "2026-08-11",
"compatibility_flags": ["nodejs_compat"],
"vars": {
"SENTRY_ENVIRONMENT": "production",
"SENTRY_RELEASE": "myapp@<git-sha>"
}
}把 SENTRY_WORKER_DSN 作为部署 binding 设置,例如:
pnpm exec wrangler secret put SENTRY_WORKER_DSNDSN 本身可以公开:它只能提交事件,不能读取 Sentry 数据。因此浏览器中使用 VITE_* 形式的 DSN 是正常做法;但 SENTRY_AUTH_TOKEN 是 source map/release 上传用的构建凭据,绝不能进入浏览器 bundle 或 Worker runtime。DSN 安全性 Vite source maps
3. Worker 侧:包住 TanStack Start 的 fetch handler#
// src/server.ts
import * as Sentry from "@sentry/cloudflare";
import { wrapFetchWithSentry } from "@sentry/tanstackstart-react";
import handler from "@tanstack/react-start/server-entry";
interface Env {
SENTRY_WORKER_DSN: string;
SENTRY_ENVIRONMENT: string;
SENTRY_RELEASE: string;
}
export default Sentry.withSentry(
(env: Env) => ({
dsn: env.SENTRY_WORKER_DSN,
environment: env.SENTRY_ENVIRONMENT,
release: env.SENTRY_RELEASE,
enableLogs: true,
// 示例起点;应根据真实流量、预算和关键路由改成 sampler。
tracesSampleRate: 0.1,
// 这里只关闭两类自动采集;其余类别仍须按隐私策略显式审查。
dataCollection: {
userInfo: false,
httpBodies: [],
},
}),
// TanStack Start 与 Cloudflare handler 的类型不同;官方示例要求保留此注释。
// @ts-expect-error - handler is not typed as a Cloudflare handler
wrapFetchWithSentry(handler),
);withSentry 负责 Worker 请求生命周期中的初始化、异常与 trace;wrapFetchWithSentry 为 TanStack Start 的 server 函数增加 tracing。不要改用 TanStack Start 的 Node --import 初始化教程:Sentry 明确标注那条路径不适用于 Cloudflare 部署。
dataCollection 是一个必须认真审查的隐私边界。当前 SDK 默认会收集丰富调试上下文;只写 userInfo: false 和 httpBodies: [] 并不等于“没有 PII”。生产环境还应按数据分类显式检查 header、cookie、URL query 和业务日志,并在 beforeSend/beforeSendLog 中移除 token、密码、身份证明和原始请求体。dataCollection 选项
4. 框架级 Server Function / 请求中间件#
将 Sentry 中间件放在 TanStack Start 的数组首位:
// src/start.ts
import {
sentryGlobalFunctionMiddleware,
sentryGlobalRequestMiddleware,
} from "@sentry/tanstackstart-react";
import { createStart } from "@tanstack/react-start";
export const startInstance = createStart(() => ({
requestMiddleware: [sentryGlobalRequestMiddleware],
functionMiddleware: [sentryGlobalFunctionMiddleware],
}));这里有一个容易漏掉的边界:上述中间件不会自动捕获 SSR 渲染异常。如果业务代码或自定义错误边界捕获了渲染异常,应在唯一的兜底点调用 Sentry.captureException(error),随后继续返回对应的错误响应或 fallback UI;不要在多个边界重复上报同一个错误。
5. 浏览器侧:尽早初始化,再挂上 router tracing#
浏览器使用 myapp-web 的 DSN,Worker 使用 myapp-worker 的 DSN。Cloudflare 专用页给出了在 router.tsx 内一次性 init 的简化方式;当前 TanStack Start 手动配置指南则推荐将初始化拆出来,并把它作为 client entry 的第一个 import。后者能捕获 hydration 前和其他模块初始化期间的错误,下面采用它。
// src/instrument.client.ts
import * as Sentry from "@sentry/tanstackstart-react";
Sentry.init({
dsn: import.meta.env.VITE_SENTRY_WEB_DSN,
environment: import.meta.env.VITE_SENTRY_ENVIRONMENT,
release: import.meta.env.VITE_SENTRY_RELEASE,
enableLogs: true,
integrations: [
// 可选:只采集高价值的旧 console 调用,避免无差别上传。
Sentry.consoleLoggingIntegration({ levels: ["warn", "error"] }),
],
tracesSampleRate: 0.1,
// 仅把 trace header 发往本应用的 API / Worker;按实际域名调整。
tracePropagationTargets: [/^\//, /^https:\/\/api\.example\.com/],
});// src/client.tsx
// 必须是第一个 import。
import "./instrument.client";
import { StartClient } from "@tanstack/react-start/client";
import { StrictMode, startTransition } from "react";
import { hydrateRoot } from "react-dom/client";
startTransition(() => {
hydrateRoot(
document,
<StrictMode>
<StartClient />
</StrictMode>,
);
});// src/router.tsx
import * as Sentry from "@sentry/tanstackstart-react";
import { createRouter } from "@tanstack/react-router";
import { routeTree } from "./routeTree.gen";
export const getRouter = () => {
const router = createRouter({ routeTree });
if (!router.isServer) {
Sentry.addIntegration(
Sentry.tanstackRouterBrowserTracingIntegration(router),
);
}
return router;
};VITE_SENTRY_WEB_DSN、VITE_SENTRY_ENVIRONMENT 和 VITE_SENTRY_RELEASE 是构建时注入的公开浏览器配置;Worker binding 不能在浏览器运行时直接读取。因此发布流水线应将同一个不可变 release 值(通常是 Git SHA 或 CI build ID)同时写给浏览器和 Worker,而环境值也要一致。TanStack Start 手动配置:浏览器初始化与 Router tracing
6. Sentry Logs 不会自动收集全部 console#
enableLogs: true 只启用 Sentry Logs 能力;推荐业务代码显式发送少量、可查询的结构化日志:
Sentry.logger.info("checkout completed", {
operation: "checkout.complete",
item_count: order.items.length,
payment_provider: "stripe",
});要将历史 console.* 调用作为 Sentry Logs 发送,需要像上例那样额外启用 consoleLoggingIntegration。生产环境通常只选 warn/error,并用 beforeSendLog 过滤 debug 噪声和敏感字段。日志会与活动 trace 关联,但日志、错误事件和浏览器 breadcrumbs 是不同的数据产品,不能把其中任意一种当作另外两种的替代。Sentry Logs
7. Source Maps 与验证#
两个 Project 时,source map 也必须按运行时分流:浏览器 bundle 上传至 myapp-web,Worker bundle 上传至 myapp-worker;两边使用相同 release。不要让一个覆盖整个 SSR 构建的 Vite 上传步骤把所有 maps 错传到前端 Project。
- 浏览器 Vite 构建可使用
@sentry/vite-plugin;它必须放在其他 Vite plugin 之后,生成hiddensource map,并在上传后删除.map文件。 - Worker 侧遵循 Sentry 的 Cloudflare source map 流程;官方指南要求配置
upload_source_maps,并用npx @sentry/wizard@latest -i sourcemaps完成对应项目的上传设置。 - Sentry Cloudflare Vite plugin 可提供额外的 Worker 依赖插桩,但当前标注为 experimental,且需要
nodejs_compat;它不是基础异常采集的前置条件。
发布后至少做三次验证:浏览器点击按钮抛出异常、请求一个会在 Worker 端抛错的 API 路由、发送一条 Sentry.logger.info。确认错误分别进入正确 Project、栈已还原到源文件,且一次浏览器到 API 的请求能在 Trace Explorer 中关联。Sentry 的官方 Cloudflare + TanStack Start 指南提供了相同的浏览器与 API 验证思路。Cloudflare source maps Cloudflare Vite plugin
案例:纯 Vite + TanStack Router SPA 只需要一个浏览器 Project#
这里没有 SSR、Worker server entry 或服务端函数。创建一个 React 类型的 myapp-web Project 即可,使用 @sentry/react,不要安装 @sentry/tanstackstart-react 或 @sentry/cloudflare 来替代它。
pnpm add @sentry/react
pnpm add -D @sentry/vite-pluginSentry 的 TanStack Router 集成包含在 @sentry/react 中,兼容 @tanstack/react-router >= 1.64.0。它应在 router 创建之后、RouterProvider 渲染之前初始化,并使用专门的 tanstackRouterBrowserTracingIntegration,而不是通用的 browserTracingIntegration。Sentry TanStack Router 集成
// src/router.tsx
import * as Sentry from "@sentry/react";
import { createRouter } from "@tanstack/react-router";
import { routeTree } from "./routeTree.gen";
export const router = createRouter({
routeTree,
// 路由 ErrorBoundary 捕获的错误在这里上报,并保留 React component stack。
defaultOnCatch: (error, errorInfo) =>
Sentry.captureReactException(error, errorInfo),
});
Sentry.init({
dsn: import.meta.env.VITE_SENTRY_DSN,
environment: import.meta.env.MODE,
release: import.meta.env.VITE_SENTRY_RELEASE,
enableLogs: true,
integrations: [
Sentry.tanstackRouterBrowserTracingIntegration(router),
Sentry.consoleLoggingIntegration({ levels: ["warn", "error"] }),
],
tracesSampleRate: import.meta.env.PROD ? 0.1 : 1.0,
tracePropagationTargets: [/^\//],
});
declare module "@tanstack/react-router" {
interface Register {
router: typeof router;
}
}路由层已使用 defaultOnCatch 时,不要再用 React 19 的 createRoot({ onCaughtError: … }) 对同一类路由 ErrorBoundary 重复上报。未捕获错误仍由 SDK 自动采集;React 19 的 onUncaughtError/onRecoverableError 或局部 <Sentry.ErrorBoundary> 可以按需要作为额外 UI/诊断边界,但应明确每种错误只由一个路径报告。
若使用文件路由,Vite 配置还需兼顾三个 plugin 的顺序:TanStack Router 在 React 前,Sentry 在所有 plugin 后。SENTRY_AUTH_TOKEN 仅在 CI 或被 Git 忽略的构建环境文件中读取,不能加 VITE_ 前缀。
// vite.config.ts
import { defineConfig, loadEnv } from "vite";
import react from "@vitejs/plugin-react";
import { tanstackRouter } from "@tanstack/router-plugin/vite";
import { sentryVitePlugin } from "@sentry/vite-plugin";
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), "");
return {
build: { sourcemap: "hidden" },
plugins: [
tanstackRouter({ target: "react", autoCodeSplitting: true }),
react(),
sentryVitePlugin({
org: env.SENTRY_ORG,
project: env.SENTRY_PROJECT,
authToken: env.SENTRY_AUTH_TOKEN,
sourcemaps: {
filesToDeleteAfterUpload: ["./dist/**/*.map"],
},
}),
],
};
});TanStack 官方要求 Router Vite plugin 在 React plugin 前;Sentry 官方要求 Vite plugin 在全部其他 plugin 后,并提醒它不会在 watch/development 模式上传 source map。生产构建后用一次故意抛错来验证 source map,而不是只看构建成功。TanStack Router + Vite Sentry Vite source maps
Convex 有 Sentry 方案吗?有,但它是异常上报,不是完整 SDK 接入#
Convex 提供内建 Sentry Exception Reporting。它适合把 Convex 的 query、mutation、action 与 http_action 执行异常发到 Sentry:在 Convex Dashboard 的 Deployment Settings → Integrations → Sentry 中填写 DSN,并在 Sentry 创建一个Node.js 平台的 Project。该内建功能当前需要 Convex Pro 计划。Convex Exception Reporting
如果同一产品同时有浏览器、Cloudflare Worker 和 Convex,通常形成第三个 Project:
| 运行时 | 推荐 Project | 说明 |
|---|---|---|
| 浏览器 | myapp-web | React / TanStack Router 或 TanStack Start 客户端 |
| Cloudflare Worker | myapp-worker | SSR、HTTP、Worker 日志与 trace |
| Convex | myapp-convex(Node.js) | Convex 函数异常 |
Convex 会附加不可覆盖的 func、func_type、func_runtime、request_id、server_name、environment 和认证用户标识等标签。这使它适合按函数和请求 ID 排查异常;事件可能需要一两分钟才显示在 Sentry。
它的边界也很重要:Convex 官方明确说明内建 Sentry 支持尚不提供 Sentry SDK 的高级自定义能力。因此不要把它当成 Convex 中已经有 Sentry.logger、完整 performance tracing 或浏览器 Replay 的承诺。Convex 另有 Log Streams,可将函数执行和 console.* 日志发到 Axiom、Datadog、PostHog 或自定义 webhook,但当前列出的目的地不包括直接的 Sentry sink;需要自建 webhook 转换器时,要另外处理认证、脱敏、重试、事件模型和去重。Convex Log Streams
sentry 与 sentry-cli:前者是 v4,后者是旧 v3#
如果说的是开发、CI 中连接 Sentry SaaS 或 self-hosted 实例的命令行工具,答案是相反的:sentry 是新版 v4 CLI,sentry-cli 是旧版 v3 CLI。v4 是一次重写:npm 包从 @sentry/cli 改为 sentry,二进制也从 sentry-cli 改为 sentry。它仍会读取原来的 SENTRY_AUTH_TOKEN、SENTRY_ORG、SENTRY_PROJECT、SENTRY_URL 和 .sentryclirc,所以凭据和大部分项目配置可以沿用。Sentry CLI v3 → v4 迁移指南
| 目标 | v3(旧) | v4(新) |
|---|---|---|
| 安装包 / 可执行文件 | @sentry/cli / sentry-cli | sentry / sentry |
| 登录 | sentry-cli login | sentry auth login |
| 新建 release | sentry-cli releases new 1.0.0 | sentry release create my-org/1.0.0(release new 是别名) |
| 上传 source map | sentry-cli sourcemaps upload ./dist | sentry sourcemap upload ./dist(sourcemaps 仍是别名) |
| CI 认证 | token | token 仍可用;交互使用还可采用 OAuth device flow |
不要把已有 CI 的二进制名直接全局替换后就认为迁移完成。v4 将多数命令组从复数改为单数,且部分 flag(例如全局 --auth-token)改由环境变量提供;release deploy、source map 的部分参数也有语义变化。若现有流水线稳定,继续 pin 住 @sentry/cli / sentry-cli 是合理的;准备升级时,应逐条对照官方迁移表,并在 CI 中执行真实上传验证。官方也提供兼容 shim,使多数旧调用可在迁移期间转发给新版。
不要只用版本数字判断新旧#
迁移指南把新版称为 v4,但新版 sentry 可执行文件目前会显示 0.x 的版本号;例如 sentry --version 输出 0.41.0 并不表示它是旧版。判断依据应是二进制名与安装包:sentry / sentry npm 包是新版客户端,sentry-cli / @sentry/cli 才是旧版。升级排查时先确认实际解析到哪个命令,而不是仅按数字猜测:
command -v sentry
sentry --version
command -v sentry-cliCI 迁移时要验证什么#
旧版的 SENTRY_AUTH_TOKEN、SENTRY_ORG、SENTRY_PROJECT、SENTRY_URL 和 .sentryclirc 仍可复用;不要把 token 写进命令行或提交到仓库。相反,原来位于命令前的 --auth-token、self-hosted 使用的 --url、--header 已分别改用环境变量;--allow-failure 已移除。脚本若依赖旧版几乎总是 1 的退出码,或解析纯文本输出,也要重测:新版提供 --json,退出码按认证、输入、API 等错误类型分类。
先做不上传文件的连通性检查,再在 staging 或一次真实 production build 中验证 source map 和 release:
# 以下命令不创建 release,也不上传 source map
sentry --version
sentry auth status
sentry release list --json
sentry sourcemap upload --helprelease list 需要已有的组织、项目和认证配置;若失败,先修正 CI 注入的环境变量,而不是在脚本中回退到明文 token。实际构建验证通过、Sentry 中能看到正确 release 且故意制造的错误能还原到源码后,再卸载旧 sentry-cli。如果仓库代码直接 import 了 @sentry/cli 的 SentryCli 类,不能只替换命令:v4 改为 sentry 包的 createSentrySDK(),需要按官方迁移说明改写调用。
本地开发不需要长期配置 SENTRY_AUTH_TOKEN。执行一次 sentry auth login 后,日常查询和手工上传复用 CLI 的登录 session;CI 才从 secret store 注入组织级 SENTRY_AUTH_TOKEN。若本地构建必须调用只接受 token 的 Vite plugin,可由可信构建脚本在当前进程中读取 sentry auth token 并立即传给 plugin,但不得打印、写入 .env、提交仓库或注入 Cloudflare runtime。更简单的选择是让本地构建跳过上传,需要验证 source map 时再用已登录的 CLI 执行 sentry sourcemap upload。
对本文的 Vite 场景,优先让 @sentry/vite-plugin 在 production build 中完成 source map 上传,通常无需手写任一 CLI 命令。只有自建 release/source-map 脚本、调试 source map 或管理 Sentry 资源时,才直接选择 CLI;无论选择哪一代,都要固定版本以保证 CI 可复现。
若你在self-hosted Sentry 服务容器内看到同名的 sentry,先用 command -v sentry 与 sentry --version 确认来源:那可能是服务端的 Python 管理命令,并不是这里的 v4 客户端 CLI。本文这节讨论的是开发者/CI 客户端;v4 客户端本身也可通过 SENTRY_URL 连到 self-hosted 实例。新版 CLI 安装与 self-hosted 配置
SDK、CLI、Agent Skill 与 MCP 如何分工#
这四者不是四种互相替代的接入方案,而是四个不同层次:
| 能力 | 主要职责 | 不负责什么 |
|---|---|---|
| Sentry SDK | 在浏览器、Worker、服务端运行时采集异常、日志、trace 和 release 上下文 | 不负责让 Agent 查询 Sentry,也不替代 source map 上传 |
| Sentry CLI | 确定性地查询 Issue/Event/Release,验证 source map,执行构建上传和 API 操作 | 不在应用运行时自动捕获异常 |
| Sentry Agent Skill | 告诉 Coding Agent 何时、如何安全调用 CLI;复用现有 CLI 登录态 | Skill 本身没有 Sentry 账号权限,也不传输事件 |
| Sentry MCP | 为人机协作式排障提供面向 Agent 的 Sentry 工具与语义化工作流 | 不是通用管理 API,也不能替代 SDK、CLI 或人工审核 |
flowchart TD R["应用运行时"] -->|"SDK"| P["Sentry Project"] CI["CI / 构建"] -->|"CLI 或构建插件\nrelease + source map"| P A["Coding Agent"] --> SK["Sentry Skill"] SK -->|"调用已登录 CLI"| CLI["Sentry CLI"] CLI -->|"Issue · Event · Release · API"| P A -->|"交互式排障"| MCP["Sentry MCP"] MCP -->|"OAuth + 受限工具"| P
Agent Skill:让 Agent 正确使用 CLI#
当前 Sentry CLI 的 sentry cli setup 会为检测到的 Coding Agent 安装内置 Skill;不希望安装时可传 --no-agent-skills。也可以手工安装:
sentry cli setup
npx skills add https://cli.sentry.devSkill 会指导 Agent 优先使用专用命令,其次用 sentry schema 探索当前 API,只有没有专用命令时才使用 sentry api。它复用 sentry auth login 已建立的本地认证,因此无需把 token 复制给 Agent prompt、仓库或 shell 命令。Sentry CLI Agentic Usage
MCP:适合交互式定位,不适合作为运行时依赖#
Sentry 官方远程 MCP 地址是 https://mcp.sentry.dev/mcp。优先让支持 Remote MCP 的客户端连接该地址并完成 OAuth;这样上游 Sentry token 由服务端处理,客户端拿到的是 MCP access token。官方将它定位为 human-in-the-loop 的开发与调试中间层,而非覆盖全部 Sentry 功能的通用 MCP。
若客户端允许固定 MCP URL,可按最小权限暴露能力,例如连接 https://mcp.sentry.dev/mcp?skills=inspect,triage;自托管 Sentry 或不支持 Remote MCP 的客户端再考虑官方 @sentry/mcp-server stdio transport,并从客户端 secret store 注入 User Auth Token,绝不能把 token 写进 MCP 配置文件或命令行历史。MCP 返回的根因推断仍要由原始 event、源码和可复现测试验证。Sentry 官方 MCP Sentry MCP 服务
一套可重复的 CLI 排障流程#
先确认身份与目标,再看 Issue 的最新原始 Event;不要从 UI 的二次包装文案猜根因:
# 本地一次登录,之后复用 session。
sentry auth login
sentry auth status
# 明确指定项目,避免 monorepo 自动检测到错误 Project。
sentry issue list my-org/my-project \
--query "is:unresolved environment:develop" \
--period 24h \
--limit 10 \
--json \
--fields shortId,title,lastSeen,level,status
# 最新 Event、异常链、tags 与 trace 一次取回。
sentry issue view PROJ-123 \
--spans all \
--json \
--fields shortId,title,event,trace
# 查看同一 Issue 的多次 Event,判断是否只影响特定 release 或浏览器。
sentry event list PROJ-123 --period 24h --full
# 验证部署版本和 source map。
sentry release list my-org/my-project \
--environment develop \
--limit 10
sentry sourcemap resolve ./distsentry sourcemap resolve 是只读检查:它会说明每个 bundle 如何找到 map、是否包含 Sentry Debug ID,不会修改文件。若要手工上传,顺序通常是 sentry sourcemap inject ./dist、sentry sourcemap upload ./dist;生产流水线已经由官方 Vite plugin 完成注入与上传时,不要重复执行。
专用命令没有覆盖某个资源时,先让 CLI 告诉你当前 schema,而不是凭记忆拼 endpoint:
sentry schema --search release
sentry schema issues list
# 最后才使用 sentry api,并先确认方法和是否会修改状态。CLI 的 --json --fields 很适合脚本和 Agent:输出字段稳定,也能减少把无关上下文送入模型。涉及 resolve、archive、delete、bulk update 等写操作时,必须先显示目标并取得人工确认。
本地复现还可使用 Spotlight,不消耗远端 Sentry 配额:
sentry local run -- pnpm dev该命令为子进程注入 SENTRY_SPOTLIGHT 和常见前端前缀变量,并在本地接收 SDK envelope;它适合验证 SDK 是否初始化、异常是否保真和清洗器是否生效。最终仍需在 develop 环境制造一条可控错误,确认远端 Issue、environment、release、原始异常链与 source map 全部正确。
发布前清单#
- 同一产品的浏览器、Worker、Convex 后端放在同一个 Sentry Organization;按运行时拆 Project,而不是按环境拆 Project。
- 每个 Project 用自己的 DSN;同一 Project 的 develop/production 复用该 DSN,仅用
environment区分。 - 浏览器只持有 public DSN;
SENTRY_AUTH_TOKEN只放 CI secret store,不进入浏览器、Cloudflare runtime 或仓库。本地使用 CLI session。 - 浏览器、Worker(以及有需要时 Convex 的发布记录)使用可追溯且一致的 release 约定;
environment使用稳定值。 - 只对本应用 API 设置
tracePropagationTargets;跨域时 CORS 允许sentry-trace与baggage。 - 在错误被 UI/transport 转换前捕获原始
Error,保留清洗后的 message、stack 和cause;每类异常只有一个报告边界。 - Logs 使用结构化字段,避免 token、cookie、原始 body、prompt 和过大的对象;先配置
beforeSend/beforeSendLog再放量。 - Project 侧启用 Allowed Domains、Inbound Filters、server-side data scrubbing、IP 隐私策略和 Spike Protection。
- browser 与 Worker 的 source map 分别上传到正确 Project,部署产物不公开
.map,并在 production build 后验证一条还原后的栈。 - 显式测试浏览器错误、Worker 错误、SSR 渲染兜底、TanStack Server Function、结构化日志和跨端 trace。
- 用 CLI 核对原始 Event、environment、release 和 source map;MCP/Agent 结论必须回到原始事件与可复现测试验证。
参考资料(整理于 2026-08-11)#
- Sentry:Project 数量与边界
- Sentry:DSN、一个 Project 一个 DSN
- Sentry:Cloudflare Workers 上的 TanStack Start
- Sentry:TanStack Start 手动配置
- Sentry:React 的 TanStack Router tracing
- Sentry:JavaScript Logs
- Sentry:Project API 与隐私字段
- Sentry:Spike Protection API
- Sentry:Stats 中的 accepted、filtered 与 rate-limited
- Sentry CLI:从 v3(
sentry-cli)迁移到 v4(sentry) - Sentry CLI:安装、认证与配置
- Sentry CLI:Agentic Usage 与 Agent Skills
- Sentry CLI:命令参考
- Sentry:官方 MCP Server
- TanStack Start:Cloudflare Workers Hosting
- TanStack Router:Vite 安装与 plugin 顺序
- Convex:Sentry Exception Reporting