Sentry - Performance Monitoring
Track application performance with transactions, spans, and distributed tracing.
Enable Performance Monitoring
import * as Sentry from "@sentry/browser";
Sentry.init({ dsn: "...", tracesSampleRate: 0.2, // 20% of transactions integrations: [ Sentry.browserTracingIntegration(), ], });
Transactions
Automatic Transactions
// Browser: Page loads and navigations Sentry.init({ integrations: [ Sentry.browserTracingIntegration({ tracePropagationTargets: ["localhost", /^https://api.example.com/], }), ], });
Manual Transactions
const transaction = Sentry.startTransaction({ op: "task", name: "Process Order", });
try { // Your code here processOrder(order); transaction.setStatus("ok"); } catch (error) { transaction.setStatus("internal_error"); throw error; } finally { transaction.finish(); }
Spans
Create Child Spans
const transaction = Sentry.startTransaction({ name: "checkout" });
const validationSpan = transaction.startChild({ op: "validation", description: "Validate cart items", }); await validateCart(cart); validationSpan.finish();
const paymentSpan = transaction.startChild({ op: "payment", description: "Process payment", }); await processPayment(payment); paymentSpan.finish();
transaction.finish();
Span Data
const span = transaction.startChild({ op: "db.query", description: "SELECT * FROM users WHERE id = ?", data: { "db.system": "postgresql", "db.name": "production", }, });
Distributed Tracing
Propagate Trace Context
// Frontend Sentry.init({ integrations: [ Sentry.browserTracingIntegration({ tracePropagationTargets: [ "localhost", /^https://api.yoursite.com/, ], }), ], });
// This automatically adds sentry-trace and baggage headers
Backend Continuation
// Express.js import * as Sentry from "@sentry/node";
app.use(Sentry.Handlers.requestHandler()); app.use(Sentry.Handlers.tracingHandler());
// The transaction is automatically continued from incoming headers
Sampling
Static Sampling
Sentry.init({ tracesSampleRate: 0.1, // 10% of transactions });
Dynamic Sampling
Sentry.init({ tracesSampler: (samplingContext) => { // Always sample errors if (samplingContext.parentSampled !== undefined) { return samplingContext.parentSampled; }
// High priority endpoints
if (samplingContext.name.includes("/checkout")) {
return 1.0;
}
// Don't sample health checks
if (samplingContext.name.includes("/health")) {
return 0;
}
// Default rate
return 0.1;
}, });
Web Vitals
// Automatically captured with browserTracingIntegration // LCP, FID, CLS, FCP, TTFB
Sentry.init({ integrations: [ Sentry.browserTracingIntegration({ enableLongTask: true, // Track long tasks }), ], });
Custom Metrics
// Capture custom metrics Sentry.metrics.increment("button_clicked", 1, { tags: { button: "checkout" }, });
Sentry.metrics.distribution("cart_value", cart.total, { unit: "dollar", tags: { currency: "USD" }, });
Sentry.metrics.gauge("active_users", activeCount);
Sentry.metrics.set("unique_visitors", visitorId);
Profiling
// Node.js import * as Sentry from "@sentry/node"; import { nodeProfilingIntegration } from "@sentry/profiling-node";
Sentry.init({ dsn: "...", integrations: [nodeProfilingIntegration()], tracesSampleRate: 1.0, profilesSampleRate: 1.0, });
Best Practices
-
Start with low sample rates, increase as needed
-
Use dynamic sampling for important transactions
-
Propagate trace context to all services
-
Add meaningful span descriptions
-
Track business-critical user flows
-
Use custom metrics for business KPIs
-
Enable profiling for performance-critical code