sentry-setup-tracing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSetup Sentry Tracing
配置Sentry Tracing
This skill helps configure Sentry's Tracing (Performance Monitoring) to track application performance, measure latency, and create distributed traces across services.
本指南帮助你配置Sentry的Tracing(性能监控)功能,以追踪应用性能、测量延迟,并创建跨服务的分布式追踪链路。
When to Use This Skill
何时使用本指南
Invoke this skill when:
- User asks to "setup tracing" or "enable performance monitoring"
- User wants to "track transactions" or "measure latency"
- User requests "distributed tracing" or "span instrumentation"
- User mentions tracking API response times or page load performance
- User asks about or custom spans
tracesSampleRate
在以下场景中使用本指南:
- 用户要求「配置追踪」或「启用性能监控」
- 用户希望「跟踪事务」或「测量延迟」
- 用户请求「分布式追踪」或「跨度埋点」
- 用户提及跟踪API响应时间或页面加载性能
- 用户询问或自定义跨度的相关问题
tracesSampleRate
Platform Detection
平台检测
Before configuring, detect the project's platform:
配置前,请先检测项目的平台:
JavaScript/TypeScript
JavaScript/TypeScript
Check for:
package.json- - Next.js
@sentry/nextjs - - React
@sentry/react - - Node.js
@sentry/node - - Browser/vanilla JS
@sentry/browser - - Vue
@sentry/vue - - Angular
@sentry/angular - - SvelteKit
@sentry/sveltekit
检查中是否有以下依赖:
package.json- - Next.js项目
@sentry/nextjs - - React项目
@sentry/react - - Node.js项目
@sentry/node - - 浏览器/原生JS项目
@sentry/browser - - Vue项目
@sentry/vue - - Angular项目
@sentry/angular - - SvelteKit项目
@sentry/sveltekit
Python
Python
Check for in requirements
sentry-sdk检查requirements文件中是否有
sentry-sdkRuby
Ruby
Check for in Gemfile
sentry-ruby检查Gemfile中是否有
sentry-rubyCore Concepts
核心概念
Explain these concepts to the user:
| Concept | Description |
|---|---|
| Trace | Complete journey of a request across services |
| Transaction | Single instance of a service being called (root span) |
| Span | Individual unit of work within a transaction |
| Sample Rate | Percentage of transactions to capture (0-1) |
向用户解释以下核心概念:
| 概念 | 说明 |
|---|---|
| Trace | 请求跨服务的完整流转过程 |
| Transaction | 单次服务调用的实例(根跨度) |
| Span | 事务内的单个工作单元 |
| Sample Rate(采样率) | 要捕获的事务占比(取值范围0-1) |
JavaScript/TypeScript Configuration
JavaScript/TypeScript配置
Step 1: Locate Sentry Init
步骤1:找到Sentry初始化代码
Find the call:
Sentry.init()- Next.js: ,
instrumentation-client.ts,sentry.server.config.tssentry.edge.config.ts - React: or entry file
src/index.tsx - Node.js: Entry point or config file
- Vue/Angular: Main app initialization
定位调用的位置:
Sentry.init()- Next.js:、
instrumentation-client.ts、sentry.server.config.tssentry.edge.config.ts - React:或其他入口文件
src/index.tsx - Node.js:项目入口文件或配置文件
- Vue/Angular:应用主初始化文件
Step 2: Enable Tracing
步骤2:启用追踪
Browser/React - Add browserTracingIntegration
浏览器/React - 添加browserTracingIntegration
javascript
import * as Sentry from "@sentry/react"; // or @sentry/browser
Sentry.init({
dsn: "YOUR_DSN_HERE",
// Add browser tracing integration
integrations: [Sentry.browserTracingIntegration()],
// Set sample rate (1.0 = 100% for testing, lower for production)
tracesSampleRate: 1.0,
// Configure which URLs receive trace headers for distributed tracing
tracePropagationTargets: [
"localhost",
/^https:\/\/yourserver\.io\/api/,
],
});javascript
import * as Sentry from "@sentry/react"; // 或 @sentry/browser
Sentry.init({
dsn: "YOUR_DSN_HERE",
// 添加浏览器追踪集成
integrations: [Sentry.browserTracingIntegration()],
// 设置采样率(测试环境设为1.0即100%,生产环境调低)
tracesSampleRate: 1.0,
// 配置哪些URL会接收追踪头以实现分布式追踪
tracePropagationTargets: [
"localhost",
/^https:\\/\\/yourserver\\.io\\/api/,
],
});Next.js - Configure All Init Files
Next.js - 配置所有初始化文件
Client ():
instrumentation-client.tstypescript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
// Browser tracing is automatic in @sentry/nextjs
});Server ():
sentry.server.config.tstypescript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
});Edge ():
sentry.edge.config.tstypescript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
});Next.js 14+ App Router Requirement:
For distributed tracing in App Router, add trace data to root layout metadata:
typescript
// app/layout.tsx
import * as Sentry from "@sentry/nextjs";
export async function generateMetadata() {
return {
other: {
...Sentry.getTraceData(),
},
};
}客户端():
instrumentation-client.tstypescript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
// @sentry/nextjs中浏览器追踪是自动集成的
});服务端():
sentry.server.config.tstypescript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
});边缘端():
sentry.edge.config.tstypescript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
});Next.js 14+ App Router要求:
要在App Router中实现分布式追踪,需在根布局的元数据中添加追踪数据:
typescript
// app/layout.tsx
import * as Sentry from "@sentry/nextjs";
export async function generateMetadata() {
return {
other: {
...Sentry.getTraceData(),
},
};
}Node.js
Node.js
javascript
const Sentry = require("@sentry/node");
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
});javascript
const Sentry = require("@sentry/node");
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
});Step 3: Configure Sampling
步骤3:配置采样策略
Option A: Uniform Sample Rate (Simple)
选项A:统一采样率(简单模式)
javascript
Sentry.init({
// Capture 20% of all transactions
tracesSampleRate: 0.2,
});javascript
Sentry.init({
// 捕获20%的所有事务
tracesSampleRate: 0.2,
});Option B: Dynamic Sampling (Advanced)
选项B:动态采样(高级模式)
javascript
Sentry.init({
tracesSampler: ({ name, attributes, parentSampled }) => {
// Always skip health checks
if (name.includes("healthcheck")) {
return 0;
}
// Always capture auth transactions
if (name.includes("auth")) {
return 1;
}
// Sample comments at 1%
if (name.includes("comment")) {
return 0.01;
}
// Inherit parent sampling decision if available
if (typeof parentSampled === "boolean") {
return parentSampled;
}
// Default: 50%
return 0.5;
},
});Note: If both and are set, takes precedence.
tracesSampleRatetracesSamplertracesSamplerjavascript
Sentry.init({
tracesSampler: ({ name, attributes, parentSampled }) => {
// 始终跳过健康检查事务
if (name.includes("healthcheck")) {
return 0;
}
// 始终捕获认证相关事务
if (name.includes("auth")) {
return 1;
}
// 对评论相关事务采样1%
if (name.includes("comment")) {
return 0.01;
}
// 如果存在父采样决策,则继承该决策
if (typeof parentSampled === "boolean") {
return parentSampled;
}
// 默认采样50%
return 0.5;
},
});注意: 如果同时设置了和,的优先级更高。
tracesSampleRatetracesSamplertracesSamplerBrowser Tracing Integration Options
浏览器追踪集成选项
The accepts many configuration options:
browserTracingIntegration()javascript
Sentry.init({
integrations: [
Sentry.browserTracingIntegration({
// Trace propagation targets (which URLs get trace headers)
tracePropagationTargets: ["localhost", /^https:\/\/api\./],
// Modify spans before creation (e.g., parameterize URLs)
beforeStartSpan: (context) => {
return {
...context,
name: context.name.replace(/\/users\/\d+/, "/users/:id"),
};
},
// Filter unwanted spans
shouldCreateSpanForRequest: (url) => {
return !url.includes("healthcheck");
},
// Timing configurations
idleTimeout: 1000, // ms before finishing idle spans
finalTimeout: 30000, // max span duration
childSpanTimeout: 15000, // max child span duration
// Feature toggles
instrumentNavigation: true, // Track URL changes
instrumentPageLoad: true, // Track initial page load
enableLongTask: true, // Track long tasks
enableInp: true, // Track Interaction to Next Paint
// INP sampling (separate from tracesSampleRate)
interactionsSampleRate: 1.0,
}),
],
});browserTracingIntegration()javascript
Sentry.init({
integrations: [
Sentry.browserTracingIntegration({
// 追踪传播目标(哪些URL会被添加追踪头)
tracePropagationTargets: ["localhost", /^https:\\/\\/api\\./],
// 创建跨度前修改配置(例如,将URL参数化)
beforeStartSpan: (context) => {
return {
...context,
name: context.name.replace(/\\/users\\/\\d+/, "/users/:id"),
};
},
// 过滤不需要的跨度
shouldCreateSpanForRequest: (url) => {
return !url.includes("healthcheck");
},
// 计时配置
idleTimeout: 1000, // 空闲跨度结束前的等待时长(毫秒)
finalTimeout: 30000, // 跨度最大时长
childSpanTimeout: 15000, // 子跨度最大时长
// 功能开关
instrumentNavigation: true, // 跟踪URL变化
instrumentPageLoad: true, // 跟踪初始页面加载
enableLongTask: true, // 跟踪长任务
enableInp: true, // 跟踪Interaction to Next Paint(INP)指标
// INP采样率(与tracesSampleRate分开设置)
interactionsSampleRate: 1.0,
}),
],
});Python Configuration
Python配置
Step 1: Enable Tracing
步骤1:启用追踪
python
import sentry_sdk
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=1.0, # 100% for testing
)python
import sentry_sdk
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=1.0, # 测试环境设为100%
)Step 2: Configure Sampling
步骤2:配置采样策略
Uniform Rate
统一采样率
python
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=0.2, # 20% of transactions
)python
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=0.2, # 捕获20%的事务
)Dynamic Sampling
动态采样
python
def traces_sampler(sampling_context):
transaction_name = sampling_context.get("transaction_context", {}).get("name", "")
if "healthcheck" in transaction_name:
return 0
if "auth" in transaction_name:
return 1.0
# Inherit from parent if available
if sampling_context.get("parent_sampled") is not None:
return sampling_context["parent_sampled"]
return 0.5
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sampler=traces_sampler,
)python
def traces_sampler(sampling_context):
transaction_name = sampling_context.get("transaction_context", {}).get("name", "")
if "healthcheck" in transaction_name:
return 0
if "auth" in transaction_name:
return 1.0
# 如果存在父采样决策,则继承
if sampling_context.get("parent_sampled") is not None:
return sampling_context["parent_sampled"]
return 0.5
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sampler=traces_sampler,
)Ruby Configuration
Ruby配置
Enable Tracing
启用追踪
ruby
Sentry.init do |config|
config.dsn = "YOUR_DSN_HERE"
config.traces_sample_rate = 1.0 # 100% for testing
endruby
Sentry.init do |config|
config.dsn = "YOUR_DSN_HERE"
config.traces_sample_rate = 1.0 # 测试环境设为100%
endDynamic Sampling
动态采样
ruby
Sentry.init do |config|
config.dsn = "YOUR_DSN_HERE"
config.traces_sampler = lambda do |sampling_context|
transaction_name = sampling_context[:transaction_context][:name]
return 0 if transaction_name.include?("healthcheck")
return 1.0 if transaction_name.include?("auth")
0.5 # Default 50%
end
endruby
Sentry.init do |config|
config.dsn = "YOUR_DSN_HERE"
config.traces_sampler = lambda do |sampling_context|
transaction_name = sampling_context[:transaction_context][:name]
return 0 if transaction_name.include?("healthcheck")
return 1.0 if transaction_name.include?("auth")
0.5 # 默认采样50%
end
endCustom Instrumentation
自定义埋点
JavaScript Custom Spans
JavaScript自定义跨度
Using startSpan (Recommended)
使用startSpan(推荐方式)
javascript
// Synchronous operation
const result = Sentry.startSpan(
{ name: "expensive-calculation", op: "function" },
() => {
return calculateSomething();
}
);
// Async operation
const result = await Sentry.startSpan(
{ name: "fetch-user-data", op: "http.client" },
async () => {
const response = await fetch("/api/user");
return response.json();
}
);
// With attributes
const result = await Sentry.startSpan(
{
name: "process-order",
op: "task",
attributes: {
"order.id": orderId,
"order.amount": amount,
},
},
async () => {
return processOrder(orderId);
}
);javascript
// 同步操作
const result = Sentry.startSpan(
{ name: "expensive-calculation", op: "function" },
() => {
return calculateSomething();
}
);
// 异步操作
const result = await Sentry.startSpan(
{ name: "fetch-user-data", op: "http.client" },
async () => {
const response = await fetch("/api/user");
return response.json();
}
);
// 携带属性
const result = await Sentry.startSpan(
{
name: "process-order",
op: "task",
attributes: {
"order.id": orderId,
"order.amount": amount,
},
},
async () => {
return processOrder(orderId);
}
);Nested Spans
嵌套跨度
javascript
await Sentry.startSpan({ name: "checkout-flow", op: "transaction" }, async () => {
// Child span 1
await Sentry.startSpan({ name: "validate-cart", op: "validation" }, async () => {
await validateCart();
});
// Child span 2
await Sentry.startSpan({ name: "process-payment", op: "payment" }, async () => {
await processPayment();
});
// Child span 3
await Sentry.startSpan({ name: "send-confirmation", op: "email" }, async () => {
await sendConfirmationEmail();
});
});javascript
await Sentry.startSpan({ name: "checkout-flow", op: "transaction" }, async () => {
// 子跨度1
await Sentry.startSpan({ name: "validate-cart", op: "validation" }, async () => {
await validateCart();
});
// 子跨度2
await Sentry.startSpan({ name: "process-payment", op: "payment" }, async () => {
await processPayment();
});
// 子跨度3
await Sentry.startSpan({ name: "send-confirmation", op: "email" }, async () => {
await sendConfirmationEmail();
});
});Manual Span Control
手动控制跨度
javascript
function middleware(req, res, next) {
return Sentry.startSpanManual({ name: "middleware", op: "middleware" }, (span) => {
res.once("finish", () => {
span.setStatus({ code: res.statusCode < 400 ? 1 : 2 });
span.end();
});
return next();
});
}javascript
function middleware(req, res, next) {
return Sentry.startSpanManual({ name: "middleware", op: "middleware" }, (span) => {
res.once("finish", () => {
span.setStatus({ code: res.statusCode < 400 ? 1 : 2 });
span.end();
});
return next();
});
}Inactive Spans (Browser)
非活跃跨度(浏览器端)
javascript
let checkoutSpan;
// Start inactive span
function onStartCheckout() {
checkoutSpan = Sentry.startInactiveSpan({ name: "checkout-flow" });
Sentry.setActiveSpanInBrowser(checkoutSpan);
}
// End when done
function onCompleteCheckout() {
checkoutSpan?.end();
}javascript
let checkoutSpan;
// 启动非活跃跨度
function onStartCheckout() {
checkoutSpan = Sentry.startInactiveSpan({ name: "checkout-flow" });
Sentry.setActiveSpanInBrowser(checkoutSpan);
}
// 完成后结束跨度
function onCompleteCheckout() {
checkoutSpan?.end();
}Python Custom Spans
Python自定义跨度
Using Decorator (Simplest)
使用装饰器(最简单方式)
python
import sentry_sdk
@sentry_sdk.trace
def expensive_function():
# Automatically creates a span
return do_work()python
import sentry_sdk
@sentry_sdk.trace
def expensive_function():
# 自动创建一个跨度
return do_work()
// 携带参数(SDK 2.35.0+)
@sentry_sdk.trace(op="database", name="fetch-users")
def fetch_users():
return db.query(User).all()With parameters (SDK 2.35.0+)
使用上下文管理器
@sentry_sdk.trace(op="database", name="fetch-users")
def fetch_users():
return db.query(User).all()
undefinedpython
import sentry_sdk
def process_order(order_id):
with sentry_sdk.start_span(name="process-order", op="task") as span:
span.set_data("order.id", order_id)
# 嵌套跨度
with sentry_sdk.start_span(name="validate-order", op="validation"):
validate(order_id)
with sentry_sdk.start_span(name="charge-payment", op="payment"):
charge(order_id)
return {"success": True}Using Context Manager
手动创建事务
python
import sentry_sdk
def process_order(order_id):
with sentry_sdk.start_span(name="process-order", op="task") as span:
span.set_data("order.id", order_id)
# Nested span
with sentry_sdk.start_span(name="validate-order", op="validation"):
validate(order_id)
with sentry_sdk.start_span(name="charge-payment", op="payment"):
charge(order_id)
return {"success": True}python
import sentry_sdk
with sentry_sdk.start_transaction(op="task", name="batch-process") as transaction:
for item in items:
with sentry_sdk.start_span(name=f"process-item-{item.id}"):
process(item)
transaction.set_tag("items_processed", len(items))Manual Transaction
集中式配置
python
import sentry_sdk
with sentry_sdk.start_transaction(op="task", name="batch-process") as transaction:
for item in items:
with sentry_sdk.start_span(name=f"process-item-{item.id}"):
process(item)
transaction.set_tag("items_processed", len(items))python
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=1.0,
functions_to_trace=[
{"qualified_name": "myapp.services.process_order"},
{"qualified_name": "myapp.services.send_notification"},
],
)Centralized Configuration
分布式追踪
—
工作原理
python
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=1.0,
functions_to_trace=[
{"qualified_name": "myapp.services.process_order"},
{"qualified_name": "myapp.services.send_notification"},
],
)Sentry通过HTTP头传播追踪上下文:
- :包含Trace ID、Span ID和采样决策
sentry-trace - :包含额外的追踪元数据
baggage
Distributed Tracing
配置追踪传播目标
How It Works
—
Sentry propagates trace context via HTTP headers:
- : Contains trace ID, span ID, sampling decision
sentry-trace - : Contains additional trace metadata
baggage
只有匹配以下规则的URL才会被添加追踪头:
javascript
Sentry.init({
tracePropagationTargets: [
"localhost",
"https://api.yourapp.com",
/^https:\\/\\/.*\\.yourapp\\.com\\/api/,
],
});Configure Trace Propagation Targets
服务端渲染(Meta标签)
Only URLs matching these patterns receive trace headers:
javascript
Sentry.init({
tracePropagationTargets: [
"localhost",
"https://api.yourapp.com",
/^https:\/\/.*\.yourapp\.com\/api/,
],
});对于SSR应用,在HTML中注入追踪数据:
javascript
// 服务端渲染以下meta标签
const traceData = Sentry.getTraceData();
// 将以下内容添加到HTML <head>中:
// <meta name="sentry-trace" content="..." />
// <meta name="baggage" content="..." />浏览器SDK会自动读取这些标签并继续追踪链路。
Server-Side Rendering (Meta Tags)
手动传播
For SSR apps, inject trace data in HTML:
javascript
// Server renders these meta tags
const traceData = Sentry.getTraceData();
// Include in HTML <head>:
// <meta name="sentry-trace" content="..." />
// <meta name="baggage" content="..." />The browser SDK automatically reads these and continues the trace.
对于非HTTP通道(如WebSocket、消息队列):
javascript
// 发送端
const traceData = Sentry.getTraceData();
sendMessage({
...payload,
_traceHeaders: traceData,
});
// 接收端
Sentry.continueTrace(
{
sentryTrace: message._traceHeaders["sentry-trace"],
baggage: message._traceHeaders["baggage"],
},
() => {
processMessage(message);
}
);Manual Propagation
常见操作类型
For non-HTTP channels (WebSockets, message queues):
javascript
// Sender
const traceData = Sentry.getTraceData();
sendMessage({
...payload,
_traceHeaders: traceData,
});
// Receiver
Sentry.continueTrace(
{
sentryTrace: message._traceHeaders["sentry-trace"],
baggage: message._traceHeaders["baggage"],
},
() => {
processMessage(message);
}
);使用统一的值以便更好地组织数据:
op| 操作类型 | 使用场景 |
|---|---|
| 对外HTTP请求 |
| 对内HTTP请求 |
| 数据库操作 |
| 数据库查询 |
| 缓存操作 |
| 后台任务 |
| 函数执行 |
| UI渲染 |
| 用户交互 |
| 序列化操作 |
| 中间件执行 |
Common Operation Types
自动追踪内容
—
浏览器(集成browserTracingIntegration后)
Use consistent values for better organization:
op| Operation | Use Case |
|---|---|
| Outgoing HTTP requests |
| Incoming HTTP requests |
| Database operations |
| Database queries |
| Cache operations |
| Background tasks |
| Function execution |
| UI rendering |
| User interactions |
| Serialization |
| Middleware execution |
- 页面加载
- 导航/路由变化
- XHR/fetch请求
- 长任务
- Interaction to Next Paint(INP)指标
What Gets Automatically Traced
Next.js
Browser (with browserTracingIntegration)
—
- Page loads
- Navigation/route changes
- XHR/fetch requests
- Long tasks
- Interaction to Next Paint (INP)
- API路由
- 服务端组件
- 页面渲染
- 数据获取
Next.js
Node.js(集成框架插件后)
- API routes
- Server components
- Page renders
- Data fetching
- HTTP请求(Express、Fastify等)
- 数据库查询(集成ORM后)
- 外部API调用
Node.js (with framework integrations)
Python(集成框架插件后)
- HTTP requests (Express, Fastify, etc.)
- Database queries (with ORM integrations)
- External API calls
- Django视图、中间件、模板
- Flask路由
- FastAPI端点
- SQLAlchemy查询
- Celery任务
Python (with framework integrations)
禁用追踪
- Django views, middleware, templates
- Flask routes
- FastAPI endpoints
- SQLAlchemy queries
- Celery tasks
重要提示: 设置并不会禁用追踪——SDK仍会处理追踪数据,但不会发送到Sentry。
tracesSampleRate: 0要完全禁用追踪,请同时省略两个采样配置项:
javascript
Sentry.init({
dsn: "YOUR_DSN_HERE",
// 不要包含tracesSampleRate或tracesSampler
});Disabling Tracing
生产环境采样率建议
Important: Setting does NOT disable tracing - it still processes traces but never sends them.
tracesSampleRate: 0To fully disable tracing, omit both sampling options:
javascript
Sentry.init({
dsn: "YOUR_DSN_HERE",
// Do NOT include tracesSampleRate or tracesSampler
});| 流量级别 | 推荐采样率 |
|---|---|
| 开发/测试环境 | |
| 低流量(<1K请求/分钟) | |
| 中流量(1K-10K请求/分钟) | |
| 高流量(>10K请求/分钟) | |
使用动态采样来捕获更多关键事务:
javascript
tracesSampler: ({ name }) => {
// 始终捕获错误和慢接口事务
if (name.includes("checkout") || name.includes("payment")) {
return 1.0;
}
// 其他事务采样10%
return 0.1;
},Production Sampling Recommendations
验证步骤
| Traffic Level | Recommended Rate |
|---|---|
| Development/Testing | |
| Low traffic (<1K req/min) | |
| Medium traffic (1K-10K req/min) | |
| High traffic (>10K req/min) | |
Use dynamic sampling to capture more of important transactions:
javascript
tracesSampler: ({ name }) => {
// Always capture errors and slow endpoints
if (name.includes("checkout") || name.includes("payment")) {
return 1.0;
}
// Sample most at 10%
return 0.1;
},配置完成后,验证追踪是否正常工作:
Verification Steps
JavaScript
After setup, verify tracing is working:
javascript
// 触发一个测试事务
await Sentry.startSpan(
{ name: "test-transaction", op: "test" },
async () => {
console.log("追踪测试");
await new Promise(resolve => setTimeout(resolve, 100));
}
);JavaScript
Python
javascript
// Trigger a test transaction
await Sentry.startSpan(
{ name: "test-transaction", op: "test" },
async () => {
console.log("Tracing test");
await new Promise(resolve => setTimeout(resolve, 100));
}
);python
with sentry_sdk.start_transaction(op="test", name="test-transaction"):
print("追踪测试")在Sentry中检查:
- 进入「性能」板块
- 查找你的测试事务
- 验证追踪瀑布图中是否显示跨度
Python
常见问题与解决方案
—
问题:事务未出现在Sentry中
python
with sentry_sdk.start_transaction(op="test", name="test-transaction"):
print("Tracing test")Check in Sentry:
- Go to Performance section
- Look for your test transaction
- Verify spans appear in the trace waterfall
解决方案:
- 确认或
tracesSampleRate > 0返回值大于0tracesSampler - 检查DSN是否正确
- 浏览器环境:确认已添加
browserTracingIntegration() - 等待几分钟,数据需要时间处理
Common Issues and Solutions
问题:分布式追踪链路未关联
Issue: Transactions not appearing
—
Solutions:
- Verify or
tracesSampleRate > 0returns > 0tracesSampler - Check DSN is correct
- For browser: Ensure is added
browserTracingIntegration() - Wait a few minutes for data to process
解决方案:
- 检查是否包含你的API URL
tracePropagationTargets - 验证CORS配置允许和
sentry-trace头baggage - SSR应用:确认已渲染追踪meta标签
Issue: Distributed traces not connected
问题:事务数量过多(高流量场景)
Solutions:
- Check includes your API URLs
tracePropagationTargets - Verify CORS allows and
sentry-traceheadersbaggage - For SSR: Ensure trace meta tags are rendered
解决方案:
- 调低
tracesSampleRate - 使用按事务名称过滤
tracesSampler - 使用跳过健康检查
shouldCreateSpanForRequest
Issue: Too many transactions (high volume)
问题:跨度嵌套不正确
Solutions:
- Lower
tracesSampleRate - Use to filter by transaction name
tracesSampler - Use to skip health checks
shouldCreateSpanForRequest
解决方案:
- 确保创建子跨度时父跨度仍处于活跃状态
- 使用回调模式(而非手动方式)
startSpan - 浏览器环境:考虑设置
parentSpanIsAlwaysRootSpan: false
Issue: Spans not nested correctly
配置完成检查清单
Solutions:
- Ensure parent span is still active when creating child
- Use callback pattern (not manual)
startSpan - For browser: Consider
parentSpanIsAlwaysRootSpan: false
markdown
undefinedSummary Checklist
Sentry Tracing配置完成
—
已应用的配置:
markdown
undefined- 已配置或
tracesSampleRatetracesSampler - 浏览器环境:已添加
browserTracingIntegration() - 已为API配置
tracePropagationTargets - Next.js App Router:已在元数据中添加</think_never_used_51bce0c785ca2f68081bfa7d91973934>{ "description": "在任意项目中配置Sentry Tracing(性能监控)。当需要添加性能监控、启用追踪、跟踪事务/跨度(Transaction/Span)或埋点应用性能时使用本指南。支持JavaScript、TypeScript、Python、Ruby、React、Next.js和Node.js。", "content": "# 配置Sentry Tracing
getTraceData()
本指南帮助你配置Sentry的Tracing(性能监控)功能,以追踪应用性能、测量延迟,并创建跨服务的分布式追踪链路。
Sentry Tracing Setup Complete
何时使用本指南
Configuration Applied:
—
- or
tracesSampleRateconfiguredtracesSampler - Browser: added
browserTracingIntegration() - configured for APIs
tracePropagationTargets - Next.js App Router: in metadata
getTraceData()
在以下场景中使用本指南:
- 用户要求「配置追踪」或「启用性能监控」
- 用户希望「跟踪事务」或「测量延迟」
- 用户请求「分布式追踪」或「跨度埋点」
- 用户提及跟踪API响应时间或页面加载性能
- 用户询问或自定义跨度的相关问题
tracesSampleRate
Sampling Strategy:
平台检测
- Development: 100% sampling for testing
- Production: Appropriate rate based on traffic
配置前,请先检测项目的平台:
Custom Instrumentation (if applicable):
JavaScript/TypeScript
- Critical paths instrumented with custom spans
- Consistent values used
op
检查中是否有以下依赖:
package.json- - Next.js项目
@sentry/nextjs - - React项目
@sentry/react - - Node.js项目
@sentry/node - - 浏览器/原生JS项目
@sentry/browser - - Vue项目
@sentry/vue - - Angular项目
@sentry/angular - - SvelteKit项目
@sentry/sveltekit
Next Steps:
Python
- Trigger some requests in your application
- Check Sentry > Performance for transactions
- Review trace waterfalls for span hierarchy
- Adjust sampling rates based on volume
---检查requirements文件中是否有
sentry-sdkQuick Reference
Ruby
| Platform | Enable Tracing | Custom Span |
|---|---|---|
| JS/Browser | | |
| Next.js | | |
| Node.js | | |
| Python | | |
| Ruby | | |
| Sampling Option | Purpose |
|---|---|
| Uniform percentage (0-1) |
| Dynamic function (takes precedence) |
检查Gemfile中是否有
sentry-ruby—
核心概念
—
向用户解释以下核心概念:
| 概念 | 说明 |
|---|---|
| Trace | 请求跨服务的完整流转过程 |
| Transaction | 单次服务调用的实例(根跨度) |
| Span | 事务内的单个工作单元 |
| Sample Rate(采样率) | 要捕获的事务占比(取值范围0-1) |
—
JavaScript/TypeScript配置
—
步骤1:找到Sentry初始化代码
—
定位调用的位置:
Sentry.init()- Next.js:、
instrumentation-client.ts、sentry.server.config.tssentry.edge.config.ts - React:或其他入口文件
src/index.tsx - Node.js:项目入口文件或配置文件
- Vue/Angular:应用主初始化文件
—
步骤2:启用追踪
—
浏览器/React - 添加browserTracingIntegration
—
javascript
import * as Sentry from "@sentry/react"; // 或 @sentry/browser
Sentry.init({
dsn: "YOUR_DSN_HERE",
// 添加浏览器追踪集成
integrations: [Sentry.browserTracingIntegration()],
// 设置采样率(测试环境设为1.0即100%,生产环境调低)
tracesSampleRate: 1.0,
// 配置哪些URL会接收追踪头以实现分布式追踪
tracePropagationTargets: [
"localhost",
/^https:\\/\\/yourserver\\.io\\/api/,
],
});—
Next.js - 配置所有初始化文件
—
客户端():
instrumentation-client.tstypescript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
// @sentry/nextjs中浏览器追踪是自动集成的
});服务端():
sentry.server.config.tstypescript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
});边缘端():
sentry.edge.config.tstypescript
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
});Next.js 14+ App Router要求:
要在App Router中实现分布式追踪,需在根布局的元数据中添加追踪数据:
typescript
// app/layout.tsx
import * as Sentry from "@sentry/nextjs";
export async function generateMetadata() {
return {
other: {
...Sentry.getTraceData(),
},
};
}—
Node.js
—
javascript
const Sentry = require("@sentry/node");
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
});—
步骤3:配置采样策略
—
选项A:统一采样率(简单模式)
—
javascript
Sentry.init({
// 捕获20%的所有事务
tracesSampleRate: 0.2,
});—
选项B:动态采样(高级模式)
—
javascript
Sentry.init({
tracesSampler: ({ name, attributes, parentSampled }) => {
// 始终跳过健康检查事务
if (name.includes("healthcheck")) {
return 0;
}
// 始终捕获认证相关事务
if (name.includes("auth")) {
return 1;
}
// 对评论相关事务采样1%
if (name.includes("comment")) {
return 0.01;
}
// 如果存在父采样决策,则继承该决策
if (typeof parentSampled === "boolean") {
return parentSampled;
}
// 默认采样50%
return 0.5;
},
});注意: 如果同时设置了和,的优先级更高。
tracesSampleRatetracesSamplertracesSampler—
浏览器追踪集成选项
—
browserTracingIntegration()javascript
Sentry.init({
integrations: [
Sentry.browserTracingIntegration({
// 追踪传播目标(哪些URL会被添加追踪头)
tracePropagationTargets: ["localhost", /^https:\\/\\/api\\./],
// 创建跨度前修改配置(例如,将URL参数化)
beforeStartSpan: (context) => {
return {
...context,
name: context.name.replace(/\\/users\\/\\d+/, "/users/:id"),
};
},
// 过滤不需要的跨度
shouldCreateSpanForRequest: (url) => {
return !url.includes("healthcheck");
},
// 计时配置
idleTimeout: 1000, // 空闲跨度结束前的等待时长(毫秒)
finalTimeout: 30000, // 跨度最大时长
childSpanTimeout: 15000, // 子跨度最大时长
// 功能开关
instrumentNavigation: true, // 跟踪URL变化
instrumentPageLoad: true, // 跟踪初始页面加载
enableLongTask: true, // 跟踪长任务
enableInp: true, // 跟踪Interaction to Next Paint
// INP采样率(与tracesSampleRate分开设置)
interactionsSampleRate: 1.0,
}),
],
});—
Python配置
—
步骤1:启用追踪
—
python
import sentry_sdk
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=1.0, # 测试环境设为100%
)—
步骤2:配置采样策略
—
统一采样率
—
python
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=0.2, # 捕获20%的事务
)—
动态采样
—
python
def traces_sampler(sampling_context):
transaction_name = sampling_context.get("transaction_context", {}).get("name", "")
if "healthcheck" in transaction_name:
return 0
if "auth" in transaction_name:
return 1.0
# 如果存在父采样决策,则继承
if sampling_context.get("parent_sampled") is not None:
return sampling_context["parent_sampled"]
return 0.5
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sampler=traces_sampler,
)—
Ruby配置
—
启用追踪
—
ruby
Sentry.init do |config|
config.dsn = "YOUR_DSN_HERE"
config.traces_sample_rate = 1.0 # 测试环境设为100%
end—
动态采样
—
ruby
Sentry.init do |config|
config.dsn = "YOUR_DSN_HERE"
config.traces_sampler = lambda do |sampling_context|
transaction_name = sampling_context[:transaction_context][:name]
return 0 if transaction_name.include?("healthcheck")
return 1.0 if transaction_name.include?("auth")
0.5 # 默认采样50%
end
end—
自定义埋点
—
JavaScript自定义跨度
—
使用startSpan(推荐方式)
—
javascript
// 同步操作
const result = Sentry.startSpan(
{ name: "expensive-calculation", op: "function" },
() => {
return calculateSomething();
}
);
// 异步操作
const result = await Sentry.startSpan(
{ name: "fetch-user-data", op: "http.client" },
async () => {
const response = await fetch("/api/user");
return response.json();
}
);
// 携带属性
const result = await Sentry.startSpan(
{
name: "process-order",
op: "task",
attributes: {
"order.id": orderId,
"order.amount": amount,
},
},
async () => {
return processOrder(orderId);
}
);—
嵌套跨度
—
javascript
await Sentry.startSpan({ name: "checkout-flow", op: "transaction" }, async () => {
// 子跨度1
await Sentry.startSpan({ name: "validate-cart", op: "validation" }, async () => {
await validateCart();
});
// 子跨度2
await Sentry.startSpan({ name: "process-payment", op: "payment" }, async () => {
await processPayment();
});
// 子跨度3
await Sentry.startSpan({ name: "send-confirmation", op: "email" }, async () => {
await sendConfirmationEmail();
});
});—
手动控制跨度
—
javascript
function middleware(req, res, next) {
return Sentry.startSpanManual({ name: "middleware", op: "middleware" }, (span) => {
res.once("finish", () => {
span.setStatus({ code: res.statusCode < 400 ? 1 : 2 });
span.end();
});
return next();
});
}—
非活跃跨度(浏览器端)
—
javascript
let checkoutSpan;
// 启动非活跃跨度
function onStartCheckout() {
checkoutSpan = Sentry.startInactiveSpan({ name: "checkout-flow" });
Sentry.setActiveSpanInBrowser(checkoutSpan);
}
// 完成后结束跨度
function onCompleteCheckout() {
checkoutSpan?.end();
}—
Python自定义跨度
—
使用装饰器(最简单方式)
—
python
import sentry_sdk
@sentry_sdk.trace
def expensive_function():
# 自动创建一个跨度
return do_work()—
携带参数(SDK 2.35.0+)
—
@sentry_sdk.trace(op="database", name="fetch-users")
def fetch_users():
return db.query(User).all()
undefined—
使用上下文管理器
—
python
import sentry_sdk
def process_order(order_id):
with sentry_sdk.start_span(name="process-order", op="task") as span:
span.set_data("order.id", order_id)
# 嵌套跨度
with sentry_sdk.start_span(name="validate-order", op="validation"):
validate(order_id)
with sentry_sdk.start_span(name="charge-payment", op="payment"):
charge(order_id)
return {"success": True}—
手动创建事务
—
python
import sentry_sdk
with sentry_sdk.start_transaction(op="task", name="batch-process") as transaction:
for item in items:
with sentry_sdk.start_span(name=f"process-item-{item.id}"):
process(item)
transaction.set_tag("items_processed", len(items))—
集中式配置
—
python
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=1.0,
functions_to_trace=[
{"qualified_name": "myapp.services.process_order"},
{"qualified_name": "myapp.services.send_notification"},
],
)—
分布式追踪
—
工作原理
—
Sentry通过HTTP头传播追踪上下文:
- :包含Trace ID、Span ID和采样决策
sentry-trace - :包含额外的追踪元数据
baggage
—
配置追踪传播目标
—
只有匹配以下规则的URL才会被添加追踪头:
javascript
Sentry.init({
tracePropagationTargets: [
"localhost",
"https://api.yourapp.com",
/^https:\\/\\/.*\\.yourapp\\.com\\/api/,
],
});—
服务端渲染(Meta标签)
—
对于SSR应用,在HTML中注入追踪数据:
javascript
// 服务端渲染以下meta标签
const traceData = Sentry.getTraceData();
// 添加到HTML <head>中:
// <meta name="sentry-trace" content="..." />
// <meta name="baggage" content="..." />浏览器SDK会自动读取这些标签并继续追踪链路。
—
手动传播
—
对于非HTTP通道(如WebSocket、消息队列):
javascript
// 发送端
const traceData = Sentry.getTraceData();
sendMessage({
...payload,
_traceHeaders: traceData,
});
// 接收端
Sentry.continueTrace(
{
sentryTrace: message._traceHeaders["sentry-trace"],
baggage: message._traceHeaders["baggage"],
},
() => {
processMessage(message);
}
);—
常见操作类型
—
使用统一的值以便更好地组织数据:
op| 操作类型 | 使用场景 |
|---|---|
| 对外HTTP请求 |
| 对内HTTP请求 |
| 数据库操作 |
| 数据库查询 |
| 缓存操作 |
| 后台任务 |
| 函数执行 |
| UI渲染 |
| 用户交互 |
| 序列化操作 |
| 中间件执行 |
—
自动追踪内容
—
浏览器(集成browserTracingIntegration后)
—
- 页面加载
- 导航/路由变化
- XHR/fetch请求
- 长任务
- Interaction to Next Paint(INP)指标
—
Next.js
—
- API路由
- 服务端组件
- 页面渲染
- 数据获取
—
Node.js(集成框架插件后)
—
- HTTP请求(Express、Fastify等)
- 数据库查询(集成ORM后)
- 外部API调用
—
Python(集成框架插件后)
—
- Django视图、中间件、模板
- Flask路由
- FastAPI端点
- SQLAlchemy查询
- Celery任务
—
禁用追踪
—
重要提示: 设置并不会禁用追踪——SDK仍会处理追踪数据,但不会发送到Sentry。
tracesSampleRate: 0要完全禁用追踪,请同时省略两个采样配置项:
javascript
Sentry.init({
dsn: "YOUR_DSN_HERE",
// 不要包含tracesSampleRate或tracesSampler
});—
生产环境采样率建议
—
| 流量级别 | 推荐采样率 |
|---|---|
| 开发/测试环境 | |
| 低流量(<1K请求/分钟) | |
| 中流量(1K-10K请求/分钟) | |
| 高流量(>10K请求/分钟) | |
使用动态采样来捕获更多关键事务:
javascript
tracesSampler: ({ name }) => {
// 始终捕获错误和慢接口事务
if (name.includes("checkout") || name.includes("payment")) {
return 1.0;
}
// 其他事务采样10%
return 0.1;
},—
验证步骤
—
配置完成后,验证追踪是否正常工作:
—
JavaScript
—
javascript
// 触发一个测试事务
await Sentry.startSpan(
{ name: "test-transaction", op: "test" },
async () => {
console.log("追踪测试");
await new Promise(resolve => setTimeout(resolve, 100));
}
);—
Python
—
python
with sentry_sdk.start_transaction(op="test", name="test-transaction"):
print("追踪测试")在Sentry中检查:
- 进入「性能」板块
- 查找你的测试事务
- 验证追踪瀑布图中是否显示跨度
—
常见问题与解决方案
—
问题:事务未出现在Sentry中
—
解决方案:
- 确认或
tracesSampleRate > 0返回值大于0tracesSampler - 检查DSN是否正确
- 浏览器环境:确认已添加
browserTracingIntegration() - 等待几分钟,数据需要时间处理
—
问题:分布式追踪链路未关联
—
解决方案:
- 检查是否包含你的API URL
tracePropagationTargets - 验证CORS配置允许和
sentry-trace头baggage - SSR应用:确认已渲染追踪meta标签
—
问题:事务数量过多(高流量场景)
—
解决方案:
- 调低
tracesSampleRate - 使用按事务名称过滤
tracesSampler - 使用跳过健康检查
shouldCreateSpanForRequest
—
问题:跨度嵌套不正确
—
解决方案:
- 确保创建子跨度时父跨度仍处于活跃状态
- 使用回调模式(而非手动方式)
startSpan - 浏览器环境:考虑设置
parentSpanIsAlwaysRootSpan: false
—
配置完成检查清单
—
markdown
undefined—
Sentry Tracing配置完成
—
已应用的配置:
—
- 已配置或
tracesSampleRatetracesSampler - 浏览器环境:已添加
browserTracingIntegration() - 已为API配置
tracePropagationTargets - Next.js App Router:已在元数据中添加
getTraceData()
—
采样策略:
—
- 开发环境:已设置100%采样率用于测试
- 生产环境:已根据流量设置合适的采样率
—
自定义埋点(如适用):
—
- 关键路径已通过自定义跨度埋点
- 使用了统一的值
op
—
下一步操作:
—
- 在应用中触发一些请求
- 查看Sentry > 性能板块中的事务
- 检查追踪瀑布图的跨度层级
- 根据流量调整采样率
---—
快速参考
—
| 平台 | 启用追踪方式 | 自定义跨度方式 |
|---|---|---|
| JS/浏览器 | | |
| Next.js | | |
| Node.js | | |
| Python | | |
| Ruby | | |
| 采样选项 | 用途 |
|---|---|
| 统一采样比例(0-1) |
| 动态采样函数(优先级更高) |
undefined