
sentry-setup-tracing
✓ Official★ 2by sentry · part of getsentry/sentry-for-cursor
Setup Sentry Tracing (Performance Monitoring) in any project. Use this when asked to add performance monitoring, enable tracing, track transactions/spans, or…
Setup Sentry Tracing (Performance Monitoring) in any project. Use this when asked to add performance monitoring, enable tracing, track transactions/spans, or…
Inspect the full instructions your agent will receiveExpandCollapse
This is the exact playbook injected into your agent when the skill activates — shown here so you can audit it before installing. You don't need to read it to use the skill.
by sentry
Setup Sentry Tracing (Performance Monitoring) in any project. Use this when asked to add performance monitoring, enable tracing, track transactions/spans, or…
npx skills add https://github.com/getsentry/sentry-for-cursor --skill sentry-setup-tracing
Download ZIPGitHub2
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
tracesSampleRateor custom spans
Platform Detection
Before configuring, detect the project's platform:
JavaScript/TypeScript
Check package.json for:
-
@sentry/nextjs- Next.js -
@sentry/react- React -
@sentry/node- Node.js -
@sentry/browser- Browser/vanilla JS -
@sentry/vue- Vue -
@sentry/angular- Angular -
@sentry/sveltekit- SvelteKit
Python
Check for sentry-sdk in requirements
Ruby
Check for sentry-ruby in Gemfile
Core 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)
Browser Tracing Integration Options
The browserTracingIntegration() accepts many configuration options:
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,
}),
],
});
Custom Instrumentation
JavaScript Custom Spans
Using startSpan (Recommended)
// 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);
}
);
Nested Spans
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();
});
});
Manual Span Control
function middleware(req, res, next) {
return Sentry.startSpanManual({ name: "middleware", op: "middleware" }, (span) => {
res.once("finish", () => {
span.setStatus({ code: res.statusCode
## Distributed Tracing
### How It Works
Sentry propagates trace context via HTTP headers:
- `sentry-trace`: Contains trace ID, span ID, sampling decision
- `baggage`: Contains additional trace metadata
### Configure Trace Propagation Targets
Only URLs matching these patterns receive trace headers:
Sentry.init({ tracePropagationTargets: [ "localhost", "https://api.yourapp.com", /^https://.*.yourapp.com/api/, ], });
### Server-Side Rendering (Meta Tags)
For SSR apps, inject trace data in HTML:
// Server renders these meta tags const traceData = Sentry.getTraceData(); // Include in HTML : // //
The browser SDK automatically reads these and continues the trace.
### Manual Propagation
For non-HTTP channels (WebSockets, message queues):
// Sender const traceData = Sentry.getTraceData(); sendMessage({ ...payload, _traceHeaders: traceData, });
// Receiver Sentry.continueTrace( { sentryTrace: message._traceHeaders["sentry-trace"], baggage: message._traceHeaders["baggage"], }, () => { processMessage(message); } );
## Common Operation Types
Use consistent `op` values for better organization:
Operation Use Case
`http.client` Outgoing HTTP requests
`http.server` Incoming HTTP requests
`db` Database operations
`db.query` Database queries
`cache` Cache operations
`task` Background tasks
`function` Function execution
`ui.render` UI rendering
`ui.action` User interactions
`serialize` Serialization
`middleware` Middleware execution
## What Gets Automatically Traced
### Browser (with browserTracingIntegration)
- Page loads
- Navigation/route changes
- XHR/fetch requests
- Long tasks
- Interaction to Next Paint (INP)
### Next.js
- API routes
- Server components
- Page renders
- Data fetching
### Node.js (with framework integrations)
- HTTP requests (Express, Fastify, etc.)
- Database queries (with ORM integrations)
- External API calls
### Python (with framework integrations)
- Django views, middleware, templates
- Flask routes
- FastAPI endpoints
- SQLAlchemy queries
- Celery tasks
## Disabling Tracing
**Important:** Setting `tracesSampleRate: 0` does NOT disable tracing - it still processes traces but never sends them.
To fully disable tracing, omit both sampling options:
Sentry.init({ dsn: "YOUR_DSN_HERE", // Do NOT include tracesSampleRate or tracesSampler });
## Production Sampling Recommendations
Traffic Level Recommended Rate
Development/Testing `1.0` (100%)
Low traffic (<1K req/min) `0.5` - `1.0`
Medium traffic (1K-10K req/min) `0.1` - `0.5`
High traffic (>10K req/min) `0.01` - `0.1`
Use dynamic sampling to capture more of important transactions:
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
After setup, verify tracing is working:
### 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("Tracing test")
**Check in Sentry:**
- Go to **Performance** section
- Look for your test transaction
- Verify spans appear in the trace waterfall
## Summary Checklist
Quick Reference
Platform Enable Tracing Custom Span
JS/Browser tracesSampleRate + browserTracingIntegration() Sentry.startSpan()
Next.js tracesSampleRate (auto-integrated) Sentry.startSpan()
Node.js tracesSampleRate Sentry.startSpan()
Python traces_sample_rate @sentry_sdk.trace or start_span()
Ruby traces_sample_rate start_span()
Sampling Option Purpose
tracesSampleRate Uniform percentage (0-1)
tracesSampler Dynamic function (takes precedence)
npx skills add https://github.com/getsentry/sentry-for-cursor --skill sentry-setup-tracingRun this in your project — your agent picks the skill up automatically.
Setup Sentry Tracing
This skill helps configure Sentry's Tracing (Performance Monitoring) to track application performance, measure latency, and create distributed traces across services.
JavaScript/TypeScript Configuration
Step 1: Locate Sentry Init
Find the Sentry.init() call:
-
Next.js:
instrumentation-client.ts,sentry.server.config.ts,sentry.edge.config.ts -
React:
src/index.tsxor entry file -
Node.js: Entry point or config file
-
Vue/Angular: Main app initialization
Step 2: Enable Tracing
Browser/React - Add browserTracingIntegration
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/,
],
});
Next.js - Configure All Init Files
Client (instrumentation-client.ts):
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.ts):
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
});
Edge (sentry.edge.config.ts):
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:
// app/layout.tsx
import * as Sentry from "@sentry/nextjs";
export async function generateMetadata() {
return {
other: {
...Sentry.getTraceData(),
},
};
}
Node.js
const Sentry = require("@sentry/node");
Sentry.init({
dsn: "YOUR_DSN_HERE",
tracesSampleRate: 1.0,
});
Step 3: Configure Sampling
Option A: Uniform Sample Rate (Simple)
Sentry.init({
// Capture 20% of all transactions
tracesSampleRate: 0.2,
});
Option B: Dynamic Sampling (Advanced)
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 tracesSampleRate and tracesSampler are set, tracesSampler takes precedence.
Python Configuration
Step 1: Enable Tracing
import sentry_sdk
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=1.0, # 100% for testing
)
Step 2: Configure Sampling
Uniform Rate
sentry_sdk.init(
dsn="YOUR_DSN_HERE",
traces_sample_rate=0.2, # 20% of transactions
)
Dynamic Sampling
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,
)
Ruby Configuration
Enable Tracing
Sentry.init do |config|
config.dsn = "YOUR_DSN_HERE"
config.traces_sample_rate = 1.0 # 100% for testing
end
Dynamic Sampling
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
end
Sentry Tracing Setup Complete
Configuration Applied:
-
tracesSampleRateortracesSamplerconfigured - Browser:
browserTracingIntegration()added -
tracePropagationTargetsconfigured for APIs - Next.js App Router:
getTraceData()in metadata
Sampling Strategy:
- Development: 100% sampling for testing
- Production: Appropriate rate based on traffic
Custom Instrumentation (if applicable):
- Critical paths instrumented with custom spans
- Consistent
opvalues used
Next Steps:
- Trigger some requests in your application
- Check Sentry > Performance for transactions
- Review trace waterfalls for span hierarchy
- Adjust sampling rates based on volume
Common Issues and Solutions
Issue: Transactions not appearing
Solutions:
-
Verify
tracesSampleRate > 0ortracesSamplerreturns > 0 -
Check DSN is correct
-
For browser: Ensure
browserTracingIntegration()is added -
Wait a few minutes for data to process
Issue: Distributed traces not connected
Solutions:
-
Check
tracePropagationTargetsincludes your API URLs -
Verify CORS allows
sentry-traceandbaggageheaders -
For SSR: Ensure trace meta tags are rendered
Issue: Too many transactions (high volume)
Solutions:
-
Lower
tracesSampleRate -
Use
tracesSamplerto filter by transaction name -
Use
shouldCreateSpanForRequestto skip health checks
Issue: Spans not nested correctly
Solutions:
-
Ensure parent span is still active when creating child
-
Use
startSpancallback pattern (not manual) -
For browser: Consider
parentSpanIsAlwaysRootSpan: false