From 44d01cd721e75c0b1678b36e71d5219d58454865 Mon Sep 17 00:00:00 2001 From: paulj Date: Mon, 2 Feb 2026 11:43:53 -0500 Subject: [PATCH 01/21] docs(explore): Add practical "what to do next" guides for logs, metrics, and traces Add four new documentation pages that bridge the gap between SDK setup and getting value from Sentry's observability features: - what-to-log.mdx: High-value logging patterns with search and alert examples - what-to-track.mdx: Metric patterns for counters, gauges, and distributions - querying-traces.mdx: How to query auto-instrumented trace data - custom-spans.mdx: When and how to add custom instrumentation Each guide follows a consistent "5 things to add" structure with code examples, query patterns, and alert recommendations. Co-Authored-By: Claude --- docs/product/explore/logs/what-to-log.mdx | 205 ++++++++++++++++++ .../product/explore/metrics/what-to-track.mdx | 154 +++++++++++++ .../explore/trace-explorer/custom-spans.mdx | 170 +++++++++++++++ .../trace-explorer/querying-traces.mdx | 96 ++++++++ 4 files changed, 625 insertions(+) create mode 100644 docs/product/explore/logs/what-to-log.mdx create mode 100644 docs/product/explore/metrics/what-to-track.mdx create mode 100644 docs/product/explore/trace-explorer/custom-spans.mdx create mode 100644 docs/product/explore/trace-explorer/querying-traces.mdx diff --git a/docs/product/explore/logs/what-to-log.mdx b/docs/product/explore/logs/what-to-log.mdx new file mode 100644 index 0000000000000..ee5af404cca49 --- /dev/null +++ b/docs/product/explore/logs/what-to-log.mdx @@ -0,0 +1,205 @@ +--- +title: "What to Log" +sidebar_order: 5 +description: "Practical guidance on what to log, how to search logs, and when to set alerts." +--- + +You've set up Sentry Logs. Now what? This guide covers the high-value logging patterns that help you debug faster and catch problems before users report them. + +## The Pattern + +Every structured log follows the same format: + +```javascript +Sentry.logger.(message, { attributes }); +``` + +**Levels:** `trace`, `debug`, `info`, `warn`, `error`, `fatal` + +**Attributes:** Key-value pairs you can search and filter on. Use whatever naming convention fits your codebase—consistency matters more than specific names. + +```javascript +Sentry.logger.info("Order completed", { + orderId: "order_123", + userId: user.id, + amount: 149.99, + paymentMethod: "stripe" +}); +``` + +Every log is automatically trace-connected. Click any log entry to see the full trace, spans, and errors from that moment. + +## Where to Add Logs + +These five categories give you the most debugging value per line of code. + +### 1. Authentication Events + +Login flows are invisible until something breaks. Log successes and failures to spot patterns—brute force attempts, OAuth misconfigurations, or MFA issues. + +```javascript +Sentry.logger.info("User logged in", { + userId: user.id, + authMethod: "oauth", + provider: "google" +}); + +Sentry.logger.warn("Login failed", { + email: maskedEmail, + reason: "invalid_password", + attemptCount: 3 +}); +``` + +**Search:** `userId:123 "logged in"` or `severity:warn authMethod:*` + +**Alert idea:** `severity:warn "Login failed"` exceeding your baseline in 5 minutes can indicate brute force or auth provider issues. + +### 2. Payment and Checkout + +Money paths need visibility even when they succeed. When payments fail, you need context fast. + +```javascript +Sentry.logger.error("Payment failed", { + orderId: "order_123", + amount: 99.99, + gateway: "stripe", + errorCode: "card_declined", + cartItems: 3 +}); +``` + +**Search:** `orderId:order_123` or `severity:error gateway:stripe` + +**Alert idea:** `severity:error gateway:*` spiking can indicate payment provider outages. + +### 3. External APIs and Async Operations + +Traces capture what your code does. Logs capture context about external triggers and async boundaries—webhooks, scheduled tasks, third-party API responses—that traces can't automatically instrument. + +```javascript +// Third-party API call +const start = Date.now(); +const response = await shippingApi.getRates(items); + +Sentry.logger.info("Shipping rates fetched", { + service: "shipping-provider", + endpoint: "/rates", + durationMs: Date.now() - start, + rateCount: response.rates.length +}); + +// Webhook received +Sentry.logger.info("Webhook received", { + source: "stripe", + eventType: "payment_intent.succeeded", + paymentId: event.data.object.id +}); +``` + +**Search:** `service:shipping-provider durationMs:>2000` or `source:stripe` + +**Alert idea:** `service:* durationMs:>3000` can catch third-party slowdowns before they cascade. + +### 4. Background Jobs + +Jobs run outside request context. Without logs, failed jobs are invisible until someone notices missing data. + +```javascript +Sentry.logger.info("Job started", { + jobType: "email-digest", + jobId: "job_456", + queue: "notifications" +}); + +Sentry.logger.error("Job failed", { + jobType: "email-digest", + jobId: "job_456", + retryCount: 3, + lastError: "SMTP timeout" +}); +``` + +**Search:** `jobType:email-digest severity:error` + +**Alert idea:** `severity:error jobType:*` spiking can indicate queue processing issues or downstream failures. + +### 5. Feature Flags and Config Changes + +When something breaks after a deploy, the first question is "what changed?" Logging flag evaluations and config reloads gives you that answer instantly. + +```javascript +Sentry.logger.info("Feature flag evaluated", { + flag: "new-checkout-flow", + enabled: true, + userId: user.id +}); + +Sentry.logger.warn("Config reloaded", { + reason: "env-change", + changedKeys: ["API_TIMEOUT", "MAX_CONNECTIONS"] +}); +``` + +**Search:** `flag:new-checkout-flow` or `"Config reloaded"` + +## Creating Alerts From Logs + +1. Go to **Explore > Logs** +2. Enter your search query (e.g., `severity:error gateway:*`) +3. Click **Save As** → **Alert** +4. Choose a threshold type: + - **Static:** Alert when count exceeds a value + - **Percent Change:** Alert when count changes relative to a previous period + - **Anomaly:** Let Sentry detect unusual patterns +5. Configure notification channels and save + +## Production Logging Strategy + +Local debugging often means many small logs tracing execution flow. In production, this creates noise that's hard to query. + +Instead, log fewer messages with higher cardinality. Store events during execution and emit them as a single structured log. + +**Don't do this:** + +```javascript +Sentry.logger.info("Checkout started", { userId: "882" }); +Sentry.logger.info("Discount applied", { code: "WINTER20" }); +Sentry.logger.error("Payment failed", { reason: "Insufficient Funds" }); +``` + +These logs are trace-connected, but searching for the error won't return the userId or discount code from the same transaction. + +**Do this instead:** + +```javascript +Sentry.logger.error("Checkout failed", { + userId: "882", + orderId: "order_pc_991", + cartTotal: 142.50, + discountCode: "WINTER20", + paymentMethod: "stripe", + errorReason: "Insufficient Funds", + itemCount: 4 +}); +``` + +One log tells the whole story. Search for the error and get full context. + +## Log Drains for Platform Logs + +If you can't install the Sentry SDK or need platform-level logs (CDN, database, load balancer), use [Log Drains](/product/drains/). + +**Platform drains:** Vercel, Cloudflare Workers, Heroku, Supabase + +**Forwarders:** OpenTelemetry Collector, Vector, Fluent Bit, AWS CloudWatch, Kafka + +## Quick Reference + +| Category | Level | Key Attributes | +|----------|-------|----------------| +| Auth events | `info`/`warn` | userId, authMethod, reason | +| Payments | `info`/`error` | orderId, amount, gateway, errorCode | +| External APIs | `info` | service, endpoint, durationMs | +| Background jobs | `info`/`error` | jobType, jobId, retryCount | +| Feature flags | `info` | flag, enabled, changedKeys | diff --git a/docs/product/explore/metrics/what-to-track.mdx b/docs/product/explore/metrics/what-to-track.mdx new file mode 100644 index 0000000000000..e1b9a49c69820 --- /dev/null +++ b/docs/product/explore/metrics/what-to-track.mdx @@ -0,0 +1,154 @@ +--- +title: "What to Track" +sidebar_order: 5 +description: "Practical guidance on what metrics to track and how to explore them in Sentry." +--- + +You've set up Sentry Metrics. Now what? This guide covers the high-value metric patterns that give you visibility into application health—and how to drill into traces when something looks off. + +## The Pattern + +Sentry supports three metric types: + +| Type | Method | Use For | +|------|--------|---------| +| **Counter** | `Sentry.metrics.count()` | Events that happen (orders, clicks, errors) | +| **Gauge** | `Sentry.metrics.gauge()` | Current state (queue depth, connections) | +| **Distribution** | `Sentry.metrics.distribution()` | Values that vary (latency, sizes, amounts) | + +Every metric is trace-connected. When a metric spikes, click into samples to see the exact trace that produced it. + +```javascript +Sentry.metrics.count("checkout.failed", 1, { + attributes: { + user_tier: "premium", + failure_reason: "payment_declined" + } +}); +``` + +## Where to Add Metrics + +These five categories give you the most visibility per line of code. + +### 1. Business Events (Counters) + +Track discrete events that matter to the business. These become your KPIs. + +```javascript +Sentry.metrics.count("checkout.completed", 1, { + attributes: { user_tier: "premium", payment_method: "card" } +}); + +Sentry.metrics.count("checkout.failed", 1, { + attributes: { user_tier: "premium", failure_reason: "payment_declined" } +}); +``` + +**How to explore:** +1. Go to **Explore > Metrics** +2. Select `checkout.failed`, set **Agg** to `sum` +3. **Group by** `failure_reason` +4. Click **Samples** to see individual events and their traces + +### 2. Application Health (Counters) + +Track success and failure of critical operations. + +```javascript +Sentry.metrics.count("email.sent", 1, { + attributes: { email_type: "welcome", provider: "sendgrid" } +}); + +Sentry.metrics.count("email.failed", 1, { + attributes: { email_type: "welcome", error: "rate_limited" } +}); + +Sentry.metrics.count("job.processed", 1, { + attributes: { job_type: "invoice-generation", queue: "billing" } +}); +``` + +**Explore:** Add both `email.sent` and `email.failed`, group by `email_type`, compare the ratio. + +### 3. Resource Utilization (Gauges) + +Track current state of pools, queues, and connections. Call these periodically (e.g., every 30 seconds). + +```javascript +Sentry.metrics.gauge("queue.depth", await queue.size(), { + attributes: { queue_name: "notifications" } +}); + +Sentry.metrics.gauge("pool.connections_active", pool.activeConnections, { + attributes: { pool_name: "postgres-primary" } +}); +``` + +**Explore:** View `max(queue.depth)` over time to spot backlogs. + +### 4. Latency and Performance (Distributions) + +Track values that vary and need percentile analysis. Averages hide outliers—use p90/p95/p99. + +```javascript +Sentry.metrics.distribution("api.latency", responseTimeMs, { + unit: "millisecond", + attributes: { endpoint: "/api/orders", method: "POST" } +}); + +Sentry.metrics.distribution("db.query_time", queryDurationMs, { + unit: "millisecond", + attributes: { table: "orders", operation: "select" } +}); +``` + +**Explore:** View `p95(api.latency)` grouped by `endpoint` to find slow routes. + +### 5. Business Values (Distributions) + +Track amounts, sizes, and quantities for analysis. + +```javascript +Sentry.metrics.distribution("order.amount", order.totalUsd, { + unit: "usd", + attributes: { user_tier: "premium", region: "us-west" } +}); + +Sentry.metrics.distribution("upload.size", fileSizeBytes, { + unit: "byte", + attributes: { file_type: "image", source: "profile-update" } +}); +``` + +**Explore:** View `avg(order.amount)` grouped by `region` to compare regional performance. + +## The Debugging Flow + +When something looks off in metrics, here's how to find the cause: + +``` +Metric spike → Samples tab → Click a sample → Full trace → Related logs/errors → Root cause +``` + +This is the advantage of trace-connected metrics. Instead of "metric alert → guesswork," you get direct links to exactly what happened. + +## When to Use Metrics vs Traces vs Logs + +| Signal | Best For | Example Question | +|--------|----------|------------------| +| **Metrics** | Aggregated counts, rates, percentiles | "How many checkouts failed this hour?" | +| **Traces** | Request flow, latency breakdown | "Why was this specific request slow?" | +| **Logs** | Detailed context, debugging | "What happened right before this error?" | + +All three are trace-connected. Start wherever makes sense and navigate to the others. + +## Quick Reference + +| Category | Type | Metric Name Examples | Key Attributes | +|----------|------|---------------------|----------------| +| Business events | `count` | checkout.completed, checkout.failed | user_tier, failure_reason | +| App health | `count` | email.sent, job.processed | email_type, job_type | +| Resources | `gauge` | queue.depth, pool.connections_active | queue_name, pool_name | +| Latency | `distribution` | api.latency, db.query_time | endpoint, table, operation | +| Business values | `distribution` | order.amount, upload.size | user_tier, region, file_type | diff --git a/docs/product/explore/trace-explorer/custom-spans.mdx b/docs/product/explore/trace-explorer/custom-spans.mdx new file mode 100644 index 0000000000000..4fa4a2cf5abb4 --- /dev/null +++ b/docs/product/explore/trace-explorer/custom-spans.mdx @@ -0,0 +1,170 @@ +--- +title: "Adding Custom Spans" +sidebar_order: 15 +description: "Add custom instrumentation for visibility beyond auto-instrumentation." +--- + +Auto-instrumentation captures a lot, but some operations need manual spans. This guide covers when and how to add custom instrumentation. + +## When to Add Custom Spans + +Add custom spans when you need visibility that auto-instrumentation doesn't provide: + +- Business-critical flows (checkout, onboarding) +- Third-party API calls with custom context +- Database queries with business context +- Background job execution +- AI/LLM operations + +## The Pattern + +```javascript +Sentry.startSpan( + { name: "operation-name", op: "category" }, + async (span) => { + span.setAttribute("key", value); + // ... your code ... + } +); +``` + +Numeric attributes become metrics you can aggregate with `sum()`, `avg()`, `p90()` in Trace Explorer. + +## Where to Add Custom Spans + +### Business-Critical User Flows + +Track the full journey through critical paths. When checkout is slow, you need to know which step. + +```javascript +Sentry.startSpan( + { name: "checkout-flow", op: "user.action" }, + async (span) => { + span.setAttribute("cart.itemCount", 3); + span.setAttribute("user.tier", "premium"); + + await validateCart(); + await processPayment(); + await createOrder(); + } +); +``` + +**Query:** `span.op:user.action` grouped by `user.tier`, visualize `p90(span.duration)`. + +**Alert idea:** `p90(span.duration) > 10s` for checkout flows. + +### Third-Party API Calls + +Measure dependencies you don't control. They're often the source of slowdowns. + +```javascript +Sentry.startSpan( + { name: "shipping-rates-api", op: "http.client" }, + async (span) => { + span.setAttribute("http.url", "api.shipper.com/rates"); + span.setAttribute("request.itemCount", items.length); + + const start = Date.now(); + const response = await fetch("https://api.shipper.com/rates"); + + span.setAttribute("http.status_code", response.status); + span.setAttribute("response.timeMs", Date.now() - start); + + return response.json(); + } +); +``` + +**Query:** `span.op:http.client` + `response.timeMs:>2000` to find slow external calls. + +**Alert idea:** `p95(span.duration) > 3s` where `http.url` contains your critical dependencies. + +### Database Queries with Business Context + +Auto-instrumentation catches queries, but custom spans let you add context that explains why a query matters. + +```javascript +Sentry.startSpan( + { name: "load-user-dashboard", op: "db.query" }, + async (span) => { + span.setAttribute("db.system", "postgres"); + span.setAttribute("query.type", "aggregation"); + span.setAttribute("query.dateRange", "30d"); + + const results = await db.query(dashboardQuery); + span.setAttribute("result.rowCount", results.length); + + return results; + } +); +``` + +**Why this matters:** Without these attributes, you see "a database query took 2 seconds." With them, you know it was aggregating 30 days of data and returned 50,000 rows. That's actionable. + +**Query ideas:** +- "Which aggregation queries are slowest?" → Group by `query.type`, sort by `p90(span.duration)` +- "Does date range affect performance?" → Filter by name, group by `query.dateRange` + +### Background Jobs + +Jobs run outside request context. Custom spans make them visible. + +```javascript +async function processEmailDigest(job) { + return Sentry.startSpan( + { name: `job:${job.type}`, op: "queue.process" }, + async (span) => { + span.setAttribute("job.id", job.id); + span.setAttribute("job.type", "email-digest"); + span.setAttribute("queue.name", "notifications"); + + const users = await getDigestRecipients(); + span.setAttribute("job.recipientCount", users.length); + + for (const user of users) { + await sendDigest(user); + } + + span.setAttribute("job.status", "completed"); + } + ); +} +``` + +**Query:** `span.op:queue.process` grouped by `job.type`, visualize `p90(span.duration)`. + +**Alert idea:** `p90(span.duration) > 60s` for queue processing. + +### AI/LLM Operations + +For AI workloads, use [Sentry Agent Monitoring](/product/insights/ai/agents/) instead of manual instrumentation when possible. It automatically captures agent workflows, tool calls, and token usage. + +If you're not using a supported framework or need custom attributes: + +```javascript +Sentry.startSpan( + { name: "generate-summary", op: "ai.inference" }, + async (span) => { + span.setAttribute("ai.model", "gpt-4"); + span.setAttribute("ai.feature", "document-summary"); + + const response = await openai.chat.completions.create({...}); + + span.setAttribute("ai.tokens.total", response.usage.total_tokens); + return response; + } +); +``` + +**Alert idea:** `p95(span.duration) > 5s` for AI inference. + +## Quick Reference + +| Category | `op` Value | Key Attributes | +|----------|-----------|----------------| +| User flows | `user.action` | cart.itemCount, user.tier | +| External APIs | `http.client` | http.url, response.timeMs | +| Database | `db.query` | query.type, result.rowCount | +| Background jobs | `queue.process` | job.type, job.id, queue.name | +| AI/LLM | `ai.inference` | ai.model, ai.tokens.total | diff --git a/docs/product/explore/trace-explorer/querying-traces.mdx b/docs/product/explore/trace-explorer/querying-traces.mdx new file mode 100644 index 0000000000000..aac272f8f879e --- /dev/null +++ b/docs/product/explore/trace-explorer/querying-traces.mdx @@ -0,0 +1,96 @@ +--- +title: "Querying Auto-Instrumented Traces" +sidebar_order: 10 +description: "Find performance issues using data Sentry captures automatically." +--- + +Sentry's browser SDK automatically captures page loads, navigation, fetch requests, and resource loading. This guide shows you how to query that data to find performance issues—no custom code required. + +## What's Auto-Instrumented + +With `browserTracingIntegration()` enabled, Sentry automatically captures: + +- Page loads and navigation +- Fetch/XHR requests +- Long animation frames (main thread blocking) +- Resource loading (JS, CSS, images) + +## Finding Performance Issues + +### Slow Page Loads + +Pages taking too long to become interactive. + +**Query:** `span.op:pageload` + +**Visualize:** `p90(span.duration)` grouped by `transaction` to compare routes. + +**Alert idea:** `p75(transaction.duration) > 3s` for pageload transactions. + +### Slow API Calls + +Fetch/XHR requests dragging down your app. + +**Query:** `span.op:http.client` + +**Visualize:** `avg(span.duration)` grouped by `span.description` (the URL). + +**Alert idea:** `p95(span.duration) > 2s` where `span.op:http.client`. + +### JavaScript Blocking the Main Thread + +Long animation frames indicate JavaScript execution blocking the UI. + +**Query:** `span.op:ui.long-animation-frame` + +**Visualize:** Sort by `span.duration` to find the worst offenders. + +**Alert idea:** `p75(span.duration) > 200ms` for long animation frames. + +### Slow SPA Navigation + +How long it takes users to move between pages after initial load. + +**Query:** `span.op:navigation` + +**Visualize:** `p90(span.duration)` grouped by `transaction` to compare route performance. + +**Alert idea:** `p75(span.duration) > 2s` for navigation. + +### Heavy Resources + +JS bundles, stylesheets, or images slowing down page load. + +**Queries:** +- `span.op:resource.script` (JavaScript) +- `span.op:resource.css` (stylesheets) +- `span.op:resource.img` (images) + +**Visualize:** `avg(span.duration)` to find the heaviest assets. + +**Alert idea:** `p75(span.duration) > 3s` for resource.script. + +## Creating Trace-Based Alerts + +1. Go to **Explore > Traces** +2. Build your query (e.g., `span.op:http.client`) +3. Click **Save As** → **Alert** +4. Choose a threshold type: + - **Static:** Set a specific threshold + - **Percent Change:** Alert on relative change + - **Anomaly:** Let Sentry detect unusual patterns +5. Configure notifications and save + +**Tip:** Alert on percentiles (p75, p95) rather than averages. Averages hide the outliers that hurt real users. + +## Quick Reference + +| What You're Looking For | Query | Visualize | +|------------------------|-------|-----------| +| Slow page loads | `span.op:pageload` | `p90(span.duration)` by route | +| Slow fetch requests | `span.op:http.client` | `avg(span.duration)` by URL | +| JS blocking UI | `span.op:ui.long-animation-frame` | `max(span.duration)` | +| Slow SPA navigation | `span.op:navigation` | `p90(span.duration)` by route | +| Heavy JS bundles | `span.op:resource.script` | `avg(span.duration)` | +| Heavy stylesheets | `span.op:resource.css` | `avg(span.duration)` | +| Slow images | `span.op:resource.img` | `avg(span.duration)` | From 12f3ba87e0d4e98c3835c995c51c081c3d33ae31 Mon Sep 17 00:00:00 2001 From: paulj Date: Fri, 13 Feb 2026 19:18:45 -0500 Subject: [PATCH 02/21] logs updates --- docs/product/explore/logs/what-to-log.mdx | 41 ++++++++++++----------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/docs/product/explore/logs/what-to-log.mdx b/docs/product/explore/logs/what-to-log.mdx index ee5af404cca49..29404df8f215b 100644 --- a/docs/product/explore/logs/what-to-log.mdx +++ b/docs/product/explore/logs/what-to-log.mdx @@ -16,7 +16,7 @@ Sentry.logger.(message, { attributes }); **Levels:** `trace`, `debug`, `info`, `warn`, `error`, `fatal` -**Attributes:** Key-value pairs you can search and filter on. Use whatever naming convention fits your codebase—consistency matters more than specific names. +**Attributes:** Key-value pairs you can search and filter on. Consistency matters, so use whatever naming convention fits your codebase. ```javascript Sentry.logger.info("Order completed", { @@ -27,15 +27,15 @@ Sentry.logger.info("Order completed", { }); ``` -Every log is automatically trace-connected. Click any log entry to see the full trace, spans, and errors from that moment. +Logs in Sentry are automatically trace-connected. Each log shows a trace ID that links to the full [trace view](/concepts/key-terms/tracing/trace-view/). ## Where to Add Logs -These five categories give you the most debugging value per line of code. +Start with these five areas and you'll catch most issues before users do. ### 1. Authentication Events -Login flows are invisible until something breaks. Log successes and failures to spot patterns—brute force attempts, OAuth misconfigurations, or MFA issues. +Login flows are invisible until something breaks. Log successes and failures to spot patterns like brute force attempts, OAuth misconfigurations, or MFA issues. ```javascript Sentry.logger.info("User logged in", { @@ -51,9 +51,9 @@ Sentry.logger.warn("Login failed", { }); ``` -**Search:** `userId:123 "logged in"` or `severity:warn authMethod:*` +**Search in Sentry:** `userId:123 "logged in"` or `severity:warn authMethod:*` -**Alert idea:** `severity:warn "Login failed"` exceeding your baseline in 5 minutes can indicate brute force or auth provider issues. +**Alert idea:** Alert when `severity:warn "Login failed"` spikes in a 5-minute window—this can indicate brute force attempts or auth provider issues. ### 2. Payment and Checkout @@ -69,13 +69,13 @@ Sentry.logger.error("Payment failed", { }); ``` -**Search:** `orderId:order_123` or `severity:error gateway:stripe` +**Search in Sentry:** `orderId:order_123` or `severity:error gateway:stripe` -**Alert idea:** `severity:error gateway:*` spiking can indicate payment provider outages. +**Alert idea:** Alert when `severity:error gateway:*` spikes—this can indicate payment provider outages. ### 3. External APIs and Async Operations -Traces capture what your code does. Logs capture context about external triggers and async boundaries—webhooks, scheduled tasks, third-party API responses—that traces can't automatically instrument. +Traces capture what your code does. Logs capture context about external triggers and async boundaries. Things like webhooks, scheduled tasks, and third-party API responses that traces can't automatically instrument. ```javascript // Third-party API call @@ -97,13 +97,13 @@ Sentry.logger.info("Webhook received", { }); ``` -**Search:** `service:shipping-provider durationMs:>2000` or `source:stripe` +**Search in Sentry:** `service:shipping-provider durationMs:>2000` or `source:stripe` -**Alert idea:** `service:* durationMs:>3000` can catch third-party slowdowns before they cascade. +**Alert idea:** Alert when `service:* durationMs:>3000` to catch third-party slowdowns before they cascade. ### 4. Background Jobs -Jobs run outside request context. Without logs, failed jobs are invisible until someone notices missing data. +Jobs run outside the request context. Without logs, failed jobs are invisible until someone notices missing data. ```javascript Sentry.logger.info("Job started", { @@ -120,9 +120,9 @@ Sentry.logger.error("Job failed", { }); ``` -**Search:** `jobType:email-digest severity:error` +**Search in Sentry:** `jobType:email-digest severity:error` -**Alert idea:** `severity:error jobType:*` spiking can indicate queue processing issues or downstream failures. +**Alert idea:** Alert when `severity:error jobType:*` spikes—this can indicate queue processing issues or downstream failures. ### 5. Feature Flags and Config Changes @@ -141,21 +141,24 @@ Sentry.logger.warn("Config reloaded", { }); ``` -**Search:** `flag:new-checkout-flow` or `"Config reloaded"` +**Search in Sentry:** `flag:new-checkout-flow` or `"Config reloaded"` ## Creating Alerts From Logs +{/* TODO: replace with Arcade */} + 1. Go to **Explore > Logs** 2. Enter your search query (e.g., `severity:error gateway:*`) -3. Click **Save As** → **Alert** +3. Click **Save As** - **Alert** 4. Choose a threshold type: - **Static:** Alert when count exceeds a value - **Percent Change:** Alert when count changes relative to a previous period - **Anomaly:** Let Sentry detect unusual patterns 5. Configure notification channels and save -## Production Logging Strategy +# Logging Strategy +## Production Logging Local debugging often means many small logs tracing execution flow. In production, this creates noise that's hard to query. Instead, log fewer messages with higher cardinality. Store events during execution and emit them as a single structured log. @@ -190,9 +193,9 @@ One log tells the whole story. Search for the error and get full context. If you can't install the Sentry SDK or need platform-level logs (CDN, database, load balancer), use [Log Drains](/product/drains/). -**Platform drains:** Vercel, Cloudflare Workers, Heroku, Supabase +**Platform drains:** [Vercel](/product/drains/vercel/), [Cloudflare Workers](/product/drains/cloudflare/), [Heroku](/product/drains/heroku/), [Supabase](/product/drains/supabase/) -**Forwarders:** OpenTelemetry Collector, Vector, Fluent Bit, AWS CloudWatch, Kafka +**Forwarders:** [OpenTelemetry Collector](/concepts/otlp/forwarding/pipelines/collector/), [Vector](/concepts/otlp/forwarding/pipelines/vector/), [Fluent Bit](/concepts/otlp/forwarding/pipelines/fluentbit/), [AWS CloudWatch](/concepts/otlp/forwarding/sources/aws-cloudwatch/), [Kafka](/concepts/otlp/forwarding/sources/kafka/) ## Quick Reference From 3ff737dfc10afb620032ea1134d8433f0254a60d Mon Sep 17 00:00:00 2001 From: paulj Date: Fri, 13 Feb 2026 21:43:49 -0500 Subject: [PATCH 03/21] metrics updates --- .../product/explore/metrics/what-to-track.mdx | 30 ++++--------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/docs/product/explore/metrics/what-to-track.mdx b/docs/product/explore/metrics/what-to-track.mdx index e1b9a49c69820..03b4633871a6d 100644 --- a/docs/product/explore/metrics/what-to-track.mdx +++ b/docs/product/explore/metrics/what-to-track.mdx @@ -4,7 +4,7 @@ sidebar_order: 5 description: "Practical guidance on what metrics to track and how to explore them in Sentry." --- -You've set up Sentry Metrics. Now what? This guide covers the high-value metric patterns that give you visibility into application health—and how to drill into traces when something looks off. +You've set up Sentry Metrics. Now what? This guide covers the high-value metric patterns that give you visibility into application health and how to drill into traces when something looks off. ## The Pattern @@ -29,7 +29,7 @@ Sentry.metrics.count("checkout.failed", 1, { ## Where to Add Metrics -These five categories give you the most visibility per line of code. +Try these five metrics and you'll spot issues before they become problems. ### 1. Business Events (Counters) @@ -47,7 +47,7 @@ Sentry.metrics.count("checkout.failed", 1, { **How to explore:** 1. Go to **Explore > Metrics** -2. Select `checkout.failed`, set **Agg** to `sum` +2. Select `checkout.failed`, set **Aggregate** to `sum` 3. **Group by** `failure_reason` 4. Click **Samples** to see individual events and their traces @@ -89,7 +89,7 @@ Sentry.metrics.gauge("pool.connections_active", pool.activeConnections, { ### 4. Latency and Performance (Distributions) -Track values that vary and need percentile analysis. Averages hide outliers—use p90/p95/p99. +Track values that vary and need percentile analysis. **Tip:** averages can hide outliers, use p90/p95/p99 instead. ```javascript Sentry.metrics.distribution("api.latency", responseTimeMs, { @@ -123,16 +123,6 @@ Sentry.metrics.distribution("upload.size", fileSizeBytes, { **Explore:** View `avg(order.amount)` grouped by `region` to compare regional performance. -## The Debugging Flow - -When something looks off in metrics, here's how to find the cause: - -``` -Metric spike → Samples tab → Click a sample → Full trace → Related logs/errors → Root cause -``` - -This is the advantage of trace-connected metrics. Instead of "metric alert → guesswork," you get direct links to exactly what happened. - ## When to Use Metrics vs Traces vs Logs | Signal | Best For | Example Question | @@ -141,14 +131,4 @@ This is the advantage of trace-connected metrics. Instead of "metric alert → g | **Traces** | Request flow, latency breakdown | "Why was this specific request slow?" | | **Logs** | Detailed context, debugging | "What happened right before this error?" | -All three are trace-connected. Start wherever makes sense and navigate to the others. - -## Quick Reference - -| Category | Type | Metric Name Examples | Key Attributes | -|----------|------|---------------------|----------------| -| Business events | `count` | checkout.completed, checkout.failed | user_tier, failure_reason | -| App health | `count` | email.sent, job.processed | email_type, job_type | -| Resources | `gauge` | queue.depth, pool.connections_active | queue_name, pool_name | -| Latency | `distribution` | api.latency, db.query_time | endpoint, table, operation | -| Business values | `distribution` | order.amount, upload.size | user_tier, region, file_type | +All three are trace-connected. Start wherever makes sense and navigate to the others. \ No newline at end of file From e7d11299dc53f84cc501545873f638aa87e1072f Mon Sep 17 00:00:00 2001 From: paulj Date: Fri, 13 Feb 2026 22:48:26 -0500 Subject: [PATCH 04/21] updates --- .../custom-spans.mdx | 44 +++--- docs/guides/index.mdx | 11 ++ .../logs/what-to-log.mdx => guides/logs.mdx} | 35 ++++- .../what-to-track.mdx => guides/metrics.mdx} | 67 ++++++--- docs/guides/querying-traces.mdx | 85 ++++++++++++ docs/guides/session-replay.mdx | 127 ++++++++++++++++++ .../trace-explorer/querying-traces.mdx | 96 ------------- src/components/sidebar/sidebarNavigation.tsx | 4 + 8 files changed, 327 insertions(+), 142 deletions(-) rename docs/{product/explore/trace-explorer => guides}/custom-spans.mdx (77%) create mode 100644 docs/guides/index.mdx rename docs/{product/explore/logs/what-to-log.mdx => guides/logs.mdx} (85%) rename docs/{product/explore/metrics/what-to-track.mdx => guides/metrics.mdx} (59%) create mode 100644 docs/guides/querying-traces.mdx create mode 100644 docs/guides/session-replay.mdx delete mode 100644 docs/product/explore/trace-explorer/querying-traces.mdx diff --git a/docs/product/explore/trace-explorer/custom-spans.mdx b/docs/guides/custom-spans.mdx similarity index 77% rename from docs/product/explore/trace-explorer/custom-spans.mdx rename to docs/guides/custom-spans.mdx index 4fa4a2cf5abb4..2ca6fdbadf1ad 100644 --- a/docs/product/explore/trace-explorer/custom-spans.mdx +++ b/docs/guides/custom-spans.mdx @@ -1,20 +1,10 @@ --- title: "Adding Custom Spans" -sidebar_order: 15 -description: "Add custom instrumentation for visibility beyond auto-instrumentation." +sidebar_order: 30 +description: "Add custom instrumentation for visibility beyond auto-instrumentation and set up alerts." --- -Auto-instrumentation captures a lot, but some operations need manual spans. This guide covers when and how to add custom instrumentation. - -## When to Add Custom Spans - -Add custom spans when you need visibility that auto-instrumentation doesn't provide: - -- Business-critical flows (checkout, onboarding) -- Third-party API calls with custom context -- Database queries with business context -- Background job execution -- AI/LLM operations +You've got auto-instrumentation running. Now what? Auto-instrumentation captures HTTP, database, and framework operations, but it can't see business logic, third-party APIs without auto-instrumentation, or background jobs. This guide shows you where to add custom spans. ## The Pattern @@ -30,9 +20,11 @@ Sentry.startSpan( Numeric attributes become metrics you can aggregate with `sum()`, `avg()`, `p90()` in Trace Explorer. -## Where to Add Custom Spans +## Where to Add Spans + +Start with these five areas and you'll have visibility into the operations that matter most. -### Business-Critical User Flows +### 1. Business-Critical User Flows Track the full journey through critical paths. When checkout is slow, you need to know which step. @@ -50,11 +42,11 @@ Sentry.startSpan( ); ``` -**Query:** `span.op:user.action` grouped by `user.tier`, visualize `p90(span.duration)`. +**Query in Explore > Traces:** `span.op:user.action` grouped by `user.tier`, visualize `p90(span.duration)`. **Alert idea:** `p90(span.duration) > 10s` for checkout flows. -### Third-Party API Calls +### 2. Third-Party API Calls Measure dependencies you don't control. They're often the source of slowdowns. @@ -76,11 +68,11 @@ Sentry.startSpan( ); ``` -**Query:** `span.op:http.client` + `response.timeMs:>2000` to find slow external calls. +**Query in Explore > Traces:** `span.op:http.client response.timeMs:>2000` to find slow external calls. **Alert idea:** `p95(span.duration) > 3s` where `http.url` contains your critical dependencies. -### Database Queries with Business Context +### 3. Database Queries with Business Context Auto-instrumentation catches queries, but custom spans let you add context that explains why a query matters. @@ -102,11 +94,11 @@ Sentry.startSpan( **Why this matters:** Without these attributes, you see "a database query took 2 seconds." With them, you know it was aggregating 30 days of data and returned 50,000 rows. That's actionable. -**Query ideas:** -- "Which aggregation queries are slowest?" → Group by `query.type`, sort by `p90(span.duration)` -- "Does date range affect performance?" → Filter by name, group by `query.dateRange` +**Query ideas in Explore > Traces:** +- "Which aggregation queries are slowest?" Group by `query.type`, sort by `p90(span.duration)` +- "Does date range affect performance?" Filter by name, group by `query.dateRange` -### Background Jobs +### 4. Background Jobs Jobs run outside request context. Custom spans make them visible. @@ -132,11 +124,11 @@ async function processEmailDigest(job) { } ``` -**Query:** `span.op:queue.process` grouped by `job.type`, visualize `p90(span.duration)`. +**Query in Explore > Traces:** `span.op:queue.process` grouped by `job.type`, visualize `p90(span.duration)`. **Alert idea:** `p90(span.duration) > 60s` for queue processing. -### AI/LLM Operations +### 5. AI/LLM Operations For AI workloads, use [Sentry Agent Monitoring](/product/insights/ai/agents/) instead of manual instrumentation when possible. It automatically captures agent workflows, tool calls, and token usage. @@ -161,7 +153,7 @@ Sentry.startSpan( ## Quick Reference -| Category | `op` Value | Key Attributes | +| Category | `op` Value | Example Attributes | |----------|-----------|----------------| | User flows | `user.action` | cart.itemCount, user.tier | | External APIs | `http.client` | http.url, response.timeMs | diff --git a/docs/guides/index.mdx b/docs/guides/index.mdx new file mode 100644 index 0000000000000..84808fa0dfa44 --- /dev/null +++ b/docs/guides/index.mdx @@ -0,0 +1,11 @@ +--- +title: Guides +sidebar_order: 15 +description: "Practical guidance on what to instrument, what to query, and how to get value from Sentry after setup." +--- + +You've set up Sentry. Now what? + +These guides help you move from "Sentry is installed" to "Sentry is helping me find and fix problems." Each covers what to instrument, what queries to run, and what alerts to create. + + diff --git a/docs/product/explore/logs/what-to-log.mdx b/docs/guides/logs.mdx similarity index 85% rename from docs/product/explore/logs/what-to-log.mdx rename to docs/guides/logs.mdx index 29404df8f215b..5178912ee83d4 100644 --- a/docs/product/explore/logs/what-to-log.mdx +++ b/docs/guides/logs.mdx @@ -1,6 +1,6 @@ --- title: "What to Log" -sidebar_order: 5 +sidebar_order: 10 description: "Practical guidance on what to log, how to search logs, and when to set alerts." --- @@ -156,9 +156,34 @@ Sentry.logger.warn("Config reloaded", { - **Anomaly:** Let Sentry detect unusual patterns 5. Configure notification channels and save -# Logging Strategy +Learn about [creating alerts](/product/new-monitors-and-alerts/alerts/) and best practices for [reducing noise and routing notifications](/product/new-monitors-and-alerts/alerts/best-practices/). + +## Logging Strategy + +### Development Logging + +In development, set sample rates to 100% to catch everything. This helps you understand what logs are being generated and tune your instrumentation before it hits production. + +**Development configuration:** + +```javascript +Sentry.init({ + dsn: "...", + environment: "development", + tracesSampleRate: 1.0, // 100% of traces + // Capture all logs in development + integrations: [ + Sentry.captureConsoleIntegration({ + levels: ["log", "info", "warn", "error", "debug"] + }) + ] +}); +``` + +Use verbose logging levels like `debug` (development diagnostics) and `trace` (fine-grained execution details) freely in development. You can [filter these out in production](/platforms/javascript/logs/#filter-logs) using `beforeSendLog` to only capture `info` and above. + +### Production Logging -## Production Logging Local debugging often means many small logs tracing execution flow. In production, this creates noise that's hard to query. Instead, log fewer messages with higher cardinality. Store events during execution and emit them as a single structured log. @@ -189,7 +214,7 @@ Sentry.logger.error("Checkout failed", { One log tells the whole story. Search for the error and get full context. -## Log Drains for Platform Logs +### Log Drains for Platform Logs If you can't install the Sentry SDK or need platform-level logs (CDN, database, load balancer), use [Log Drains](/product/drains/). @@ -199,7 +224,7 @@ If you can't install the Sentry SDK or need platform-level logs (CDN, database, ## Quick Reference -| Category | Level | Key Attributes | +| Category | Level | Example Attributes | |----------|-------|----------------| | Auth events | `info`/`warn` | userId, authMethod, reason | | Payments | `info`/`error` | orderId, amount, gateway, errorCode | diff --git a/docs/product/explore/metrics/what-to-track.mdx b/docs/guides/metrics.mdx similarity index 59% rename from docs/product/explore/metrics/what-to-track.mdx rename to docs/guides/metrics.mdx index 03b4633871a6d..5ec98b2c3de1c 100644 --- a/docs/product/explore/metrics/what-to-track.mdx +++ b/docs/guides/metrics.mdx @@ -1,7 +1,7 @@ --- title: "What to Track" -sidebar_order: 5 -description: "Practical guidance on what metrics to track and how to explore them in Sentry." +sidebar_order: 15 +description: "Practical guidance on what metrics to track, how to explore them, and when to set alerts." --- You've set up Sentry Metrics. Now what? This guide covers the high-value metric patterns that give you visibility into application health and how to drill into traces when something looks off. @@ -27,11 +27,11 @@ Sentry.metrics.count("checkout.failed", 1, { }); ``` -## Where to Add Metrics +## Where to Track Metrics -Try these five metrics and you'll spot issues before they become problems. +Start with these five metrics and you'll spot issues before they become problems. -### 1. Business Events (Counters) +### 1. Business Events Track discrete events that matter to the business. These become your KPIs. @@ -45,13 +45,13 @@ Sentry.metrics.count("checkout.failed", 1, { }); ``` -**How to explore:** +**Explore in Sentry:** 1. Go to **Explore > Metrics** 2. Select `checkout.failed`, set **Aggregate** to `sum` 3. **Group by** `failure_reason` 4. Click **Samples** to see individual events and their traces -### 2. Application Health (Counters) +### 2. Application Health Track success and failure of critical operations. @@ -69,9 +69,9 @@ Sentry.metrics.count("job.processed", 1, { }); ``` -**Explore:** Add both `email.sent` and `email.failed`, group by `email_type`, compare the ratio. +**Explore in Sentry:** Add both `email.sent` and `email.failed`, group by `email_type`, compare the ratio. -### 3. Resource Utilization (Gauges) +### 3. Resource Utilization Track current state of pools, queues, and connections. Call these periodically (e.g., every 30 seconds). @@ -85,9 +85,9 @@ Sentry.metrics.gauge("pool.connections_active", pool.activeConnections, { }); ``` -**Explore:** View `max(queue.depth)` over time to spot backlogs. +**Explore in Sentry:** View `max(queue.depth)` over time to spot backlogs. -### 4. Latency and Performance (Distributions) +### 4. Latency and Performance Track values that vary and need percentile analysis. **Tip:** averages can hide outliers, use p90/p95/p99 instead. @@ -103,9 +103,9 @@ Sentry.metrics.distribution("db.query_time", queryDurationMs, { }); ``` -**Explore:** View `p95(api.latency)` grouped by `endpoint` to find slow routes. +**Explore in Sentry:** View `p95(api.latency)` grouped by `endpoint` to find slow routes. -### 5. Business Values (Distributions) +### 5. Business Values Track amounts, sizes, and quantities for analysis. @@ -121,7 +121,44 @@ Sentry.metrics.distribution("upload.size", fileSizeBytes, { }); ``` -**Explore:** View `avg(order.amount)` grouped by `region` to compare regional performance. +**Explore in Sentry:** View `avg(order.amount)` grouped by `region` to compare regional performance. + +{/* +## Creating Alerts From Metrics + +1. Go to **Explore > Metrics** +2. Build your query (e.g., `checkout.failed` grouped by `failure_reason`) +3. Click **Save As** - **Alert** +4. Choose a threshold type: + - **Static:** Alert when count exceeds a value + - **Percent Change:** Alert when count changes relative to a previous period + - **Anomaly:** Let Sentry detect unusual patterns +5. Configure notification channels and save + +Learn about [creating alerts](/product/new-monitors-and-alerts/alerts/) and best practices for [reducing noise and routing notifications](/product/new-monitors-and-alerts/alerts/best-practices/). +*/} + +## Alerts and Dashboard Widgets + + + Alerts and dashboard widgets for Metrics are coming soon. + + +You'll soon be able to: +- Create alert rules based on metric queries +- Add metric visualizations to dashboards +- Set up notifications when metrics cross thresholds +- Save common queries for quick access + +## Quick Reference + +| Category | Type | Method | Example Attributes | +|----------|------|--------|----------------| +| Business events | Counter | `count()` | user_tier, payment_method, failure_reason | +| Application health | Counter | `count()` | email_type, provider, job_type, queue | +| Resource utilization | Gauge | `gauge()` | queue_name, pool_name | +| Latency/performance | Distribution | `distribution()` | endpoint, method, table, operation | +| Business values | Distribution | `distribution()` | user_tier, region, file_type | ## When to Use Metrics vs Traces vs Logs @@ -131,4 +168,4 @@ Sentry.metrics.distribution("upload.size", fileSizeBytes, { | **Traces** | Request flow, latency breakdown | "Why was this specific request slow?" | | **Logs** | Detailed context, debugging | "What happened right before this error?" | -All three are trace-connected. Start wherever makes sense and navigate to the others. \ No newline at end of file +All three are trace-connected. Start wherever makes sense and navigate to the others. diff --git a/docs/guides/querying-traces.mdx b/docs/guides/querying-traces.mdx new file mode 100644 index 0000000000000..a10738ba11bf3 --- /dev/null +++ b/docs/guides/querying-traces.mdx @@ -0,0 +1,85 @@ +--- +title: "Querying Traces" +sidebar_order: 20 +description: "Find performance issues using data Sentry captures automatically and set up alerts." +--- + +You've enabled tracing. Now what? Sentry's auto-instrumentation captures a lot without custom code. This guide shows you how to query that data to find performance issues. + +## What's Auto-Instrumented + +With `browserTracingIntegration()` enabled, Sentry automatically captures: + +- Page loads and navigation +- Fetch/XHR requests +- Long animation frames (main thread blocking) +- Resource loading (JS, CSS, images) + +## Where to Look + +Start with these five queries and you'll catch most performance issues before users complain. + +### 1. Slow Page Loads: Pages taking too long to become interactive hurt first impressions + +**Query in Explore > Traces:** `span.op:pageload` & **Visualize:** `p90(span.duration)` grouped by `transaction` to compare routes. + +- **What to look for:** Routes with p90 over 3 seconds. Explore sample traces to see the breakdown. Usually it's slow API calls, heavy JavaScript, or large images. + +- **Alert idea:** `p75(transaction.duration) > 3s` for pageload transactions. + +### 2. Slow API Calls: Fetch/XHR requests are often the bottleneck in modern web apps + +**Query in Explore > Traces:** `span.op:http.client` & **Visualize:** `avg(span.duration)` grouped by `span.description` (the URL). + +- **What to look for:** Endpoints with avg duration over 1 second or p95 over 2 seconds. Check if it's the backend or network latency by looking at sample traces. + +- **Alert idea:** `p95(span.duration) > 2s` where `span.op:http.client`. + +### 3. JavaScript Blocking the UI: Long animation frames mean JavaScript execution is freezing the interface + +**Query in Explore > Traces:** `span.op:ui.long-animation-frame` & **Visualize:** Sort by `span.duration` to find the worst offenders. + +- **What to look for:** Frames over 200ms. This is what causes jank and unresponsiveness. Look at the stack trace in sample traces to find the expensive operation. + +- **Alert idea:** `p75(span.duration) > 200ms` for long animation frames. + +### 4. Slow SPA Navigation: After the initial load, how fast do users move between pages? + +**Query in Explore > Traces:** `span.op:navigation` & **Visualize:** `p90(span.duration)` grouped by `transaction` to compare route performance. + +- **What to look for:** Navigation over 1 second feels sluggish. Click into traces to see if it's data fetching, component rendering, or something else. + +- **Alert idea:** `p75(span.duration) > 2s` for navigation. + +### 5. Heavy Resources: Large JS bundles, stylesheets, or images slowing down your site + +**Query in Explore > Traces:** `span.op:resource.script` (JavaScript), `span.op:resource.css` (stylesheets), or `span.op:resource.img` (images) & **Visualize:** `avg(span.duration)` to find the heaviest assets. + +- **What to look for:** Resources taking over 1 second. Check the span description to see which files. Often it's third-party scripts or unoptimized images. + +- **Alert idea:** `p75(span.duration) > 3s` for resource.script. + +## Creating Alerts From Traces + +1. Go to **Explore > Traces** +2. Build your query (e.g., `span.op:http.client`) +3. Click **Save As** - **Alert** +4. Choose a threshold type: + - **Static:** Alert when a value exceeds a threshold + - **Percent Change:** Alert when a value changes relative to a previous period + - **Anomaly:** Let Sentry detect unusual patterns +5. Configure notification channels and save + +**Tip:** Averages can hide outliers, use p75/p90/p95 instead. + +Learn about [creating alerts](/product/new-monitors-and-alerts/alerts/) and best practices for [reducing noise and routing notifications](/product/new-monitors-and-alerts/alerts/best-practices/). + +## Quick Reference + +| Category | Query | Visualize | +|----------|-------|-----------| +| Slow page loads | `span.op:pageload` | `p90(span.duration)` by transaction | +| Slow fetch requests | `span.op:http.client` | `avg(span.duration)` by URL | +| JS blocking UI | `span.op:ui.long-animation-frame` | `max(span.duration)` | +| Slow SPA navigation | `span.op:navigation` | `p90(span.duration)` by transaction | +| Heavy resources | `span.op:resource.*` | `avg(span.duration)` by description | diff --git a/docs/guides/session-replay.mdx b/docs/guides/session-replay.mdx new file mode 100644 index 0000000000000..21ecfe7d1ddab --- /dev/null +++ b/docs/guides/session-replay.mdx @@ -0,0 +1,127 @@ +--- +title: "Using Session Replay" +sidebar_order: 40 +description: "Practical guidance on debugging errors and finding UX issues with Session Replay." +--- + +You've set up Session Replay. Now what? Stack traces tell you *what* broke. Replay shows you *why*. This guide covers how to use replay to debug errors and spot UX problems before users report them. + +## What Replay Captures + +Every replay connected to an error includes: +- **User actions** — clicks, navigation, form inputs +- **Network requests** — API calls, responses, failures, latency +- **Console logs** — warnings, errors, debug messages +- **Application state** — URL changes, route transitions + +## AI Summary + + + +The AI Summary tab automatically generates a natural language summary of what happened during a session. Instead of watching the entire replay, you can read a text description that highlights key actions, navigation paths, and timestamps. + +Use AI Summary to: +- Quickly understand what a user did without watching the full replay +- Jump to specific moments in the session by clicking timestamps in the summary +- Share context with teammates who need the highlights, not the full recording + +Click the **AI Summary** tab in any replay to see the generated summary. You can regenerate it if needed. + + + +## Where to Use Replay + +Start with these five workflows and you'll debug faster and catch UX issues before they become support tickets. + +### 1. Root Cause Analysis for Errors + +When an error spikes, the stack trace shows the line of code. Replay shows the user journey that triggered it. + +**What to look for:** + +- **Failed API calls** — Check the Network tab. A 500 error or timeout often cascaded into the JavaScript error. +- **Race conditions** — Did they click twice? Navigate before a request finished? Trigger conflicting operations? +- **Edge case data** — Empty arrays, null values, unexpected formats your code didn't handle. +- **Browser/device context** — Errors on slow connections or older browsers reveal assumptions in your code. + +**Search in Sentry:** Go to **Replays** and filter by `count_errors:>0` to see all sessions with errors. Click into a replay to watch it, or check the AI Summary tab to quickly jump to key moments. + +### 2. Reproducing User-Reported Bugs + +User says it's broken, but you can't reproduce it locally. Replay shows you exactly what they did. + +**What to watch:** + +- The exact sequence of clicks and navigation +- Form inputs or selections that triggered the bug +- Browser console errors they didn't mention +- Network failures or slow responses that affected behavior + +**Search in Sentry:** Go to **Replays** and filter by `user.email:jane@example.com` or `user.id:123` to find sessions around the time they reported the issue. + +### 3. Finding Error Patterns Across Users + +When multiple users hit the same error, patterns emerge that point to the root cause. + +**What to compare:** + +- Do they all come from the same release? +- Did they visit the same pages in the same order? +- Do they share the same browser, device, or region? +- Did a specific API endpoint fail for all of them? + +**Search in Sentry:** Go to **Replays** and filter by `count_errors:>0 release:1.2.3` to see if errors cluster by release, or use `count_errors:>0 browser.name:Chrome` to compare by browser. + +### 4. Spotting Rage Clicks and Dead Clicks + +Clicks that don't work create silent frustration. Replay catches these before users complain. + +**Rage clicks:** Users clicking the same element repeatedly because nothing happens. + +**Dead clicks:** Clicks on elements that look interactive but have no handler. + +**Common causes:** + +- Button appears clickable but has no handler +- Click handler is slow or async without visual feedback +- Element is covered by an invisible overlay (z-index issue) +- JavaScript error preventing the handler from running + +**Search in Sentry:** Go to **Replays** and check the "Most Rage Clicks" and "Most Dead Clicks" widgets at the top* to see the worst offenders. Or filter by `count_rage_clicks:>0` or `count_dead_clicks:>0`. *If you don't see the widgets, toggle "Show Widgets" at the top. + +### 5. Identifying Slow Interactions + +Users waiting too long for responses creates perceived sluggishness even if the page loaded fast. + +**What to watch:** + +- Long gaps between click and visual response +- Loading spinners that last too long (over 2-3 seconds) +- Form submissions with no feedback +- Navigation that feels frozen + +**Search in Sentry:** Go to **Replays** and filter by `url:*/checkout*` to focus on critical flows, then watch replays to spot slow interactions. + +## Privacy Considerations + +By default, Session Replay masks all text content, user input, and images. Sensitive data stays in the browser. + +You'll see placeholder blocks instead of actual content, which is enough to understand what users did without exposing their data. If you need to see specific elements for debugging (like button labels or navigation items), you can unmask them: + +```html +

Welcome to Checkout

+``` + +Be selective. Never unmask form inputs, and review your [privacy configuration](/platforms/javascript/session-replay/privacy/) before increasing sample rates. + +## Quick Reference + +| What You're Looking For | Filter | +|------------------------|--------| +| Sessions with errors | `count_errors:>0` | +| Specific user | `user.email:jane@example.com` | +| Specific page | `url:*/checkout*` | +| Rage clicks | `count_rage_clicks:>0` | +| Dead clicks | `count_dead_clicks:>0` | +| Mobile users | `device.family:iPhone` | +| Slow sessions | Filter by URL, watch for slow interactions | diff --git a/docs/product/explore/trace-explorer/querying-traces.mdx b/docs/product/explore/trace-explorer/querying-traces.mdx deleted file mode 100644 index aac272f8f879e..0000000000000 --- a/docs/product/explore/trace-explorer/querying-traces.mdx +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: "Querying Auto-Instrumented Traces" -sidebar_order: 10 -description: "Find performance issues using data Sentry captures automatically." ---- - -Sentry's browser SDK automatically captures page loads, navigation, fetch requests, and resource loading. This guide shows you how to query that data to find performance issues—no custom code required. - -## What's Auto-Instrumented - -With `browserTracingIntegration()` enabled, Sentry automatically captures: - -- Page loads and navigation -- Fetch/XHR requests -- Long animation frames (main thread blocking) -- Resource loading (JS, CSS, images) - -## Finding Performance Issues - -### Slow Page Loads - -Pages taking too long to become interactive. - -**Query:** `span.op:pageload` - -**Visualize:** `p90(span.duration)` grouped by `transaction` to compare routes. - -**Alert idea:** `p75(transaction.duration) > 3s` for pageload transactions. - -### Slow API Calls - -Fetch/XHR requests dragging down your app. - -**Query:** `span.op:http.client` - -**Visualize:** `avg(span.duration)` grouped by `span.description` (the URL). - -**Alert idea:** `p95(span.duration) > 2s` where `span.op:http.client`. - -### JavaScript Blocking the Main Thread - -Long animation frames indicate JavaScript execution blocking the UI. - -**Query:** `span.op:ui.long-animation-frame` - -**Visualize:** Sort by `span.duration` to find the worst offenders. - -**Alert idea:** `p75(span.duration) > 200ms` for long animation frames. - -### Slow SPA Navigation - -How long it takes users to move between pages after initial load. - -**Query:** `span.op:navigation` - -**Visualize:** `p90(span.duration)` grouped by `transaction` to compare route performance. - -**Alert idea:** `p75(span.duration) > 2s` for navigation. - -### Heavy Resources - -JS bundles, stylesheets, or images slowing down page load. - -**Queries:** -- `span.op:resource.script` (JavaScript) -- `span.op:resource.css` (stylesheets) -- `span.op:resource.img` (images) - -**Visualize:** `avg(span.duration)` to find the heaviest assets. - -**Alert idea:** `p75(span.duration) > 3s` for resource.script. - -## Creating Trace-Based Alerts - -1. Go to **Explore > Traces** -2. Build your query (e.g., `span.op:http.client`) -3. Click **Save As** → **Alert** -4. Choose a threshold type: - - **Static:** Set a specific threshold - - **Percent Change:** Alert on relative change - - **Anomaly:** Let Sentry detect unusual patterns -5. Configure notifications and save - -**Tip:** Alert on percentiles (p75, p95) rather than averages. Averages hide the outliers that hurt real users. - -## Quick Reference - -| What You're Looking For | Query | Visualize | -|------------------------|-------|-----------| -| Slow page loads | `span.op:pageload` | `p90(span.duration)` by route | -| Slow fetch requests | `span.op:http.client` | `avg(span.duration)` by URL | -| JS blocking UI | `span.op:ui.long-animation-frame` | `max(span.duration)` | -| Slow SPA navigation | `span.op:navigation` | `p90(span.duration)` by route | -| Heavy JS bundles | `span.op:resource.script` | `avg(span.duration)` | -| Heavy stylesheets | `span.op:resource.css` | `avg(span.duration)` | -| Slow images | `span.op:resource.img` | `avg(span.duration)` | diff --git a/src/components/sidebar/sidebarNavigation.tsx b/src/components/sidebar/sidebarNavigation.tsx index 88de1485506fc..8c6e7acc86ed3 100644 --- a/src/components/sidebar/sidebarNavigation.tsx +++ b/src/components/sidebar/sidebarNavigation.tsx @@ -12,6 +12,10 @@ import {docNodeToNavNode, getNavNodes} from './utils'; /** a root of `"some-root"` maps to the `/some-root/` url */ // todo: we should probably get rid of this const productSidebarItems = [ + { + title: 'Guides', + root: 'guides', + }, { title: 'Account Settings', root: 'account', From c7282c8943f9d15f31518d923b5d83207d69b17c Mon Sep 17 00:00:00 2001 From: paulj Date: Tue, 17 Feb 2026 00:56:02 -0500 Subject: [PATCH 05/21] add issues page --- docs/guides/issues-errors.mdx | 194 ++++++++++++++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100644 docs/guides/issues-errors.mdx diff --git a/docs/guides/issues-errors.mdx b/docs/guides/issues-errors.mdx new file mode 100644 index 0000000000000..ce2e85f6d70f9 --- /dev/null +++ b/docs/guides/issues-errors.mdx @@ -0,0 +1,194 @@ +--- +title: "What to Watch" +sidebar_order: 5 +description: "Practical guidance on what errors to catch, how to search issues, and when to set alerts." +--- + +You've set up Sentry error monitoring. Now what? This guide covers the high-value error patterns that help you catch problems before they impact users and fix issues faster. + +## The Pattern + +Sentry automatically captures unhandled errors. For handled errors, use `Sentry.captureException()` to add context: + +```javascript +try { + await processOrder(order); +} catch (error) { + Sentry.captureException(error, { + tags: { + order_id: order.id, + payment_method: order.paymentMethod + }, + level: "error" + }); + throw error; +} +``` + +**Levels:** `fatal`, `error`, `warning`, `info`, `debug` + +**Context:** Tags, user info, and breadcrumbs help you debug faster. Tags are searchable, so use them for high-cardinality data like IDs, regions, and feature flags. + +Every error in Sentry is automatically trace-connected. Click the trace ID to see the full [trace view](/concepts/key-terms/tracing/trace-view/) and understand what led to the error. + +## Where to Look + +Start with these five views to catch critical issues. + +### 1. Unresolved High-Volume Issues + +High event counts mean either many users are affected or one user is stuck in a loop. Both need immediate attention. + +**In Issues:** Search for `is:unresolved` (applied by default) and use the sort dropdown (defaults to "Last Seen") to sort by **Events** + +**What to look for:** +- Issues at the top with high event counts (many occurrences in a short time) +- Click into these issues to see the stack trace and how many users are affected + +Learn more about [Issue States & Triage](/product/issues/states-triage/) to manage and prioritize issues. + +**Alert idea:** Trigger when event count spikes in a short time window to catch high-impact bugs and infinite loops. + +### 2. New Issues After Deploy + +Every deploy introduces risk. New errors that appear right after a release are usually regressions. + +**In Issues:** Filter by `is:unresolved` and sort by **Age** to find issues that first appeared recently (not just issues that happened recently). Filter by release: `release:v1.2.3` + +**What to look for:** +- Issues that didn't exist in the previous release +- Errors in code paths you just changed +- New error types (TypeError, ReferenceError) indicating breaking changes + +Learn more about [Release Health](/product/releases/health/) to track error rates and crash-free sessions per release. + +**Alert idea:** Trigger when a new issue is created, filtered to production environment and error/fatal level. This catches regressions immediately after deploy. + +### 3. Errors by Environment + +Production errors are critical. Staging errors help you catch problems before they reach users. Comparing environments helps you spot configuration issues. + +**In Issues:** Search for `is:unresolved environment:production` or `environment:staging` + +**What to look for:** +- Errors only in production (often config, API keys, or data issues) +- Errors only in staging (caught before deploy, needs fixing) +- Same error in both (systemic code issue) + +Learn more about configuring environments to separate production and staging issues. + +**Alert idea:** Trigger when a new issue is created, filtered to production environment. These often indicate config drift or environment-specific bugs. + +### 4. Errors with High User Impact + +Some errors affect power users heavily. Others affect everyone rarely. Prioritize by unique user count, not just event count. + +**In Issues:** Search for `is:unresolved` and use the sort dropdown to sort by **Users** + +**What to look for:** +- Issues affecting many unique users (e.g., more than 10 users indicates widespread impact) +- Issues affecting VIP or paying users (check user tags) +- Issues blocking core workflows (login, checkout, data access) + +Learn more about custom tags to mark user tiers, plans, or roles. Then search `is:unresolved user.tier:enterprise` to prioritize high-value users. + +**Alert idea:** Trigger when unique user count exceeds a threshold in a time window (e.g., more than 50 users in 1 hour) to catch widespread issues. + +### 5. User-Reported Issues + +When users report problems, they often see an error. User feedback tells you which errors hurt the experience most, even if event counts are low. + +**In Issues:** Navigate to **User Feedback** in the left sidebar to see reports submitted by users. + +**What to look for:** +- User descriptions of what they were doing when the error occurred +- Patterns in feedback about specific workflows or features +- Issues that frustrate users even if they don't generate many events + +Enable the [User Feedback Widget](/platforms/javascript/user-feedback/) to let users report problems directly when errors happen. + +**Alert idea:** Trigger when a new issue is created, filtered to issue category equals feedback. This ensures you respond quickly when users report problems. + +## Creating Issue Alerts + +Issue alerts notify you when specific conditions are met. To create one: + +1. Go to **Alerts** and click "Create Alert Rule" +2. Select "Issues" and click "Set Conditions" +3. Configure "When" conditions (what triggers the alert) +4. Add "If" filters to narrow the scope (optional) +5. Set "Then" actions (where to send notifications) + +Common triggers: new issues, high event counts, high user counts, state changes. + +Common filters: environment, tags, issue properties. + +Learn more about [Creating Alerts](/product/alerts/create-alerts/) and [Issue Alert Configuration](/product/alerts/create-alerts/issue-alert-config/). + +## Error Handling Strategy + +### Capture Context, Not Just Exceptions + +When you catch an error, add tags, user info, and breadcrumbs to make debugging instant. + +```javascript +Sentry.captureException(error, { + tags: { + order_id: order.id, + payment_gateway: "stripe", + region: user.region + }, + user: { + id: user.id, + email: user.email + }, + contexts: { + order: { + total: order.total, + items: order.items.length, + discount_code: order.discountCode + } + } +}); +``` + +**Search in Sentry:** `order_id:order_123` or `payment_gateway:stripe region:us-west` + +### Ignore Known Noise + +Some errors aren't actionable. Use `ignoreErrors` to filter them out. + +```javascript +Sentry.init({ + dsn: "...", + ignoreErrors: [ + "Non-Error promise rejection captured", + /^Timeout of \d+ms exceeded$/ + ] +}); +``` + +Also use `beforeSend` to filter errors dynamically: + +```javascript +Sentry.init({ + beforeSend(event, hint) { + // Ignore errors from browser extensions + if (event.exception?.values?.[0]?.stacktrace?.frames?.some( + frame => frame.filename?.includes("chrome-extension://") + )) { + return null; + } + return event; + } +}); +``` + +## Quick Reference + +| View | Search Query | Look For | +|------|--------------|----------| +| High-volume issues | `is:unresolved` (sort by Events) | High event counts, post-deploy spikes | +| New regressions | `is:unresolved` (sort by Age) | Issues that first appeared recently | +| Environment issues | `environment:production` | Prod-only config or data issues | +| High user impact | `is:unresolved` (sort by Users) | Issues affecting many users | From 36b3d4666a6d2d51bd9b04c5ed1bfc2debcac54c Mon Sep 17 00:00:00 2001 From: paulj Date: Tue, 17 Feb 2026 11:54:36 -0500 Subject: [PATCH 06/21] docs(guides): Link feature names to product documentation Link Sentry feature names (Sentry Issues, Sentry Logs, Sentry Metrics, Sentry Tracing, Session Replay) in the opening sentences to their corresponding product walkthrough pages under /product/explore/ and /product/issues/. This provides users with easy navigation to comprehensive product documentation while maintaining the practical focus of the guides. Co-Authored-By: Claude Sonnet 4.5 (1M context) --- docs/guides/custom-spans.mdx | 2 +- docs/guides/issues-errors.mdx | 2 +- docs/guides/logs.mdx | 2 +- docs/guides/metrics.mdx | 2 +- docs/guides/querying-traces.mdx | 2 +- docs/guides/session-replay.mdx | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/guides/custom-spans.mdx b/docs/guides/custom-spans.mdx index 2ca6fdbadf1ad..1f2e00f0b9eb8 100644 --- a/docs/guides/custom-spans.mdx +++ b/docs/guides/custom-spans.mdx @@ -4,7 +4,7 @@ sidebar_order: 30 description: "Add custom instrumentation for visibility beyond auto-instrumentation and set up alerts." --- -You've got auto-instrumentation running. Now what? Auto-instrumentation captures HTTP, database, and framework operations, but it can't see business logic, third-party APIs without auto-instrumentation, or background jobs. This guide shows you where to add custom spans. +You've got your Sentry SDK [auto-instrumentation](/product/explore/trace-explorer/) running. Now what? Auto-instrumentation captures HTTP, database, and framework operations, but it can't see business logic, third-party APIs without auto-instrumentation, or background jobs. This guide shows you where to add custom spans. ## The Pattern diff --git a/docs/guides/issues-errors.mdx b/docs/guides/issues-errors.mdx index ce2e85f6d70f9..8c20896bc436a 100644 --- a/docs/guides/issues-errors.mdx +++ b/docs/guides/issues-errors.mdx @@ -4,7 +4,7 @@ sidebar_order: 5 description: "Practical guidance on what errors to catch, how to search issues, and when to set alerts." --- -You've set up Sentry error monitoring. Now what? This guide covers the high-value error patterns that help you catch problems before they impact users and fix issues faster. +You've set up [Sentry Issues](/product/issues/). Now what? This guide covers the high-value error patterns that help you catch problems before they impact users and fix issues faster. ## The Pattern diff --git a/docs/guides/logs.mdx b/docs/guides/logs.mdx index 5178912ee83d4..b5184d0bbd568 100644 --- a/docs/guides/logs.mdx +++ b/docs/guides/logs.mdx @@ -4,7 +4,7 @@ sidebar_order: 10 description: "Practical guidance on what to log, how to search logs, and when to set alerts." --- -You've set up Sentry Logs. Now what? This guide covers the high-value logging patterns that help you debug faster and catch problems before users report them. +You've set up [Sentry Logs](/product/explore/logs/). Now what? This guide covers the high-value logging patterns that help you debug faster and catch problems before users report them. ## The Pattern diff --git a/docs/guides/metrics.mdx b/docs/guides/metrics.mdx index 5ec98b2c3de1c..6b0312cf5ec21 100644 --- a/docs/guides/metrics.mdx +++ b/docs/guides/metrics.mdx @@ -4,7 +4,7 @@ sidebar_order: 15 description: "Practical guidance on what metrics to track, how to explore them, and when to set alerts." --- -You've set up Sentry Metrics. Now what? This guide covers the high-value metric patterns that give you visibility into application health and how to drill into traces when something looks off. +You've set up [Sentry Metrics](/product/explore/metrics/). Now what? This guide covers the high-value metric patterns that give you visibility into application health and how to drill into traces when something looks off. ## The Pattern diff --git a/docs/guides/querying-traces.mdx b/docs/guides/querying-traces.mdx index a10738ba11bf3..63237d647b024 100644 --- a/docs/guides/querying-traces.mdx +++ b/docs/guides/querying-traces.mdx @@ -4,7 +4,7 @@ sidebar_order: 20 description: "Find performance issues using data Sentry captures automatically and set up alerts." --- -You've enabled tracing. Now what? Sentry's auto-instrumentation captures a lot without custom code. This guide shows you how to query that data to find performance issues. +You've enabled [Sentry Tracing](/product/explore/trace-explorer/). Now what? Sentry's auto-instrumentation captures a lot without custom code. This guide shows you how to query that data to find performance issues. ## What's Auto-Instrumented diff --git a/docs/guides/session-replay.mdx b/docs/guides/session-replay.mdx index 21ecfe7d1ddab..7854f5a802389 100644 --- a/docs/guides/session-replay.mdx +++ b/docs/guides/session-replay.mdx @@ -4,7 +4,7 @@ sidebar_order: 40 description: "Practical guidance on debugging errors and finding UX issues with Session Replay." --- -You've set up Session Replay. Now what? Stack traces tell you *what* broke. Replay shows you *why*. This guide covers how to use replay to debug errors and spot UX problems before users report them. +You've set up [Sentry Session Replay](/product/explore/session-replay/). Now what? Stack traces tell you *what* broke. Replay shows you *why*. This guide covers how to use replay to debug errors and spot UX problems before users report them. ## What Replay Captures From 3d388fed3537af465715470dcf7e56766c8fd2da Mon Sep 17 00:00:00 2001 From: paulj Date: Tue, 17 Feb 2026 12:08:56 -0500 Subject: [PATCH 07/21] tweaks and links --- docs/guides/issues-errors.mdx | 6 +++--- docs/guides/session-replay.mdx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/guides/issues-errors.mdx b/docs/guides/issues-errors.mdx index 8c20896bc436a..543265b856c05 100644 --- a/docs/guides/issues-errors.mdx +++ b/docs/guides/issues-errors.mdx @@ -4,7 +4,7 @@ sidebar_order: 5 description: "Practical guidance on what errors to catch, how to search issues, and when to set alerts." --- -You've set up [Sentry Issues](/product/issues/). Now what? This guide covers the high-value error patterns that help you catch problems before they impact users and fix issues faster. +Your Sentry SDK is sending errors to [Sentry Issues](/product/issues/) out of the box. Now what? This guide covers the high-value error patterns that help you catch problems before they impact users and fix issues faster. ## The Pattern @@ -156,7 +156,7 @@ Sentry.captureException(error, { ### Ignore Known Noise -Some errors aren't actionable. Use `ignoreErrors` to filter them out. +Some errors aren't actionable. Use ignoreErrors to filter them out. ```javascript Sentry.init({ @@ -168,7 +168,7 @@ Sentry.init({ }); ``` -Also use `beforeSend` to filter errors dynamically: +Also use beforeSend to filter errors dynamically: ```javascript Sentry.init({ diff --git a/docs/guides/session-replay.mdx b/docs/guides/session-replay.mdx index 7854f5a802389..037e1f78e692f 100644 --- a/docs/guides/session-replay.mdx +++ b/docs/guides/session-replay.mdx @@ -123,5 +123,5 @@ Be selective. Never unmask form inputs, and review your [privacy configuration]( | Specific page | `url:*/checkout*` | | Rage clicks | `count_rage_clicks:>0` | | Dead clicks | `count_dead_clicks:>0` | -| Mobile users | `device.family:iPhone` | +| Mobile users | `device.family:iOS` | | Slow sessions | Filter by URL, watch for slow interactions | From e7cba86c4271efd150279ff87ef4e2b223c68d0a Mon Sep 17 00:00:00 2001 From: Paul Jaffre Date: Tue, 17 Feb 2026 21:22:51 -0500 Subject: [PATCH 08/21] Apply suggestions from code review Co-authored-by: Alex Krawiec Co-authored-by: Shannon Anahata --- docs/guides/custom-spans.mdx | 8 +++++--- docs/guides/index.mdx | 2 +- docs/guides/issues-errors.mdx | 8 ++++---- docs/guides/metrics.mdx | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/guides/custom-spans.mdx b/docs/guides/custom-spans.mdx index 1f2e00f0b9eb8..edfa9af4899bf 100644 --- a/docs/guides/custom-spans.mdx +++ b/docs/guides/custom-spans.mdx @@ -4,7 +4,9 @@ sidebar_order: 30 description: "Add custom instrumentation for visibility beyond auto-instrumentation and set up alerts." --- -You've got your Sentry SDK [auto-instrumentation](/product/explore/trace-explorer/) running. Now what? Auto-instrumentation captures HTTP, database, and framework operations, but it can't see business logic, third-party APIs without auto-instrumentation, or background jobs. This guide shows you where to add custom spans. +You've got your Sentry SDK [auto-instrumentation](/product/explore/trace-explorer/) running. Now what? + +Auto-instrumentation captures HTTP, database, and framework operations. But it can't see business logic, third-party APIs without auto-instrumentation, or background jobs. This guide shows you where to add custom spans to fill in those gaps. ## The Pattern @@ -26,7 +28,7 @@ Start with these five areas and you'll have visibility into the operations that ### 1. Business-Critical User Flows -Track the full journey through critical paths. When checkout is slow, you need to know which step. +Track the full journey through critical paths. When checkout is slow, you need to know which step is responsible. ```javascript Sentry.startSpan( @@ -100,7 +102,7 @@ Sentry.startSpan( ### 4. Background Jobs -Jobs run outside request context. Custom spans make them visible. +Jobs run outside of request context. Custom spans make them visible. ```javascript async function processEmailDigest(job) { diff --git a/docs/guides/index.mdx b/docs/guides/index.mdx index 84808fa0dfa44..e1499b3c89190 100644 --- a/docs/guides/index.mdx +++ b/docs/guides/index.mdx @@ -6,6 +6,6 @@ description: "Practical guidance on what to instrument, what to query, and how t You've set up Sentry. Now what? -These guides help you move from "Sentry is installed" to "Sentry is helping me find and fix problems." Each covers what to instrument, what queries to run, and what alerts to create. +These guides help you move from "Sentry is configured" to "Sentry is helping me find and fix problems." Each covers what to instrument, what queries to run, and what alerts to create. diff --git a/docs/guides/issues-errors.mdx b/docs/guides/issues-errors.mdx index 543265b856c05..109ddd5a3d1ac 100644 --- a/docs/guides/issues-errors.mdx +++ b/docs/guides/issues-errors.mdx @@ -8,7 +8,7 @@ Your Sentry SDK is sending errors to [Sentry Issues](/product/issues/) out of th ## The Pattern -Sentry automatically captures unhandled errors. For handled errors, use `Sentry.captureException()` to add context: +Sentry automatically captures unhandled errors. For handled errors, use `Sentry.captureException()` and add context: ```javascript try { @@ -33,7 +33,7 @@ Every error in Sentry is automatically trace-connected. Click the trace ID to se ## Where to Look -Start with these five views to catch critical issues. +Start with these five views to catch the most critical issues. ### 1. Unresolved High-Volume Issues @@ -81,7 +81,7 @@ Learn more about configuring env ### 4. Errors with High User Impact -Some errors affect power users heavily. Others affect everyone rarely. Prioritize by unique user count, not just event count. +Some errors heavily affect power users. Others affect everyone, but rarely. Prioritize by unique user count, not just event count. **In Issues:** Search for `is:unresolved` and use the sort dropdown to sort by **Users** @@ -168,7 +168,7 @@ Sentry.init({ }); ``` -Also use beforeSend to filter errors dynamically: +You can also use beforeSend to filter errors dynamically: ```javascript Sentry.init({ diff --git a/docs/guides/metrics.mdx b/docs/guides/metrics.mdx index 6b0312cf5ec21..07181ed6f3b70 100644 --- a/docs/guides/metrics.mdx +++ b/docs/guides/metrics.mdx @@ -73,7 +73,7 @@ Sentry.metrics.count("job.processed", 1, { ### 3. Resource Utilization -Track current state of pools, queues, and connections. Call these periodically (e.g., every 30 seconds). +Track the current state of pools, queues, and connections. Call these periodically (e.g., every 30 seconds). ```javascript Sentry.metrics.gauge("queue.depth", await queue.size(), { From 2a796d0c1c9ceb209a9f8f792d3127fc439eb9ef Mon Sep 17 00:00:00 2001 From: paulj Date: Tue, 17 Feb 2026 23:10:40 -0500 Subject: [PATCH 09/21] add more PR feedback --- docs/guides/issues-errors.mdx | 44 +++++++++++------------------------ 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/docs/guides/issues-errors.mdx b/docs/guides/issues-errors.mdx index 109ddd5a3d1ac..7e2b4de734dfb 100644 --- a/docs/guides/issues-errors.mdx +++ b/docs/guides/issues-errors.mdx @@ -27,9 +27,9 @@ try { **Levels:** `fatal`, `error`, `warning`, `info`, `debug` -**Context:** Tags, user info, and breadcrumbs help you debug faster. Tags are searchable, so use them for high-cardinality data like IDs, regions, and feature flags. +**Context:** Tags, user info, logs, and session replays help you debug faster. Tags are searchable, so use them for high-cardinality data like IDs, regions, and feature flags. -Every error in Sentry is automatically trace-connected. Click the trace ID to see the full [trace view](/concepts/key-terms/tracing/trace-view/) and understand what led to the error. +Every error in Sentry is automatically trace-connected. Click the trace ID to see the full [trace view](/concepts/key-terms/tracing/#traces-to-trace-view) and understand what led to the error. ## Where to Look @@ -39,7 +39,7 @@ Start with these five views to catch the most critical issues. High event counts mean either many users are affected or one user is stuck in a loop. Both need immediate attention. -**In Issues:** Search for `is:unresolved` (applied by default) and use the sort dropdown (defaults to "Last Seen") to sort by **Events** +**[In Issues](https://sentry.io/orgredirect/organizations/:orgslug/issues/):** Search for `is:unresolved` (applied by default) and use the sort dropdown (defaults to "Last Seen") to sort by **Events** **What to look for:** - Issues at the top with high event counts (many occurrences in a short time) @@ -53,7 +53,7 @@ Learn more about [Issue States & Triage](/product/issues/states-triage/) to mana Every deploy introduces risk. New errors that appear right after a release are usually regressions. -**In Issues:** Filter by `is:unresolved` and sort by **Age** to find issues that first appeared recently (not just issues that happened recently). Filter by release: `release:v1.2.3` +**[In Issues](https://sentry.io/orgredirect/organizations/:orgslug/issues/):** Filter by `is:unresolved` and sort by **Age** to find issues that first appeared recently (not just issues that happened recently). Filter by release: `release:v1.2.3` **What to look for:** - Issues that didn't exist in the previous release @@ -68,7 +68,7 @@ Learn more about [Release Health](/product/releases/health/) to track error rate Production errors are critical. Staging errors help you catch problems before they reach users. Comparing environments helps you spot configuration issues. -**In Issues:** Search for `is:unresolved environment:production` or `environment:staging` +**[In Issues](https://sentry.io/orgredirect/organizations/:orgslug/issues/):** Search for `is:unresolved environment:production` or `environment:staging` **What to look for:** - Errors only in production (often config, API keys, or data issues) @@ -83,7 +83,7 @@ Learn more about configuring env Some errors heavily affect power users. Others affect everyone, but rarely. Prioritize by unique user count, not just event count. -**In Issues:** Search for `is:unresolved` and use the sort dropdown to sort by **Users** +**[In Issues](https://sentry.io/orgredirect/organizations/:orgslug/issues/):** Search for `is:unresolved` and use the sort dropdown to sort by **Users** **What to look for:** - Issues affecting many unique users (e.g., more than 10 users indicates widespread impact) @@ -98,50 +98,34 @@ Learn more about custom tags Date: Tue, 17 Feb 2026 23:27:23 -0500 Subject: [PATCH 10/21] more tweaks --- docs/guides/issues-errors.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/guides/issues-errors.mdx b/docs/guides/issues-errors.mdx index 7e2b4de734dfb..0aa059a4be5bf 100644 --- a/docs/guides/issues-errors.mdx +++ b/docs/guides/issues-errors.mdx @@ -33,7 +33,9 @@ Every error in Sentry is automatically trace-connected. Click the trace ID to se ## Where to Look -Start with these five views to catch the most critical issues. +Start by creating these five [Issue views](https://sentry.io/orgredirect/organizations/:orgslug/issues/) to catch the most critical problems. + +**Save these views**: Turn these five searches into saved Issues views by clicking **Save As** after setting each filter. ### 1. Unresolved High-Volume Issues From 011de3e7b986dee5046380e03bd795752790ed52 Mon Sep 17 00:00:00 2001 From: paulj Date: Tue, 17 Feb 2026 23:41:56 -0500 Subject: [PATCH 11/21] more tweaks --- docs/guides/issues-errors.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/issues-errors.mdx b/docs/guides/issues-errors.mdx index 0aa059a4be5bf..5896cda5c05de 100644 --- a/docs/guides/issues-errors.mdx +++ b/docs/guides/issues-errors.mdx @@ -55,7 +55,7 @@ Learn more about [Issue States & Triage](/product/issues/states-triage/) to mana Every deploy introduces risk. New errors that appear right after a release are usually regressions. -**[In Issues](https://sentry.io/orgredirect/organizations/:orgslug/issues/):** Filter by `is:unresolved` and sort by **Age** to find issues that first appeared recently (not just issues that happened recently). Filter by release: `release:v1.2.3` +**[In Issues](https://sentry.io/orgredirect/organizations/:orgslug/issues/):** Filter by `is:unresolved firstRelease:v1.2.3` to find issues introduced in a specific release. Sort by **Age** to see the newest issues first. **What to look for:** - Issues that didn't exist in the previous release From c788dcbb8e94af5bbb71012d006060c1e6f950fb Mon Sep 17 00:00:00 2001 From: paulj Date: Wed, 18 Feb 2026 01:10:14 -0500 Subject: [PATCH 12/21] docs: Add practical guides links to platform quick start pages Add "Next Steps" links to the new /guides/ section across all platform documentation quick start pages. This helps users discover practical guidance on what to monitor, log, track, and investigate after initial SDK setup. Co-Authored-By: Claude --- docs/platforms/android/index.mdx | 1 + docs/platforms/dart/common/index.mdx | 1 + docs/platforms/dart/guides/flutter/index.mdx | 1 + docs/platforms/dotnet/guides/android/index.mdx | 4 ++++ docs/platforms/dotnet/guides/apple/index.mdx | 4 ++++ docs/platforms/dotnet/guides/aspnet/index.mdx | 4 ++++ docs/platforms/dotnet/guides/aspnetcore/index.mdx | 4 ++++ docs/platforms/dotnet/guides/aws-lambda/index.mdx | 4 ++++ docs/platforms/dotnet/guides/azure-functions-worker/index.mdx | 4 ++++ docs/platforms/dotnet/guides/blazor-webassembly/index.mdx | 4 ++++ docs/platforms/dotnet/guides/entityframework/index.mdx | 4 ++++ docs/platforms/dotnet/guides/extensions-logging/index.mdx | 4 ++++ docs/platforms/dotnet/guides/google-cloud-functions/index.mdx | 4 ++++ docs/platforms/dotnet/guides/log4net/index.mdx | 4 ++++ docs/platforms/dotnet/guides/maui/index.mdx | 4 ++++ docs/platforms/dotnet/guides/nlog/index.mdx | 4 ++++ docs/platforms/dotnet/guides/serilog/index.mdx | 4 ++++ docs/platforms/dotnet/guides/winforms/index.mdx | 4 ++++ docs/platforms/dotnet/guides/winui/index.mdx | 4 ++++ docs/platforms/dotnet/guides/wpf/index.mdx | 4 ++++ docs/platforms/dotnet/guides/xamarin/index.mdx | 4 ++++ docs/platforms/dotnet/index.mdx | 4 ++++ docs/platforms/elixir/index.mdx | 4 ++++ docs/platforms/go/common/index.mdx | 4 ++++ docs/platforms/go/guides/echo/index.mdx | 4 ++++ docs/platforms/go/guides/fasthttp/index.mdx | 4 ++++ docs/platforms/go/guides/fiber/index.mdx | 4 ++++ docs/platforms/go/guides/gin/index.mdx | 4 ++++ docs/platforms/go/guides/http/index.mdx | 4 ++++ docs/platforms/go/guides/iris/index.mdx | 4 ++++ docs/platforms/go/guides/logrus/index.mdx | 4 ++++ docs/platforms/go/guides/negroni/index.mdx | 4 ++++ docs/platforms/go/guides/slog/index.mdx | 4 ++++ docs/platforms/go/guides/zerolog/index.mdx | 4 ++++ docs/platforms/godot/index.mdx | 4 ++++ docs/platforms/java/common/index.mdx | 4 ++++ docs/platforms/java/guides/spring-boot/index.mdx | 4 ++++ docs/platforms/java/guides/spring/index.mdx | 4 ++++ docs/platforms/javascript/guides/angular/index.mdx | 1 + docs/platforms/javascript/guides/aws-lambda/index.mdx | 4 ++++ docs/platforms/javascript/guides/azure-functions/index.mdx | 1 + docs/platforms/javascript/guides/bun/index.mdx | 1 + docs/platforms/javascript/guides/capacitor/index.mdx | 4 ++++ docs/platforms/javascript/guides/cloudflare/index.mdx | 1 + docs/platforms/javascript/guides/cordova/index.mdx | 1 + docs/platforms/javascript/guides/deno/index.mdx | 1 + docs/platforms/javascript/guides/electron/index.mdx | 1 + docs/platforms/javascript/guides/ember/index.mdx | 1 + docs/platforms/javascript/guides/firebase/index.mdx | 1 + docs/platforms/javascript/guides/gatsby/index.mdx | 1 + docs/platforms/javascript/guides/gcp-functions/index.mdx | 1 + docs/platforms/javascript/guides/nestjs/index.mdx | 1 + docs/platforms/javascript/guides/nextjs/index.mdx | 1 + docs/platforms/javascript/guides/nuxt/index.mdx | 1 + docs/platforms/javascript/guides/react-router/index.mdx | 1 + docs/platforms/javascript/guides/react/index.mdx | 1 + docs/platforms/javascript/guides/remix/index.mdx | 1 + docs/platforms/javascript/guides/solid/index.mdx | 1 + docs/platforms/javascript/guides/solidstart/index.mdx | 1 + docs/platforms/javascript/guides/svelte/index.mdx | 1 + docs/platforms/javascript/guides/sveltekit/index.mdx | 1 + .../platforms/javascript/guides/tanstackstart-react/index.mdx | 1 + docs/platforms/javascript/guides/vue/index.mdx | 1 + docs/platforms/javascript/guides/wasm/index.mdx | 1 + docs/platforms/kotlin/guides/compose-multiplatform/index.mdx | 4 ++++ docs/platforms/kotlin/guides/kotlin-multiplatform/index.mdx | 1 + docs/platforms/native/common/index.mdx | 4 ++++ docs/platforms/native/guides/breakpad/index.mdx | 1 + docs/platforms/native/guides/crashpad/index.mdx | 1 + docs/platforms/native/guides/minidumps/index.mdx | 1 + docs/platforms/native/guides/wasm/index.mdx | 1 + docs/platforms/nintendo-switch/index.mdx | 1 + docs/platforms/php/guides/laravel/index.mdx | 4 ++++ docs/platforms/php/guides/symfony/index.mdx | 4 ++++ docs/platforms/php/index.mdx | 4 ++++ docs/platforms/playstation/index.mdx | 1 + docs/platforms/python/index.mdx | 4 ++++ docs/platforms/react-native/index.mdx | 1 + docs/platforms/ruby/common/index.mdx | 4 ++++ docs/platforms/rust/guides/actix-web/index.mdx | 4 ++++ docs/platforms/rust/guides/axum/index.mdx | 4 ++++ docs/platforms/rust/guides/tracing/index.mdx | 4 ++++ docs/platforms/rust/index.mdx | 4 ++++ docs/platforms/unity/index.mdx | 4 ++++ docs/platforms/unreal/index.mdx | 4 ++++ docs/platforms/xbox/index.mdx | 1 + includes/apple-platform-getting-started.mdx | 1 + .../getting-started-complete/javascript.astro.mdx | 2 ++ platform-includes/getting-started-complete/javascript.mdx | 1 + .../getting-started-complete/javascript.nuxt.mdx | 2 ++ .../getting-started-complete/javascript.remix.mdx | 1 + .../getting-started-complete/javascript.sveltekit.mdx | 2 ++ platform-includes/getting-started-node/javascript.mdx | 1 + 93 files changed, 246 insertions(+) diff --git a/docs/platforms/android/index.mdx b/docs/platforms/android/index.mdx index ded14c1bd01fc..ff78836ff873b 100644 --- a/docs/platforms/android/index.mdx +++ b/docs/platforms/android/index.mdx @@ -181,6 +181,7 @@ class MyActivity : AppCompatActivity() { ## Next Steps +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn about the features of Sentry's Android SDK - Learn how to enhance stack traces of your Sentry errors - Enrich events with additional context to make debugging simpler diff --git a/docs/platforms/dart/common/index.mdx b/docs/platforms/dart/common/index.mdx index baa27d2edd61d..75f4e920aadaa 100644 --- a/docs/platforms/dart/common/index.mdx +++ b/docs/platforms/dart/common/index.mdx @@ -91,5 +91,6 @@ try { ## Next Steps +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn about the features of Sentry's Dart SDK - Add performance instrumentation to your app diff --git a/docs/platforms/dart/guides/flutter/index.mdx b/docs/platforms/dart/guides/flutter/index.mdx index 4a95ab6fa49d8..9a4e796784877 100644 --- a/docs/platforms/dart/guides/flutter/index.mdx +++ b/docs/platforms/dart/guides/flutter/index.mdx @@ -162,6 +162,7 @@ try { ## Next Steps +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn about the features of Sentry's Flutter SDK - Add readable stack traces to errors - Add performance instrumentation to your app diff --git a/docs/platforms/dotnet/guides/android/index.mdx b/docs/platforms/dotnet/guides/android/index.mdx index 9e310f511e265..6382f4c9bec89 100644 --- a/docs/platforms/dotnet/guides/android/index.mdx +++ b/docs/platforms/dotnet/guides/android/index.mdx @@ -118,3 +118,7 @@ The default value is 1000. This snippet includes an intentional error, so you can test that everything is working as soon as you set it up. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/apple/index.mdx b/docs/platforms/dotnet/guides/apple/index.mdx index 4f0e670b90103..fce68d02fa330 100644 --- a/docs/platforms/dotnet/guides/apple/index.mdx +++ b/docs/platforms/dotnet/guides/apple/index.mdx @@ -84,3 +84,7 @@ The .NET for iOS, macOS, and Mac Catalyst integration is part of [Sentry](/platf This snippet includes an intentional error, so you can test that everything is working as soon as you set it up. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/aspnet/index.mdx b/docs/platforms/dotnet/guides/aspnet/index.mdx index 9dc391e97ef7b..01a23442670ed 100644 --- a/docs/platforms/dotnet/guides/aspnet/index.mdx +++ b/docs/platforms/dotnet/guides/aspnet/index.mdx @@ -129,3 +129,7 @@ For information about Troubleshooting, please visit the [troubleshooting](troubl ## Samples - A [sample with ASP.NET and EF 6](https://github.com/getsentry/examples/tree/master/dotnet/AspNetMvc5Ef6) and additional samples of the [.NET SDKs](https://github.com/getsentry/examples/tree/master/dotnet) + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/aspnetcore/index.mdx b/docs/platforms/dotnet/guides/aspnetcore/index.mdx index a97db264a3479..4b88c8a007593 100644 --- a/docs/platforms/dotnet/guides/aspnetcore/index.mdx +++ b/docs/platforms/dotnet/guides/aspnetcore/index.mdx @@ -273,3 +273,7 @@ Sentry.init({ ``` The [AspNetCore.Mvc sample](https://github.com/getsentry/sentry-dotnet/tree/main/samples/Sentry.Samples.AspNetCore.Mvc) uses this approach. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/aws-lambda/index.mdx b/docs/platforms/dotnet/guides/aws-lambda/index.mdx index 82e03fe40923d..cd73af06cf856 100644 --- a/docs/platforms/dotnet/guides/aws-lambda/index.mdx +++ b/docs/platforms/dotnet/guides/aws-lambda/index.mdx @@ -74,3 +74,7 @@ This snippet includes an intentional error, so you can test that everything is w ## Samples - Our [samples on GitHub](https://github.com/getsentry/sentry-dotnet/tree/main/samples/Sentry.Samples.Aws.Lambda.AspNetCoreServer) demonstrate Sentry on AWS Lambda. (**C#**) + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/azure-functions-worker/index.mdx b/docs/platforms/dotnet/guides/azure-functions-worker/index.mdx index cf1ebc6774d22..0c2ee421763dd 100644 --- a/docs/platforms/dotnet/guides/azure-functions-worker/index.mdx +++ b/docs/platforms/dotnet/guides/azure-functions-worker/index.mdx @@ -98,3 +98,7 @@ This snippet includes an intentional error, so you can test that everything is w ## Samples - [Azure Functions Sample](https://github.com/getsentry/sentry-dotnet/blob/main/samples/Sentry.Samples.OpenTelemetry.AzureFunctions/) demonstrates Sentry with Azure Functions Isolated Worker SDK. (**C#**) + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/blazor-webassembly/index.mdx b/docs/platforms/dotnet/guides/blazor-webassembly/index.mdx index c7163bd625652..47238187d469f 100644 --- a/docs/platforms/dotnet/guides/blazor-webassembly/index.mdx +++ b/docs/platforms/dotnet/guides/blazor-webassembly/index.mdx @@ -60,3 +60,7 @@ This snippet includes an intentional error, so you can test that everything is w ## Samples - This [integration with Blazor WebAssembly](https://github.com/getsentry/sentry-dotnet/tree/main/samples/Sentry.Samples.AspNetCore.Blazor.Wasm) sample demonstrates using Sentry with Blazor WebAssembly. (**C#**) + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/entityframework/index.mdx b/docs/platforms/dotnet/guides/entityframework/index.mdx index 3649699b783d2..5cde6ef1229ea 100644 --- a/docs/platforms/dotnet/guides/entityframework/index.mdx +++ b/docs/platforms/dotnet/guides/entityframework/index.mdx @@ -107,3 +107,7 @@ This snippet includes an intentional error, so you can test that everything is w Check out a complete working [sample](https://github.com/getsentry/sentry-dotnet-ef/tree/master/samples/Sentry.Samples.AspNet.Mvc) to see it in action. ![Sample breadcrumbs in Sentry](./img/dotnet-entityframework.png) + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/extensions-logging/index.mdx b/docs/platforms/dotnet/guides/extensions-logging/index.mdx index 8ca30d77f9798..54e397b2a4290 100644 --- a/docs/platforms/dotnet/guides/extensions-logging/index.mdx +++ b/docs/platforms/dotnet/guides/extensions-logging/index.mdx @@ -175,3 +175,7 @@ This snippet includes an intentional error, so you can test that everything is w - A [simple example](https://github.com/getsentry/sentry-dotnet/tree/main/samples/Sentry.Samples.ME.Logging) using simply the `LoggerFactory`. - An [example](https://github.com/getsentry/sentry-dotnet/tree/main/samples/Sentry.Samples.GenericHost) using the _generic host_. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/google-cloud-functions/index.mdx b/docs/platforms/dotnet/guides/google-cloud-functions/index.mdx index 790e9de7f9a50..9f5a88864acf8 100644 --- a/docs/platforms/dotnet/guides/google-cloud-functions/index.mdx +++ b/docs/platforms/dotnet/guides/google-cloud-functions/index.mdx @@ -166,3 +166,7 @@ This snippet includes an intentional error, so you can test that everything is w - [Google Cloud Functions sample](https://github.com/getsentry/sentry-dotnet/tree/main/samples/Sentry.Samples.Google.Cloud.Functions) - For [more samples](https://github.com/getsentry/sentry-dotnet-samples) of the .NET SDKs. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/log4net/index.mdx b/docs/platforms/dotnet/guides/log4net/index.mdx index 31712fac53d06..1c239fea255b0 100644 --- a/docs/platforms/dotnet/guides/log4net/index.mdx +++ b/docs/platforms/dotnet/guides/log4net/index.mdx @@ -66,3 +66,7 @@ This snippet includes an intentional error, so you can test that everything is w For a [sample app.config](https://github.com/getsentry/sentry-dotnet/blob/main/samples/Sentry.Samples.Log4Net/app.config) or a complete working [sample](https://github.com/getsentry/sentry-dotnet/tree/main/samples/Sentry.Samples.Log4Net) to see it in action. ![Sample event in Sentry](./img/log4net-sample.gif) + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/maui/index.mdx b/docs/platforms/dotnet/guides/maui/index.mdx index 50201bf4e2987..bd422b0b246cb 100644 --- a/docs/platforms/dotnet/guides/maui/index.mdx +++ b/docs/platforms/dotnet/guides/maui/index.mdx @@ -123,3 +123,7 @@ Use caution when enabling, as such values may contain personally identifiable in This snippet includes an intentional error, so you can test that everything is working as soon as you set it up. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/nlog/index.mdx b/docs/platforms/dotnet/guides/nlog/index.mdx index b17176d4ced46..1e4fae1abe5a7 100644 --- a/docs/platforms/dotnet/guides/nlog/index.mdx +++ b/docs/platforms/dotnet/guides/nlog/index.mdx @@ -207,3 +207,7 @@ This snippet includes an intentional error, so you can test that everything is w - A [simple example](https://github.com/getsentry/sentry-dotnet/tree/main/samples/Sentry.Samples.NLog). - Example of [advanced configuration](configuration/advanced-configuration-example) + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/serilog/index.mdx b/docs/platforms/dotnet/guides/serilog/index.mdx index b9fc0ad6c85aa..767c129dc6ecd 100644 --- a/docs/platforms/dotnet/guides/serilog/index.mdx +++ b/docs/platforms/dotnet/guides/serilog/index.mdx @@ -97,3 +97,7 @@ This snippet includes an intentional error, so you can test that everything is w - A [simple example](https://github.com/getsentry/sentry-dotnet/tree/main/samples/Sentry.Samples.Serilog). - An [example with ASP.NET Core](https://github.com/getsentry/sentry-dotnet/tree/main/samples/Sentry.Samples.AspNetCore.Serilog). + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/winforms/index.mdx b/docs/platforms/dotnet/guides/winforms/index.mdx index 20b2ccd6b7d6d..8cbd6de571746 100644 --- a/docs/platforms/dotnet/guides/winforms/index.mdx +++ b/docs/platforms/dotnet/guides/winforms/index.mdx @@ -235,3 +235,7 @@ This snippet includes an intentional error, so you can test that everything is w ## Resources [Discussion on GitHub `Application.SetUnhandledExceptionMode`](https://github.com/getsentry/sentry-dotnet/issues/176) + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/winui/index.mdx b/docs/platforms/dotnet/guides/winui/index.mdx index beb9ca8e3f0a3..b2d9a8d58a816 100644 --- a/docs/platforms/dotnet/guides/winui/index.mdx +++ b/docs/platforms/dotnet/guides/winui/index.mdx @@ -156,3 +156,7 @@ sealed partial class App : Application This snippet includes an intentional error, so you can test that everything is working as soon as you set it up. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/wpf/index.mdx b/docs/platforms/dotnet/guides/wpf/index.mdx index 17bcf507ee843..a73c37958c402 100644 --- a/docs/platforms/dotnet/guides/wpf/index.mdx +++ b/docs/platforms/dotnet/guides/wpf/index.mdx @@ -77,3 +77,7 @@ public partial class App : Application This snippet includes an intentional error, so you can test that everything is working as soon as you set it up. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/guides/xamarin/index.mdx b/docs/platforms/dotnet/guides/xamarin/index.mdx index 4dd41a94aad02..2f1cf14199e4b 100644 --- a/docs/platforms/dotnet/guides/xamarin/index.mdx +++ b/docs/platforms/dotnet/guides/xamarin/index.mdx @@ -92,3 +92,7 @@ For information about Troubleshooting, please visit the [troubleshooting](troubl ## Samples - An [example](https://github.com/getsentry/sentry-xamarin/tree/main/Samples) using Xamarin Forms and most of the SDK features. (**Android, iOS, UWP**) + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/dotnet/index.mdx b/docs/platforms/dotnet/index.mdx index d4da60e9d2c83..b8181ba3ec7ae 100644 --- a/docs/platforms/dotnet/index.mdx +++ b/docs/platforms/dotnet/index.mdx @@ -89,3 +89,7 @@ SentrySdk.Init(options => This snippet includes an intentional error, so you can test that everything is working as soon as you set it up. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/elixir/index.mdx b/docs/platforms/elixir/index.mdx index 0fff6c05aae94..21af83ed257fb 100644 --- a/docs/platforms/elixir/index.mdx +++ b/docs/platforms/elixir/index.mdx @@ -40,3 +40,7 @@ Learn more about manually capturing an error or message in our To view and resolve the recorded error, log into [sentry.io](https://sentry.io) and select your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/go/common/index.mdx b/docs/platforms/go/common/index.mdx index 4179c4a200eee..fccb464507e6e 100644 --- a/docs/platforms/go/common/index.mdx +++ b/docs/platforms/go/common/index.mdx @@ -33,3 +33,7 @@ Learn more about manually capturing an error or message in our To view and resolve the recorded error, log into [sentry.io](https://sentry.io) and select your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/go/guides/echo/index.mdx b/docs/platforms/go/guides/echo/index.mdx index c083f518b7e04..60990f4804451 100644 --- a/docs/platforms/go/guides/echo/index.mdx +++ b/docs/platforms/go/guides/echo/index.mdx @@ -136,3 +136,7 @@ sentry.Init(sentry.ClientOptions{ }, }) ``` + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/go/guides/fasthttp/index.mdx b/docs/platforms/go/guides/fasthttp/index.mdx index 167a91fb81527..f929e6e9b8831 100644 --- a/docs/platforms/go/guides/fasthttp/index.mdx +++ b/docs/platforms/go/guides/fasthttp/index.mdx @@ -144,3 +144,7 @@ sentry.Init(sentry.ClientOptions{ }, }) ``` + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/go/guides/fiber/index.mdx b/docs/platforms/go/guides/fiber/index.mdx index 3a3128125ad7c..acc99fc0511d2 100644 --- a/docs/platforms/go/guides/fiber/index.mdx +++ b/docs/platforms/go/guides/fiber/index.mdx @@ -135,3 +135,7 @@ sentry.Init(sentry.ClientOptions{ }, }) ``` + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/go/guides/gin/index.mdx b/docs/platforms/go/guides/gin/index.mdx index 54e811ceb9148..a1024f85b601e 100644 --- a/docs/platforms/go/guides/gin/index.mdx +++ b/docs/platforms/go/guides/gin/index.mdx @@ -130,3 +130,7 @@ sentry.Init(sentry.ClientOptions{ }, }) ``` + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/go/guides/http/index.mdx b/docs/platforms/go/guides/http/index.mdx index bf03bbb552308..6d50fbf2c28a0 100644 --- a/docs/platforms/go/guides/http/index.mdx +++ b/docs/platforms/go/guides/http/index.mdx @@ -143,3 +143,7 @@ sentry.Init(sentry.ClientOptions{ }, }) ``` + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/go/guides/iris/index.mdx b/docs/platforms/go/guides/iris/index.mdx index 473b819039f39..e1dc4b2acab8d 100644 --- a/docs/platforms/go/guides/iris/index.mdx +++ b/docs/platforms/go/guides/iris/index.mdx @@ -130,3 +130,7 @@ sentry.Init(sentry.ClientOptions{ }, }) ``` + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/go/guides/logrus/index.mdx b/docs/platforms/go/guides/logrus/index.mdx index b05fcec5dcba4..a16a111e49c51 100644 --- a/docs/platforms/go/guides/logrus/index.mdx +++ b/docs/platforms/go/guides/logrus/index.mdx @@ -182,3 +182,7 @@ if client != nil { ## Logs For comprehensive logging setup with Logrus, including advanced configuration options and best practices, see the [Go Logs documentation](/platforms/go/logs/). The Logrus integration shown above provides seamless integration with Sentry's structured logging features. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/go/guides/negroni/index.mdx b/docs/platforms/go/guides/negroni/index.mdx index 7138f898e95ae..3cc5883ce26c2 100644 --- a/docs/platforms/go/guides/negroni/index.mdx +++ b/docs/platforms/go/guides/negroni/index.mdx @@ -163,3 +163,7 @@ app.UseHandler(mux) http.ListenAndServe(":3000", app) ``` + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/go/guides/slog/index.mdx b/docs/platforms/go/guides/slog/index.mdx index fc8edfa8cafdc..534e18f57dff3 100644 --- a/docs/platforms/go/guides/slog/index.mdx +++ b/docs/platforms/go/guides/slog/index.mdx @@ -88,3 +88,7 @@ logger.With("key.string", "value").Info("An error occurred") ## Logs For comprehensive logging setup with slog, including advanced configuration options and best practices, see the [Go Logs documentation](/platforms/go/logs/). The slog integration shown above provides seamless integration with Sentry's structured logging features. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/go/guides/zerolog/index.mdx b/docs/platforms/go/guides/zerolog/index.mdx index 4966c02d43a80..51e19f66d7aa5 100644 --- a/docs/platforms/go/guides/zerolog/index.mdx +++ b/docs/platforms/go/guides/zerolog/index.mdx @@ -159,3 +159,7 @@ This ensures that logs from specific contexts or threads use the appropriate Sen Use Zerolog as you normally would, and it will automatically send logs at or above the specified levels to Sentry. Note: Ensure Sentry is flushed before the application exits to avoid losing any pending events. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/godot/index.mdx b/docs/platforms/godot/index.mdx index f2ccb5b1a4c8f..3757cad916aca 100644 --- a/docs/platforms/godot/index.mdx +++ b/docs/platforms/godot/index.mdx @@ -42,3 +42,7 @@ Learn more about manually capturing an error or message in our To view and resolve the recorded error, log into [sentry.io](https://sentry.io) and select your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/java/common/index.mdx b/docs/platforms/java/common/index.mdx index 00ceed9ceb552..19690d65913ec 100644 --- a/docs/platforms/java/common/index.mdx +++ b/docs/platforms/java/common/index.mdx @@ -35,3 +35,7 @@ Learn more about manually capturing an error or message in our To view and resolve the recorded error, log into [sentry.io](https://sentry.io) and select your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/java/guides/spring-boot/index.mdx b/docs/platforms/java/guides/spring-boot/index.mdx index 95da1d4a0037a..d9a14e7b098ae 100644 --- a/docs/platforms/java/guides/spring-boot/index.mdx +++ b/docs/platforms/java/guides/spring-boot/index.mdx @@ -37,3 +37,7 @@ Learn more about manually capturing an error or message in our To view and resolve the recorded error, log into [sentry.io](https://sentry.io) and select your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/java/guides/spring/index.mdx b/docs/platforms/java/guides/spring/index.mdx index c305185e86965..e7a8eb447c32b 100644 --- a/docs/platforms/java/guides/spring/index.mdx +++ b/docs/platforms/java/guides/spring/index.mdx @@ -37,3 +37,7 @@ Learn more about manually capturing an error or message in our To view and resolve the recorded error, log into [sentry.io](https://sentry.io) and select your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/javascript/guides/angular/index.mdx b/docs/platforms/javascript/guides/angular/index.mdx index cf9d8b14f8921..72389d55aa207 100644 --- a/docs/platforms/javascript/guides/angular/index.mdx +++ b/docs/platforms/javascript/guides/angular/index.mdx @@ -80,6 +80,7 @@ At this point, you should have integrated Sentry into Angular application and sh Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Extend Sentry to your backend using one of our [SDKs](/) - Continue to customize your configuration - Make use of Angular-specific features diff --git a/docs/platforms/javascript/guides/aws-lambda/index.mdx b/docs/platforms/javascript/guides/aws-lambda/index.mdx index fa8592dba9e6e..904ee6ddd79c0 100644 --- a/docs/platforms/javascript/guides/aws-lambda/index.mdx +++ b/docs/platforms/javascript/guides/aws-lambda/index.mdx @@ -52,3 +52,7 @@ export const handler = Sentry.wrapHandler(async (event, context) => { throw new Error("This is a test error"); })); ``` + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/javascript/guides/azure-functions/index.mdx b/docs/platforms/javascript/guides/azure-functions/index.mdx index 43eaf012d2c67..31ccdf7c9732f 100644 --- a/docs/platforms/javascript/guides/azure-functions/index.mdx +++ b/docs/platforms/javascript/guides/azure-functions/index.mdx @@ -175,6 +175,7 @@ At this point, you should have integrated Sentry into your Azure Function and sh Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Continue to customize your configuration - Learn how to manually capture errors - Get familiar with [Sentry's product features](/) like tracing, insights, and alerts diff --git a/docs/platforms/javascript/guides/bun/index.mdx b/docs/platforms/javascript/guides/bun/index.mdx index 61e1ca8ef2236..4459845808df7 100644 --- a/docs/platforms/javascript/guides/bun/index.mdx +++ b/docs/platforms/javascript/guides/bun/index.mdx @@ -137,6 +137,7 @@ At this point, you should have integrated Sentry into your Bun application, whic Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Extend Sentry to your frontend using one of our [frontend SDKs](/) - Learn how to manually capture errors - Continue to customize your configuration diff --git a/docs/platforms/javascript/guides/capacitor/index.mdx b/docs/platforms/javascript/guides/capacitor/index.mdx index 992b2961079a8..0bd10a0c9fce7 100644 --- a/docs/platforms/javascript/guides/capacitor/index.mdx +++ b/docs/platforms/javascript/guides/capacitor/index.mdx @@ -564,3 +564,7 @@ Learn more about manually capturing an error or message in our To view and resolve the recorded error, log into [sentry.io](https://sentry.io) and select your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/javascript/guides/cloudflare/index.mdx b/docs/platforms/javascript/guides/cloudflare/index.mdx index 61829fcbe953b..a07ef31f5753e 100644 --- a/docs/platforms/javascript/guides/cloudflare/index.mdx +++ b/docs/platforms/javascript/guides/cloudflare/index.mdx @@ -221,6 +221,7 @@ At this point, you should have integrated Sentry and should already be sending d Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn how to [manually capture errors](/platforms/javascript/guides/cloudflare/usage/) - Continue to [customize your configuration](/platforms/javascript/guides/cloudflare/configuration/) - Make use of [Cloudflare-specific features](/platforms/javascript/guides/cloudflare/features) diff --git a/docs/platforms/javascript/guides/cordova/index.mdx b/docs/platforms/javascript/guides/cordova/index.mdx index 6f1e4980feb6c..aa3f1381a23ca 100644 --- a/docs/platforms/javascript/guides/cordova/index.mdx +++ b/docs/platforms/javascript/guides/cordova/index.mdx @@ -93,6 +93,7 @@ At this point, you should have integrated Sentry into your Cordova application a Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Continue to customize your configuration - Learn how to upload debug symbols to make sure your native stack traces are readable - Check our [Ionic support guide](/platforms/javascript/guides/cordova/ionic/) diff --git a/docs/platforms/javascript/guides/deno/index.mdx b/docs/platforms/javascript/guides/deno/index.mdx index 9198844a3c363..80fbd940a5aa5 100644 --- a/docs/platforms/javascript/guides/deno/index.mdx +++ b/docs/platforms/javascript/guides/deno/index.mdx @@ -138,6 +138,7 @@ At this point, you should have integrated Sentry into your Deno application and Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Extend Sentry to your frontend using one of our [frontend SDKs](/) - Learn how to manually capture errors - Continue to customize your configuration diff --git a/docs/platforms/javascript/guides/electron/index.mdx b/docs/platforms/javascript/guides/electron/index.mdx index 360f7b83b329d..188f2aff4c67b 100644 --- a/docs/platforms/javascript/guides/electron/index.mdx +++ b/docs/platforms/javascript/guides/electron/index.mdx @@ -256,6 +256,7 @@ At this point, you should have integrated Sentry into your Electron application Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Continue to customize your configuration - Learn how to manually capture errors - Make use of Electron-specific features diff --git a/docs/platforms/javascript/guides/ember/index.mdx b/docs/platforms/javascript/guides/ember/index.mdx index df76bcee5c681..079522d16fd8b 100644 --- a/docs/platforms/javascript/guides/ember/index.mdx +++ b/docs/platforms/javascript/guides/ember/index.mdx @@ -176,6 +176,7 @@ At this point, you should have integrated Sentry into your Ember application and Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn how to [manually capture errors](/platforms/javascript/guides/ember/usage/) - Continue to [customize your configuration](/platforms/javascript/guides/ember/configuration/) - Get familiar with [Sentry's product features](/product/) like tracing, insights, and alerts diff --git a/docs/platforms/javascript/guides/firebase/index.mdx b/docs/platforms/javascript/guides/firebase/index.mdx index 5e75dc28723f9..caf9f38d480b9 100644 --- a/docs/platforms/javascript/guides/firebase/index.mdx +++ b/docs/platforms/javascript/guides/firebase/index.mdx @@ -184,6 +184,7 @@ At this point, you should have integrated Sentry into your Cloud Functions for F Now's a good time to customize your setup and look into more advanced topics: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Continue to customize your configuration - Learn how to manually capture errors - Get familiar with [Sentry's product features](/product/) like tracing, insights, and alerts diff --git a/docs/platforms/javascript/guides/gatsby/index.mdx b/docs/platforms/javascript/guides/gatsby/index.mdx index 9f89caca16793..4682ffd85df08 100644 --- a/docs/platforms/javascript/guides/gatsby/index.mdx +++ b/docs/platforms/javascript/guides/gatsby/index.mdx @@ -198,6 +198,7 @@ At this point, you should have integrated Sentry into your Gatsby application an Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Extend Sentry to your backend using one of our [SDKs](/) - Continue to customize your configuration - Learn how to manually capture errors diff --git a/docs/platforms/javascript/guides/gcp-functions/index.mdx b/docs/platforms/javascript/guides/gcp-functions/index.mdx index 1a1203edded55..fb63c7359fc70 100644 --- a/docs/platforms/javascript/guides/gcp-functions/index.mdx +++ b/docs/platforms/javascript/guides/gcp-functions/index.mdx @@ -132,6 +132,7 @@ At this point, you should have integrated Sentry into your Google Cloud Platform Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Continue to customize your configuration - Learn how to manually capture errors - Get familiar with [Sentry's product features](/product/) like tracing, insights, and alerts diff --git a/docs/platforms/javascript/guides/nestjs/index.mdx b/docs/platforms/javascript/guides/nestjs/index.mdx index 016bade28f993..6ced340c9130d 100644 --- a/docs/platforms/javascript/guides/nestjs/index.mdx +++ b/docs/platforms/javascript/guides/nestjs/index.mdx @@ -106,6 +106,7 @@ At this point, you should have integrated Sentry into your Nest.js application a Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Extend Sentry to your frontend using one of our [frontend SDKs](/) - Learn how to [manually capture errors](/platforms/javascript/guides/nestjs/usage/) - Continue to [customize your configuration](/platforms/javascript/guides/nestjs/configuration/) diff --git a/docs/platforms/javascript/guides/nextjs/index.mdx b/docs/platforms/javascript/guides/nextjs/index.mdx index af9e5843b3d06..be8906efafb7f 100644 --- a/docs/platforms/javascript/guides/nextjs/index.mdx +++ b/docs/platforms/javascript/guides/nextjs/index.mdx @@ -335,6 +335,7 @@ Learn more about [Logs configuration](/platforms/javascript/guides/nextjs/logs/) You've successfully integrated Sentry into your Next.js application! Here's what to explore next: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - [Logs Integrations](/platforms/javascript/guides/nextjs/logs/#integrations) - Connect popular logging libraries like Pino, Winston, and Bunyan - [Distributed Tracing](/platforms/javascript/guides/nextjs/tracing/distributed-tracing/) - Trace requests across services and microservices - [AI Agent Monitoring](/platforms/javascript/guides/nextjs/ai-agent-monitoring/) - Monitor AI agents built with Vercel AI SDK, LangChain, and more diff --git a/docs/platforms/javascript/guides/nuxt/index.mdx b/docs/platforms/javascript/guides/nuxt/index.mdx index a950a2c6df1ab..2fe4b2165d775 100644 --- a/docs/platforms/javascript/guides/nuxt/index.mdx +++ b/docs/platforms/javascript/guides/nuxt/index.mdx @@ -103,6 +103,7 @@ At this point, you should have integrated Sentry into your Nuxt application and Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn how to [manually capture errors](/platforms/javascript/guides/nuxt/usage/) - Continue to [customize your configuration](/platforms/javascript/guides/nuxt/configuration/) - Get familiar with [Sentry's product features](/product) like tracing, insights, and alerts diff --git a/docs/platforms/javascript/guides/react-router/index.mdx b/docs/platforms/javascript/guides/react-router/index.mdx index 8be24ca9d0fe7..7504409b216c7 100644 --- a/docs/platforms/javascript/guides/react-router/index.mdx +++ b/docs/platforms/javascript/guides/react-router/index.mdx @@ -257,6 +257,7 @@ At this point, you should have integrated Sentry into your React Router Framewor Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn how to manually capture errors - Continue to customize your configuration - Get familiar with [Sentry's product features](/product/) like tracing, insights, and alerts diff --git a/docs/platforms/javascript/guides/react/index.mdx b/docs/platforms/javascript/guides/react/index.mdx index cb115f2046940..84db6936f704a 100644 --- a/docs/platforms/javascript/guides/react/index.mdx +++ b/docs/platforms/javascript/guides/react/index.mdx @@ -440,6 +440,7 @@ For more help, see the Troubleshooting page You've successfully integrated Sentry into your React application! Here's what to explore next: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - [Session Replay](/platforms/javascript/guides/react/session-replay/) — Watch video-like reproductions of user sessions to debug errors in context - [Distributed Tracing](/platforms/javascript/guides/react/tracing/distributed-tracing/) — Trace requests from your React frontend to backend services - [Connect GitHub + Seer](/organization/integrations/source-code-mgmt/github/#installing-github) — Enable AI-powered [root cause analysis](/product/ai-in-sentry/seer/) by connecting your repository diff --git a/docs/platforms/javascript/guides/remix/index.mdx b/docs/platforms/javascript/guides/remix/index.mdx index b9655c17186b5..0557f18f36572 100644 --- a/docs/platforms/javascript/guides/remix/index.mdx +++ b/docs/platforms/javascript/guides/remix/index.mdx @@ -103,6 +103,7 @@ At this point, you should have integrated Sentry into your Remix application and Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn how to [manually capture errors](/platforms/javascript/guides/remix/usage/) - Continue to [customize your configuration](/platforms/javascript/guides/remix/configuration/) - Get familiar with [Sentry's product features](/product/) like tracing, insights, and alerts diff --git a/docs/platforms/javascript/guides/solid/index.mdx b/docs/platforms/javascript/guides/solid/index.mdx index ec7de3f11d098..5d09b87b95f5f 100644 --- a/docs/platforms/javascript/guides/solid/index.mdx +++ b/docs/platforms/javascript/guides/solid/index.mdx @@ -192,6 +192,7 @@ At this point, you should have integrated Sentry into your Solid application and Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Extend Sentry to your backend using one of our [SDKs](/) - Continue to customize your configuration - Make use of Solid-specific features diff --git a/docs/platforms/javascript/guides/solidstart/index.mdx b/docs/platforms/javascript/guides/solidstart/index.mdx index 6ec5ff0f228c1..4a5102cb757c9 100644 --- a/docs/platforms/javascript/guides/solidstart/index.mdx +++ b/docs/platforms/javascript/guides/solidstart/index.mdx @@ -370,6 +370,7 @@ At this point, you should have integrated Sentry into your SolidStart applicatio Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn how to manually capture errors - Continue to customize your configuration - Learn how to make use of SolidStart-specific features diff --git a/docs/platforms/javascript/guides/svelte/index.mdx b/docs/platforms/javascript/guides/svelte/index.mdx index 6391d42ceb9ec..53487083ddb3c 100644 --- a/docs/platforms/javascript/guides/svelte/index.mdx +++ b/docs/platforms/javascript/guides/svelte/index.mdx @@ -283,6 +283,7 @@ At this point, you should have integrated Sentry into your Svelte application an Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Extend Sentry to your backend using one of our [SDKs](/) - Continue to customize your configuration - Make use of Svelte-specific features diff --git a/docs/platforms/javascript/guides/sveltekit/index.mdx b/docs/platforms/javascript/guides/sveltekit/index.mdx index efd2eca2fa6d7..b424771bcad85 100644 --- a/docs/platforms/javascript/guides/sveltekit/index.mdx +++ b/docs/platforms/javascript/guides/sveltekit/index.mdx @@ -73,6 +73,7 @@ At this point, you should have integrated Sentry into your SvelteKit application Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn how to [manually capture errors](/platforms/javascript/guides/sveltekit/usage/) - Continue to [customize your configuration](/platforms/javascript/guides/sveltekit/configuration/) - Learn how to [manually instrument](/platforms/javascript/guides/sveltekit/apis#load-function-instrumentation) SvelteKit-specific features diff --git a/docs/platforms/javascript/guides/tanstackstart-react/index.mdx b/docs/platforms/javascript/guides/tanstackstart-react/index.mdx index 568ff96a89837..3c173eee88cef 100644 --- a/docs/platforms/javascript/guides/tanstackstart-react/index.mdx +++ b/docs/platforms/javascript/guides/tanstackstart-react/index.mdx @@ -391,6 +391,7 @@ At this point, you should have integrated Sentry into your TanStack Start React Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn how to [manually capture errors](/platforms/javascript/guides/tanstackstart-react/usage/) - Continue to [customize your configuration](/platforms/javascript/guides/tanstackstart-react/configuration/) - Get familiar with [Sentry's product features](/product/) like tracing, insights, and alerts diff --git a/docs/platforms/javascript/guides/vue/index.mdx b/docs/platforms/javascript/guides/vue/index.mdx index 4d33cd0613577..6540aca0262a5 100644 --- a/docs/platforms/javascript/guides/vue/index.mdx +++ b/docs/platforms/javascript/guides/vue/index.mdx @@ -298,6 +298,7 @@ At this point, you should have integrated Sentry into your Vue application and s Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Extend Sentry to your backend using one of our [SDKs](/) - Continue to customize your configuration - Make use of Vue-specific features diff --git a/docs/platforms/javascript/guides/wasm/index.mdx b/docs/platforms/javascript/guides/wasm/index.mdx index e4bd6da115ce3..8afbd943711aa 100644 --- a/docs/platforms/javascript/guides/wasm/index.mdx +++ b/docs/platforms/javascript/guides/wasm/index.mdx @@ -195,6 +195,7 @@ At this point, you should have integrated Sentry into your JavaScript applicatio Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Instrument your frontend and backend using our [SDKs](/) - Continue to [customize your configuration](/platforms/javascript/guides/wasm/configuration) - Learn how to [manually capture errors](/platforms/javascript/guides/wasm/usage) diff --git a/docs/platforms/kotlin/guides/compose-multiplatform/index.mdx b/docs/platforms/kotlin/guides/compose-multiplatform/index.mdx index cdcd623dda435..df4fb6c489658 100644 --- a/docs/platforms/kotlin/guides/compose-multiplatform/index.mdx +++ b/docs/platforms/kotlin/guides/compose-multiplatform/index.mdx @@ -55,3 +55,7 @@ For Android applications, you need to manually upload ProGuard mapping files usi ### iOS For iOS applications, follow the [Uploading Debug Symbols guide](/platforms/apple/guides/ios/dsym) to set up debug symbols upload. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/kotlin/guides/kotlin-multiplatform/index.mdx b/docs/platforms/kotlin/guides/kotlin-multiplatform/index.mdx index 856d3c362725a..3ad27af0e2f89 100644 --- a/docs/platforms/kotlin/guides/kotlin-multiplatform/index.mdx +++ b/docs/platforms/kotlin/guides/kotlin-multiplatform/index.mdx @@ -41,6 +41,7 @@ To view and resolve the recorded error, log into [sentry.io](https://sentry.io) ## Next Steps +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn more about Sentry's Kotlin Multiplatform SDK features - Learn about different ways to initialize the SDK - See configuration options for the Kotlin Multiplatform Gradle Plugin diff --git a/docs/platforms/native/common/index.mdx b/docs/platforms/native/common/index.mdx index 982b872dd61cb..eac4618542734 100644 --- a/docs/platforms/native/common/index.mdx +++ b/docs/platforms/native/common/index.mdx @@ -31,3 +31,7 @@ Learn more about manually capturing an error or message in our To view and resolve the recorded error, log into [sentry.io](https://sentry.io) and select your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/native/guides/breakpad/index.mdx b/docs/platforms/native/guides/breakpad/index.mdx index 250d49de8ac7e..c493bcd73f3f2 100644 --- a/docs/platforms/native/guides/breakpad/index.mdx +++ b/docs/platforms/native/guides/breakpad/index.mdx @@ -85,3 +85,4 @@ bool UploadMinidump(std::string &path) { ); } ``` + diff --git a/docs/platforms/native/guides/crashpad/index.mdx b/docs/platforms/native/guides/crashpad/index.mdx index 752ac15adb746..9be7076f096c4 100644 --- a/docs/platforms/native/guides/crashpad/index.mdx +++ b/docs/platforms/native/guides/crashpad/index.mdx @@ -78,3 +78,4 @@ By default, the crashpad handler will limit uploads to one per hour. To disable ```cpp arguments.push_back("--no-rate-limit"); ``` + diff --git a/docs/platforms/native/guides/minidumps/index.mdx b/docs/platforms/native/guides/minidumps/index.mdx index a49d59487042b..b25bab4907804 100644 --- a/docs/platforms/native/guides/minidumps/index.mdx +++ b/docs/platforms/native/guides/minidumps/index.mdx @@ -129,3 +129,4 @@ uploads. These limits are subject to future change and defined currently as: + diff --git a/docs/platforms/native/guides/wasm/index.mdx b/docs/platforms/native/guides/wasm/index.mdx index 64bc149ff84eb..c3aa7b2178d02 100644 --- a/docs/platforms/native/guides/wasm/index.mdx +++ b/docs/platforms/native/guides/wasm/index.mdx @@ -106,3 +106,4 @@ Here is an example event for WebAssembly: } } ``` + diff --git a/docs/platforms/nintendo-switch/index.mdx b/docs/platforms/nintendo-switch/index.mdx index 99e92a848ad3d..e9f6548c291c9 100644 --- a/docs/platforms/nintendo-switch/index.mdx +++ b/docs/platforms/nintendo-switch/index.mdx @@ -15,3 +15,4 @@ You can also use Sentry's [Unity](/platforms/unity/game-consoles/) and [Unreal E ---- "Nintendo", "Nintendo Switch" are trademarks or registered trademarks of Nintendo. + diff --git a/docs/platforms/php/guides/laravel/index.mdx b/docs/platforms/php/guides/laravel/index.mdx index ce7e7a57e2407..8ee3666001a28 100644 --- a/docs/platforms/php/guides/laravel/index.mdx +++ b/docs/platforms/php/guides/laravel/index.mdx @@ -120,3 +120,7 @@ If you do leave Sentry enabled when developing or running tests, it's possible f If you're using Laravel's Forge platform to provision and deploy your PHP application, you can create a Sentry organization through [Forge](https://forge.laravel.com/docs/integrations/sentry.html). ![Sentry and Forge](./img/forge-sentry.png) + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/php/guides/symfony/index.mdx b/docs/platforms/php/guides/symfony/index.mdx index 0d4d1a365c4d7..9c0cff050cb2b 100644 --- a/docs/platforms/php/guides/symfony/index.mdx +++ b/docs/platforms/php/guides/symfony/index.mdx @@ -67,3 +67,7 @@ class SentryTestController extends AbstractController ``` After you visit the `/_sentry-test` page, you can view and resolve the recorded error by logging into [sentry.io](https://sentry.io) and opening your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/php/index.mdx b/docs/platforms/php/index.mdx index c019bbc430af6..da3aeed7159a5 100644 --- a/docs/platforms/php/index.mdx +++ b/docs/platforms/php/index.mdx @@ -90,3 +90,7 @@ try { If you're using Laravel's Forge platform to provision and deploy your PHP application, you can create a Sentry organization through [Forge](https://forge.laravel.com/docs/integrations/sentry.html). ![Sentry and Forge](./img/forge-sentry.png) + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/playstation/index.mdx b/docs/platforms/playstation/index.mdx index 50e4eadb257c8..e5b692d1f2caa 100644 --- a/docs/platforms/playstation/index.mdx +++ b/docs/platforms/playstation/index.mdx @@ -20,3 +20,4 @@ Access to Sentry's error and crash reporting for consoles is a paid feature. We ---- "PlayStation", "PS5" are registered trademarks or trademarks of Sony Interactive Entertainment Inc. + diff --git a/docs/platforms/python/index.mdx b/docs/platforms/python/index.mdx index aca9f92b4c3a9..e7d7726ba99b8 100644 --- a/docs/platforms/python/index.mdx +++ b/docs/platforms/python/index.mdx @@ -101,3 +101,7 @@ To view and resolve the recorded error, log into [sentry.io](https://sentry.io) Not seeing your error in Sentry? Make sure you're running the above example from a file and not from a Python shell like IPython. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/react-native/index.mdx b/docs/platforms/react-native/index.mdx index bdb9394e641d0..e7fa2bb589f0d 100644 --- a/docs/platforms/react-native/index.mdx +++ b/docs/platforms/react-native/index.mdx @@ -130,6 +130,7 @@ Sentry.nativeCrash(); ## Next Steps +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn about the features of Sentry's React Native SDK - Add readable stack traces to errors - Add Apple Privacy manifest diff --git a/docs/platforms/ruby/common/index.mdx b/docs/platforms/ruby/common/index.mdx index b687e4e39d26c..6f1e062b0a0a6 100644 --- a/docs/platforms/ruby/common/index.mdx +++ b/docs/platforms/ruby/common/index.mdx @@ -38,3 +38,7 @@ Learn more about manually capturing an error or message in our To view and resolve the recorded error, log into [sentry.io](https://sentry.io) and select your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/rust/guides/actix-web/index.mdx b/docs/platforms/rust/guides/actix-web/index.mdx index beb77f680c085..9dcda181c6cc2 100644 --- a/docs/platforms/rust/guides/actix-web/index.mdx +++ b/docs/platforms/rust/guides/actix-web/index.mdx @@ -93,3 +93,7 @@ Learn more about manually capturing an error or message in our To view and resolve the recorded error, log into [sentry.io](https://sentry.io) and select your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/rust/guides/axum/index.mdx b/docs/platforms/rust/guides/axum/index.mdx index f045e23454db0..dc4a83742116a 100644 --- a/docs/platforms/rust/guides/axum/index.mdx +++ b/docs/platforms/rust/guides/axum/index.mdx @@ -105,3 +105,7 @@ Learn more about manually capturing an error or message in our To view and resolve the recorded panic, log into [sentry.io](https://sentry.io) and select your project. Select Issues, and then Errors & Outages in the sidebar, where you will find the newly created issue. Clicking on the issue's title will open a page where you can see detailed information and mark it as resolved. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/rust/guides/tracing/index.mdx b/docs/platforms/rust/guides/tracing/index.mdx index 9a5abe4643694..c779c3058551a 100644 --- a/docs/platforms/rust/guides/tracing/index.mdx +++ b/docs/platforms/rust/guides/tracing/index.mdx @@ -122,3 +122,7 @@ To view and resolve the recorded error, log into [sentry.io](https://sentry.io) If you're using tracing (the Sentry feature), you can view the recorded traces and spans by selecting Explore, and then Traces in the sidebar. If you're using logs, you can view the recorded logs by selecting Explore, and then Logs in the sidebar. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/rust/index.mdx b/docs/platforms/rust/index.mdx index 116ad0d3b95a8..6548c8df738cb 100644 --- a/docs/platforms/rust/index.mdx +++ b/docs/platforms/rust/index.mdx @@ -134,3 +134,7 @@ Conflicts could lead to UI warning messages in Sentry, as it can be interpreted - [Crates.io page](https://crates.io/crates/sentry) - [Bug Tracker](https://github.com/getsentry/sentry-rust/issues) - [GitHub Project](https://github.com/getsentry/sentry-rust) + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/unity/index.mdx b/docs/platforms/unity/index.mdx index fdf7385f89f0a..a57321c352cda 100644 --- a/docs/platforms/unity/index.mdx +++ b/docs/platforms/unity/index.mdx @@ -102,3 +102,7 @@ Learn more about manually capturing an error or message in our [Usage documentat To view and resolve the recorded error, log into [sentry.io](https://sentry.io) and select your project. Clicking on the error's title will open a page where you can see detailed information and mark it as resolved. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/unreal/index.mdx b/docs/platforms/unreal/index.mdx index 31a2c13181a99..37a1f53e9a1c2 100644 --- a/docs/platforms/unreal/index.mdx +++ b/docs/platforms/unreal/index.mdx @@ -121,3 +121,7 @@ To view and resolve the recorded error, log into [sentry.io](https://sentry.io) ☝ This feature is supported on Windows, Linux, and Android. + +## Next Steps + +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup diff --git a/docs/platforms/xbox/index.mdx b/docs/platforms/xbox/index.mdx index f7216782be22c..26c6298ea2034 100644 --- a/docs/platforms/xbox/index.mdx +++ b/docs/platforms/xbox/index.mdx @@ -19,3 +19,4 @@ Access to Sentry's error and crash reporting for consoles is a paid feature. We ---- "Microsoft", "Xbox" are trademarks of the Microsoft group of companies. + diff --git a/includes/apple-platform-getting-started.mdx b/includes/apple-platform-getting-started.mdx index a8a9d5741ab8f..b326cccd289ab 100644 --- a/includes/apple-platform-getting-started.mdx +++ b/includes/apple-platform-getting-started.mdx @@ -422,6 +422,7 @@ if (error) { ## Next Steps +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn more about Sentry's Apple SDK features - Add readable stack traces to errors - Add Apple Privacy manifest diff --git a/platform-includes/getting-started-complete/javascript.astro.mdx b/platform-includes/getting-started-complete/javascript.astro.mdx index dc08647b6af71..fa796a4a2d7ca 100644 --- a/platform-includes/getting-started-complete/javascript.astro.mdx +++ b/platform-includes/getting-started-complete/javascript.astro.mdx @@ -403,6 +403,7 @@ Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Continue to customize your configuration - Learn how to manually capture errors - Learn more about [deploying Astro apps to Cloudflare Pages](/platforms/javascript/guides/cloudflare/frameworks/astro/) @@ -412,6 +413,7 @@ Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Continue to customize your configuration - Learn how to manually capture errors - Get familiar with [Sentry's product features](/product/) like tracing, insights, and alerts diff --git a/platform-includes/getting-started-complete/javascript.mdx b/platform-includes/getting-started-complete/javascript.mdx index 9cb7b43c75f81..8c73f92de2407 100644 --- a/platform-includes/getting-started-complete/javascript.mdx +++ b/platform-includes/getting-started-complete/javascript.mdx @@ -48,6 +48,7 @@ At this point, you should have integrated Sentry into your JavaScript applicatio Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Extend Sentry to your backend using one of our [SDKs](/) - Learn how to [manually capture errors](/platforms/javascript/usage/) - Continue to [customize your configuration](/platforms/javascript/configuration/) diff --git a/platform-includes/getting-started-complete/javascript.nuxt.mdx b/platform-includes/getting-started-complete/javascript.nuxt.mdx index fc065d8a9d4a9..01be5fe060b2e 100644 --- a/platform-includes/getting-started-complete/javascript.nuxt.mdx +++ b/platform-includes/getting-started-complete/javascript.nuxt.mdx @@ -369,6 +369,7 @@ At this point, you should have integrated Sentry into your Nuxt application and Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn how to [manually capture errors](/platforms/javascript/guides/nuxt/usage/) - Continue to [customize your configuration](/platforms/javascript/guides/nuxt/configuration/) - Get familiar with [Sentry's product features](/product) like tracing, insights, and alerts @@ -387,6 +388,7 @@ Now's a good time to customize your setup and look into more advanced topics. Ou +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn how to [manually capture errors](/platforms/javascript/guides/nuxt/usage/) - Continue to [customize your configuration](/platforms/javascript/guides/nuxt/configuration/) - Get familiar with [Sentry's product features](/product) like tracing, insights, and alerts diff --git a/platform-includes/getting-started-complete/javascript.remix.mdx b/platform-includes/getting-started-complete/javascript.remix.mdx index 3a54ead3a7851..8ddeca706bce3 100644 --- a/platform-includes/getting-started-complete/javascript.remix.mdx +++ b/platform-includes/getting-started-complete/javascript.remix.mdx @@ -460,6 +460,7 @@ At this point, you should have integrated Sentry into your Remix application and Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn how to manually capture errors - Continue to customize your configuration - Get familiar with [Sentry's product features](/product/) like tracing, insights, and alerts diff --git a/platform-includes/getting-started-complete/javascript.sveltekit.mdx b/platform-includes/getting-started-complete/javascript.sveltekit.mdx index 7e2fcf8e662f8..38e87bbe37813 100644 --- a/platform-includes/getting-started-complete/javascript.sveltekit.mdx +++ b/platform-includes/getting-started-complete/javascript.sveltekit.mdx @@ -461,6 +461,7 @@ Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn how to [manually capture errors](/platforms/javascript/guides/sveltekit/usage/) - Continue to [customize your configuration](/platforms/javascript/guides/sveltekit/configuration/) - Learn how to [manually instrument](/platforms/javascript/guides/sveltekit/apis#load-function-instrumentation) SvelteKit-specific features @@ -478,6 +479,7 @@ Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Learn how to [manually capture errors](/platforms/javascript/guides/cloudflare/usage/) - Continue to [customize your configuration](/platforms/javascript/guides/cloudflare/configuration/) - Get familiar with [Sentry's product features](/product) like tracing, insights, and alerts diff --git a/platform-includes/getting-started-node/javascript.mdx b/platform-includes/getting-started-node/javascript.mdx index 7a73dc5eb6f6a..82065334b18c0 100644 --- a/platform-includes/getting-started-node/javascript.mdx +++ b/platform-includes/getting-started-node/javascript.mdx @@ -83,6 +83,7 @@ At this point, you should have integrated Sentry into your application, which sh Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are: +- Explore [practical guides](/guides/) on what to monitor, log, track, and investigate after setup - Extend Sentry to your frontend using one of our [frontend SDKs](/) - Learn how to manually capture errors - Continue to customize your configuration From e8918649a55f486fa53dc7dfee99a12900e002ac Mon Sep 17 00:00:00 2001 From: paulj Date: Wed, 18 Feb 2026 14:02:03 -0500 Subject: [PATCH 13/21] docs(guides): Add Python and PHP examples to practical guides Add multi-language code examples using tabbed content for: - custom-spans - issues-errors - logs - metrics - querying-traces - session-replay Co-Authored-By: Claude --- docs/guides/custom-spans.mdx | 246 ++++++++++++++++++++++--- docs/guides/issues-errors.mdx | 171 +++++++++++++++--- docs/guides/logs.mdx | 308 ++++++++++++++++++++++++++++---- docs/guides/metrics.mdx | 225 +++++++++++++++++++---- docs/guides/querying-traces.mdx | 14 +- docs/guides/session-replay.mdx | 22 +-- 6 files changed, 845 insertions(+), 141 deletions(-) diff --git a/docs/guides/custom-spans.mdx b/docs/guides/custom-spans.mdx index edfa9af4899bf..e569066ee0282 100644 --- a/docs/guides/custom-spans.mdx +++ b/docs/guides/custom-spans.mdx @@ -4,20 +4,36 @@ sidebar_order: 30 description: "Add custom instrumentation for visibility beyond auto-instrumentation and set up alerts." --- -You've got your Sentry SDK [auto-instrumentation](/product/explore/trace-explorer/) running. Now what? +You've got your Sentry SDK [auto-instrumentation](/product/explore/trace-explorer/) running. Now what? Auto-instrumentation captures HTTP, database, and framework operations. But it can't see business logic, third-party APIs without auto-instrumentation, or background jobs. This guide shows you where to add custom spans to fill in those gaps. ## The Pattern -```javascript -Sentry.startSpan( - { name: "operation-name", op: "category" }, - async (span) => { - span.setAttribute("key", value); +```javascript {tabTitle: JavaScript} +Sentry.startSpan({ name: "operation-name", op: "category" }, async (span) => { + span.setAttribute("key", value); + // ... your code ... +}); +``` + +```python {tabTitle: Python} +import sentry_sdk + +with sentry_sdk.start_span(name="operation-name", op="category") as span: + span.set_data("key", value) + # ... your code ... +``` + +```php {tabTitle: PHP} +$spanContext = \Sentry\Tracing\SpanContext::make() + ->setOp('category') + ->setDescription('operation-name') + ->setData(['key' => $value]); + +\Sentry\trace(function () { // ... your code ... - } -); +}, $spanContext); ``` Numeric attributes become metrics you can aggregate with `sum()`, `avg()`, `p90()` in Trace Explorer. @@ -30,18 +46,43 @@ Start with these five areas and you'll have visibility into the operations that Track the full journey through critical paths. When checkout is slow, you need to know which step is responsible. -```javascript -Sentry.startSpan( - { name: "checkout-flow", op: "user.action" }, - async (span) => { - span.setAttribute("cart.itemCount", 3); - span.setAttribute("user.tier", "premium"); +```javascript {tabTitle: JavaScript} +Sentry.startSpan({ name: "checkout-flow", op: "user.action" }, async (span) => { + span.setAttribute("cart.itemCount", 3); + span.setAttribute("user.tier", "premium"); - await validateCart(); - await processPayment(); - await createOrder(); - } -); + await validateCart(); + await processPayment(); + await createOrder(); +}); +``` + +```python {tabTitle: Python} +import sentry_sdk + +with sentry_sdk.start_span(name="checkout-flow", op="user.action") as span: + span.set_data("cart.itemCount", 3) + span.set_data("user.tier", "premium") + + validate_cart() + process_payment() + create_order() +``` + +```php {tabTitle: PHP} +$spanContext = \Sentry\Tracing\SpanContext::make() + ->setOp('user.action') + ->setDescription('checkout-flow') + ->setData([ + 'cart.itemCount' => 3, + 'user.tier' => 'premium', + ]); + +\Sentry\trace(function () { + $this->validateCart(); + $this->processPayment(); + $this->createOrder(); +}, $spanContext); ``` **Query in Explore > Traces:** `span.op:user.action` grouped by `user.tier`, visualize `p90(span.duration)`. @@ -52,7 +93,7 @@ Sentry.startSpan( Measure dependencies you don't control. They're often the source of slowdowns. -```javascript +```javascript {tabTitle: JavaScript} Sentry.startSpan( { name: "shipping-rates-api", op: "http.client" }, async (span) => { @@ -70,6 +111,44 @@ Sentry.startSpan( ); ``` +```python {tabTitle: Python} +import time +import sentry_sdk + +with sentry_sdk.start_span(name="shipping-rates-api", op="http.client") as span: + span.set_data("http.url", "api.shipper.com/rates") + span.set_data("request.itemCount", len(items)) + + start = time.time() + response = requests.get("https://api.shipper.com/rates") + + span.set_data("http.status_code", response.status_code) + span.set_data("response.timeMs", int((time.time() - start) * 1000)) +``` + +```php {tabTitle: PHP} +$spanContext = \Sentry\Tracing\SpanContext::make() + ->setOp('http.client') + ->setDescription('shipping-rates-api') + ->setData([ + 'http.url' => 'api.shipper.com/rates', + 'request.itemCount' => count($items), + ]); + +\Sentry\trace(function () use ($spanContext) { + $start = microtime(true); + $response = $this->httpClient->get('https://api.shipper.com/rates'); + + $span = \Sentry\SentrySdk::getCurrentHub()->getSpan(); + $span->setData([ + 'http.status_code' => $response->getStatusCode(), + 'response.timeMs' => (int)((microtime(true) - $start) * 1000), + ]); + + return $response; +}, $spanContext); +``` + **Query in Explore > Traces:** `span.op:http.client response.timeMs:>2000` to find slow external calls. **Alert idea:** `p95(span.duration) > 3s` where `http.url` contains your critical dependencies. @@ -78,7 +157,7 @@ Sentry.startSpan( Auto-instrumentation catches queries, but custom spans let you add context that explains why a query matters. -```javascript +```javascript {tabTitle: JavaScript} Sentry.startSpan( { name: "load-user-dashboard", op: "db.query" }, async (span) => { @@ -94,9 +173,42 @@ Sentry.startSpan( ); ``` +```python {tabTitle: Python} +import sentry_sdk + +with sentry_sdk.start_span(name="load-user-dashboard", op="db.query") as span: + span.set_data("db.system", "postgres") + span.set_data("query.type", "aggregation") + span.set_data("query.dateRange", "30d") + + results = db.execute(dashboard_query).fetchall() + span.set_data("result.rowCount", len(results)) +``` + +```php {tabTitle: PHP} +$spanContext = \Sentry\Tracing\SpanContext::make() + ->setOp('db.query') + ->setDescription('load-user-dashboard') + ->setData([ + 'db.system' => 'postgres', + 'query.type' => 'aggregation', + 'query.dateRange' => '30d', + ]); + +$results = \Sentry\trace(function () use ($dashboardQuery) { + $results = $this->db->query($dashboardQuery)->fetchAll(); + + $span = \Sentry\SentrySdk::getCurrentHub()->getSpan(); + $span->setData(['result.rowCount' => count($results)]); + + return $results; +}, $spanContext); +``` + **Why this matters:** Without these attributes, you see "a database query took 2 seconds." With them, you know it was aggregating 30 days of data and returned 50,000 rows. That's actionable. **Query ideas in Explore > Traces:** + - "Which aggregation queries are slowest?" Group by `query.type`, sort by `p90(span.duration)` - "Does date range affect performance?" Filter by name, group by `query.dateRange` @@ -104,7 +216,7 @@ Sentry.startSpan( Jobs run outside of request context. Custom spans make them visible. -```javascript +```javascript {tabTitle: JavaScript} async function processEmailDigest(job) { return Sentry.startSpan( { name: `job:${job.type}`, op: "queue.process" }, @@ -126,6 +238,51 @@ async function processEmailDigest(job) { } ``` +```python {tabTitle: Python} +import sentry_sdk + +def process_email_digest(job): + with sentry_sdk.start_span(name=f"job:{job.type}", op="queue.process") as span: + span.set_data("job.id", job.id) + span.set_data("job.type", "email-digest") + span.set_data("queue.name", "notifications") + + users = get_digest_recipients() + span.set_data("job.recipientCount", len(users)) + + for user in users: + send_digest(user) + + span.set_data("job.status", "completed") +``` + +```php {tabTitle: PHP} +public function processEmailDigest($job) +{ + $spanContext = \Sentry\Tracing\SpanContext::make() + ->setOp('queue.process') + ->setDescription("job:{$job->type}") + ->setData([ + 'job.id' => $job->id, + 'job.type' => 'email-digest', + 'queue.name' => 'notifications', + ]); + + \Sentry\trace(function () use ($job) { + $users = $this->getDigestRecipients(); + + $span = \Sentry\SentrySdk::getCurrentHub()->getSpan(); + $span->setData(['job.recipientCount' => count($users)]); + + foreach ($users as $user) { + $this->sendDigest($user); + } + + $span->setData(['job.status' => 'completed']); + }, $spanContext); +} +``` + **Query in Explore > Traces:** `span.op:queue.process` grouped by `job.type`, visualize `p90(span.duration)`. **Alert idea:** `p90(span.duration) > 60s` for queue processing. @@ -136,7 +293,7 @@ For AI workloads, use [Sentry Agent Monitoring](/product/insights/ai/agents/) in If you're not using a supported framework or need custom attributes: -```javascript +```javascript {tabTitle: JavaScript} Sentry.startSpan( { name: "generate-summary", op: "ai.inference" }, async (span) => { @@ -151,14 +308,45 @@ Sentry.startSpan( ); ``` +```python {tabTitle: Python} +import sentry_sdk + +with sentry_sdk.start_span(name="generate-summary", op="ai.inference") as span: + span.set_data("ai.model", "gpt-4") + span.set_data("ai.feature", "document-summary") + + response = openai.chat.completions.create(...) + + span.set_data("ai.tokens.total", response.usage.total_tokens) +``` + +```php {tabTitle: PHP} +$spanContext = \Sentry\Tracing\SpanContext::make() + ->setOp('ai.inference') + ->setDescription('generate-summary') + ->setData([ + 'ai.model' => 'gpt-4', + 'ai.feature' => 'document-summary', + ]); + +$response = \Sentry\trace(function () { + $response = $this->openai->chat()->completions()->create([...]); + + $span = \Sentry\SentrySdk::getCurrentHub()->getSpan(); + $span->setData(['ai.tokens.total' => $response->usage->totalTokens]); + + return $response; +}, $spanContext); +``` + **Alert idea:** `p95(span.duration) > 5s` for AI inference. ## Quick Reference -| Category | `op` Value | Example Attributes | -|----------|-----------|----------------| -| User flows | `user.action` | cart.itemCount, user.tier | -| External APIs | `http.client` | http.url, response.timeMs | -| Database | `db.query` | query.type, result.rowCount | +| Category | `op` Value | Example Attributes | +| --------------- | --------------- | ---------------------------- | +| User flows | `user.action` | cart.itemCount, user.tier | +| External APIs | `http.client` | http.url, response.timeMs | +| Database | `db.query` | query.type, result.rowCount | | Background jobs | `queue.process` | job.type, job.id, queue.name | -| AI/LLM | `ai.inference` | ai.model, ai.tokens.total | +| AI/LLM | `ai.inference` | ai.model, ai.tokens.total | diff --git a/docs/guides/issues-errors.mdx b/docs/guides/issues-errors.mdx index 5896cda5c05de..b59a0fe71b74d 100644 --- a/docs/guides/issues-errors.mdx +++ b/docs/guides/issues-errors.mdx @@ -8,23 +8,48 @@ Your Sentry SDK is sending errors to [Sentry Issues](/product/issues/) out of th ## The Pattern -Sentry automatically captures unhandled errors. For handled errors, use `Sentry.captureException()` and add context: +Sentry automatically captures unhandled errors. For handled errors, use `captureException()` and add context: -```javascript +```javascript {tabTitle: JavaScript} try { await processOrder(order); } catch (error) { Sentry.captureException(error, { tags: { order_id: order.id, - payment_method: order.paymentMethod + payment_method: order.paymentMethod, }, - level: "error" + level: "error", }); throw error; } ``` +```python {tabTitle: Python} +import sentry_sdk + +try: + process_order(order) +except Exception as e: + sentry_sdk.capture_exception(e) + sentry_sdk.set_tag("order_id", order.id) + sentry_sdk.set_tag("payment_method", order.payment_method) + raise +``` + +```php {tabTitle: PHP} +try { + $this->processOrder($order); +} catch (\Throwable $exception) { + \Sentry\configureScope(function (\Sentry\State\Scope $scope) use ($order): void { + $scope->setTag('order_id', $order->id); + $scope->setTag('payment_method', $order->paymentMethod); + }); + \Sentry\captureException($exception); + throw $exception; +} +``` + **Levels:** `fatal`, `error`, `warning`, `info`, `debug` **Context:** Tags, user info, logs, and session replays help you debug faster. Tags are searchable, so use them for high-cardinality data like IDs, regions, and feature flags. @@ -41,9 +66,10 @@ Start by creating these five [Issue views](https://sentry.io/orgredirect/organiz High event counts mean either many users are affected or one user is stuck in a loop. Both need immediate attention. -**[In Issues](https://sentry.io/orgredirect/organizations/:orgslug/issues/):** Search for `is:unresolved` (applied by default) and use the sort dropdown (defaults to "Last Seen") to sort by **Events** +**[In Issues](https://sentry.io/orgredirect/organizations/:orgslug/issues/):** Search for `is:unresolved` (applied by default) and use the sort dropdown (defaults to "Last Seen") to sort by **Events** **What to look for:** + - Issues at the top with high event counts (many occurrences in a short time) - Click into these issues to see the stack trace and how many users are affected @@ -58,6 +84,7 @@ Every deploy introduces risk. New errors that appear right after a release are u **[In Issues](https://sentry.io/orgredirect/organizations/:orgslug/issues/):** Filter by `is:unresolved firstRelease:v1.2.3` to find issues introduced in a specific release. Sort by **Age** to see the newest issues first. **What to look for:** + - Issues that didn't exist in the previous release - Errors in code paths you just changed - New error types (TypeError, ReferenceError) indicating breaking changes @@ -73,6 +100,7 @@ Production errors are critical. Staging errors help you catch problems before th **[In Issues](https://sentry.io/orgredirect/organizations/:orgslug/issues/):** Search for `is:unresolved environment:production` or `environment:staging` **What to look for:** + - Errors only in production (often config, API keys, or data issues) - Errors only in staging (caught before deploy, needs fixing) - Same error in both (systemic code issue) @@ -88,6 +116,7 @@ Some errors heavily affect power users. Others affect everyone, but rarely. Prio **[In Issues](https://sentry.io/orgredirect/organizations/:orgslug/issues/):** Search for `is:unresolved` and use the sort dropdown to sort by **Users** **What to look for:** + - Issues affecting many unique users (e.g., more than 10 users indicates widespread impact) - Issues affecting VIP or paying users (check user tags) - Issues blocking core workflows (login, checkout, data access) @@ -105,6 +134,7 @@ Enable the [User Feedback Widget](/platforms/javascript/user-feedback/) to let u **[In Issues](https://sentry.io/orgredirect/organizations/:orgslug/issues/):** Navigate to **User Feedback** in the left sidebar to see reports submitted by users. **What to look for:** + - User descriptions of what they were doing when the error occurred - Patterns in feedback about specific workflows or features - Issues that frustrate users even if they don't generate many events @@ -115,9 +145,9 @@ Enable the [User Feedback Widget](/platforms/javascript/user-feedback/) to let u ### Capture Context, Not Just Exceptions -When you catch an error, add tags and context to make debugging instant. Set user info globally with `Sentry.setUser()` so it applies to all events. Enable [Session Replays](/product/explore/session-replay/) and [Logs](/product/explore/logs/) for even more visibility. +When you catch an error, add tags and context to make debugging instant. Set user info globally so it applies to all events. Enable [Session Replays](/product/explore/session-replay/) and [Logs](/product/explore/logs/) for even more visibility. -```javascript +```javascript {tabTitle: JavaScript} // Set user globally (e.g., after login) Sentry.setUser({ id: user.id, email: user.email }); @@ -126,55 +156,148 @@ Sentry.captureException(error, { tags: { order_id: order.id, payment_gateway: "stripe", - region: user.region + region: user.region, }, contexts: { order: { total: order.total, items: order.items.length, - discount_code: order.discountCode - } - } + discount_code: order.discountCode, + }, + }, }); ``` +```python {tabTitle: Python} +import sentry_sdk + +# Set user globally (e.g., after login) +sentry_sdk.set_user({"id": user.id, "email": user.email}) + +# Add tags and context per-event +sentry_sdk.set_tags({ + "order_id": order.id, + "payment_gateway": "stripe", + "region": user.region +}) +sentry_sdk.set_context("order", { + "total": order.total, + "items": len(order.items), + "discount_code": order.discount_code +}) +sentry_sdk.capture_exception(error) +``` + +```php {tabTitle: PHP} +// Set user globally (e.g., after login) +\Sentry\configureScope(function (\Sentry\State\Scope $scope) use ($user): void { + $scope->setUser(['id' => $user->id, 'email' => $user->email]); +}); + +// Add tags and context per-event +\Sentry\configureScope(function (\Sentry\State\Scope $scope) use ($order, $user): void { + $scope->setTag('order_id', $order->id); + $scope->setTag('payment_gateway', 'stripe'); + $scope->setTag('region', $user->region); + $scope->setContext('order', [ + 'total' => $order->total, + 'items' => count($order->items), + 'discount_code' => $order->discountCode + ]); +}); +\Sentry\captureException($error); +``` + **Search in Sentry:** `order_id:order_123` or `payment_gateway:stripe region:us-west` ### Ignore Known Noise Some errors aren't actionable. Use ignoreErrors to filter them out. -```javascript +```javascript {tabTitle: JavaScript} Sentry.init({ dsn: "...", ignoreErrors: [ "Non-Error promise rejection captured", - /^Timeout of \d+ms exceeded$/ - ] + /^Timeout of \d+ms exceeded$/, + ], }); ``` +```python {tabTitle: Python} +import sentry_sdk + +sentry_sdk.init( + dsn="...", + ignore_errors=[ + ValueError, + ConnectionError, + ] +) +``` + +```php {tabTitle: PHP} +\Sentry\init([ + 'dsn' => '...', + 'ignore_exceptions' => [ + \RuntimeException::class, + ], +]); +``` + You can also use beforeSend to filter errors dynamically: -```javascript +```javascript {tabTitle: JavaScript} Sentry.init({ beforeSend(event, hint) { // Ignore errors from browser extensions - if (event.exception?.values?.[0]?.stacktrace?.frames?.some( - frame => frame.filename?.includes("chrome-extension://") - )) { + if ( + event.exception?.values?.[0]?.stacktrace?.frames?.some((frame) => + frame.filename?.includes("chrome-extension://") + ) + ) { return null; } return event; - } + }, }); ``` +```python {tabTitle: Python} +import sentry_sdk + +def before_send(event, hint): + # Ignore specific error types + if "exc_info" in hint: + exc_type, exc_value, tb = hint["exc_info"] + if isinstance(exc_value, KeyboardInterrupt): + return None + return event + +sentry_sdk.init( + dsn="...", + before_send=before_send +) +``` + +```php {tabTitle: PHP} +\Sentry\init([ + 'dsn' => '...', + 'before_send' => function (\Sentry\Event $event, ?\Sentry\EventHint $hint): ?\Sentry\Event { + // Ignore specific error types + if ($hint !== null && $hint->exception instanceof \RuntimeException) { + return null; + } + return $event; + }, +]); +``` + ## Quick Reference -| View | Search Query | Look For | -|------|--------------|----------| +| View | Search Query | Look For | +| ------------------ | -------------------------------- | ------------------------------------- | | High-volume issues | `is:unresolved` (sort by Events) | High event counts, post-deploy spikes | -| New regressions | `is:unresolved` (sort by Age) | Issues that first appeared recently | -| Environment issues | `environment:production` | Prod-only config or data issues | -| High user impact | `is:unresolved` (sort by Users) | Issues affecting many users | +| New regressions | `is:unresolved` (sort by Age) | Issues that first appeared recently | +| Environment issues | `environment:production` | Prod-only config or data issues | +| High user impact | `is:unresolved` (sort by Users) | Issues affecting many users | diff --git a/docs/guides/logs.mdx b/docs/guides/logs.mdx index b5184d0bbd568..661b3715b93dd 100644 --- a/docs/guides/logs.mdx +++ b/docs/guides/logs.mdx @@ -10,23 +10,52 @@ You've set up [Sentry Logs](/product/explore/logs/). Now what? This guide covers Every structured log follows the same format: -```javascript +```javascript {tabTitle: JavaScript} Sentry.logger.(message, { attributes }); ``` -**Levels:** `trace`, `debug`, `info`, `warn`, `error`, `fatal` +```python {tabTitle: Python} +from sentry_sdk import logger +logger.(message, attribute=value) +``` + +```php {tabTitle: PHP} +\Sentry\logger()->(message, attributes: [...]); +``` + +**Levels:** `trace`, `debug`, `info`, `warn` (or `warning` in Python), `error`, `fatal` **Attributes:** Key-value pairs you can search and filter on. Consistency matters, so use whatever naming convention fits your codebase. -```javascript +```javascript {tabTitle: JavaScript} Sentry.logger.info("Order completed", { orderId: "order_123", userId: user.id, amount: 149.99, - paymentMethod: "stripe" + paymentMethod: "stripe", }); ``` +```python {tabTitle: Python} +from sentry_sdk import logger as sentry_logger + +sentry_logger.info("Order completed", + order_id="order_123", + user_id=user.id, + amount=149.99, + payment_method="stripe" +) +``` + +```php {tabTitle: PHP} +\Sentry\logger()->info('Order completed', attributes: [ + 'order_id' => 'order_123', + 'user_id' => $user->id, + 'amount' => 149.99, + 'payment_method' => 'stripe', +]); +``` + Logs in Sentry are automatically trace-connected. Each log shows a trace ID that links to the full [trace view](/concepts/key-terms/tracing/trace-view/). ## Where to Add Logs @@ -37,20 +66,50 @@ Start with these five areas and you'll catch most issues before users do. Login flows are invisible until something breaks. Log successes and failures to spot patterns like brute force attempts, OAuth misconfigurations, or MFA issues. -```javascript +```javascript {tabTitle: JavaScript} Sentry.logger.info("User logged in", { userId: user.id, authMethod: "oauth", - provider: "google" + provider: "google", }); Sentry.logger.warn("Login failed", { email: maskedEmail, reason: "invalid_password", - attemptCount: 3 + attemptCount: 3, }); ``` +```python {tabTitle: Python} +from sentry_sdk import logger as sentry_logger + +sentry_logger.info("User logged in", + user_id=user.id, + auth_method="oauth", + provider="google" +) + +sentry_logger.warning("Login failed", + email=masked_email, + reason="invalid_password", + attempt_count=3 +) +``` + +```php {tabTitle: PHP} +\Sentry\logger()->info('User logged in', attributes: [ + 'user_id' => $user->id, + 'auth_method' => 'oauth', + 'provider' => 'google', +]); + +\Sentry\logger()->warn('Login failed', attributes: [ + 'email' => $maskedEmail, + 'reason' => 'invalid_password', + 'attempt_count' => 3, +]); +``` + **Search in Sentry:** `userId:123 "logged in"` or `severity:warn authMethod:*` **Alert idea:** Alert when `severity:warn "Login failed"` spikes in a 5-minute window—this can indicate brute force attempts or auth provider issues. @@ -59,16 +118,38 @@ Sentry.logger.warn("Login failed", { Money paths need visibility even when they succeed. When payments fail, you need context fast. -```javascript +```javascript {tabTitle: JavaScript} Sentry.logger.error("Payment failed", { orderId: "order_123", amount: 99.99, gateway: "stripe", errorCode: "card_declined", - cartItems: 3 + cartItems: 3, }); ``` +```python {tabTitle: Python} +from sentry_sdk import logger as sentry_logger + +sentry_logger.error("Payment failed", + order_id="order_123", + amount=99.99, + gateway="stripe", + error_code="card_declined", + cart_items=3 +) +``` + +```php {tabTitle: PHP} +\Sentry\logger()->error('Payment failed', attributes: [ + 'order_id' => 'order_123', + 'amount' => 99.99, + 'gateway' => 'stripe', + 'error_code' => 'card_declined', + 'cart_items' => 3, +]); +``` + **Search in Sentry:** `orderId:order_123` or `severity:error gateway:stripe` **Alert idea:** Alert when `severity:error gateway:*` spikes—this can indicate payment provider outages. @@ -77,7 +158,7 @@ Sentry.logger.error("Payment failed", { Traces capture what your code does. Logs capture context about external triggers and async boundaries. Things like webhooks, scheduled tasks, and third-party API responses that traces can't automatically instrument. -```javascript +```javascript {tabTitle: JavaScript} // Third-party API call const start = Date.now(); const response = await shippingApi.getRates(items); @@ -86,17 +167,60 @@ Sentry.logger.info("Shipping rates fetched", { service: "shipping-provider", endpoint: "/rates", durationMs: Date.now() - start, - rateCount: response.rates.length + rateCount: response.rates.length, }); // Webhook received Sentry.logger.info("Webhook received", { source: "stripe", eventType: "payment_intent.succeeded", - paymentId: event.data.object.id + paymentId: event.data.object.id, }); ``` +```python {tabTitle: Python} +import time +from sentry_sdk import logger as sentry_logger + +# Third-party API call +start = time.time() +response = shipping_api.get_rates(items) + +sentry_logger.info("Shipping rates fetched", + service="shipping-provider", + endpoint="/rates", + duration_ms=int((time.time() - start) * 1000), + rate_count=len(response.rates) +) + +# Webhook received +sentry_logger.info("Webhook received", + source="stripe", + event_type="payment_intent.succeeded", + payment_id=event["data"]["object"]["id"] +) +``` + +```php {tabTitle: PHP} +// Third-party API call +$start = microtime(true); +$response = $shippingApi->getRates($items); + +\Sentry\logger()->info('Shipping rates fetched', attributes: [ + 'service' => 'shipping-provider', + 'endpoint' => '/rates', + 'duration_ms' => (int)((microtime(true) - $start) * 1000), + 'rate_count' => count($response->rates), +]); + +// Webhook received +\Sentry\logger()->info('Webhook received', attributes: [ + 'source' => 'stripe', + 'event_type' => 'payment_intent.succeeded', + 'payment_id' => $event['data']['object']['id'], +]); +``` + **Search in Sentry:** `service:shipping-provider durationMs:>2000` or `source:stripe` **Alert idea:** Alert when `service:* durationMs:>3000` to catch third-party slowdowns before they cascade. @@ -105,21 +229,53 @@ Sentry.logger.info("Webhook received", { Jobs run outside the request context. Without logs, failed jobs are invisible until someone notices missing data. -```javascript +```javascript {tabTitle: JavaScript} Sentry.logger.info("Job started", { jobType: "email-digest", jobId: "job_456", - queue: "notifications" + queue: "notifications", }); Sentry.logger.error("Job failed", { jobType: "email-digest", jobId: "job_456", retryCount: 3, - lastError: "SMTP timeout" + lastError: "SMTP timeout", }); ``` +```python {tabTitle: Python} +from sentry_sdk import logger as sentry_logger + +sentry_logger.info("Job started", + job_type="email-digest", + job_id="job_456", + queue="notifications" +) + +sentry_logger.error("Job failed", + job_type="email-digest", + job_id="job_456", + retry_count=3, + last_error="SMTP timeout" +) +``` + +```php {tabTitle: PHP} +\Sentry\logger()->info('Job started', attributes: [ + 'job_type' => 'email-digest', + 'job_id' => 'job_456', + 'queue' => 'notifications', +]); + +\Sentry\logger()->error('Job failed', attributes: [ + 'job_type' => 'email-digest', + 'job_id' => 'job_456', + 'retry_count' => 3, + 'last_error' => 'SMTP timeout', +]); +``` + **Search in Sentry:** `jobType:email-digest severity:error` **Alert idea:** Alert when `severity:error jobType:*` spikes—this can indicate queue processing issues or downstream failures. @@ -128,19 +284,47 @@ Sentry.logger.error("Job failed", { When something breaks after a deploy, the first question is "what changed?" Logging flag evaluations and config reloads gives you that answer instantly. -```javascript +```javascript {tabTitle: JavaScript} Sentry.logger.info("Feature flag evaluated", { flag: "new-checkout-flow", enabled: true, - userId: user.id + userId: user.id, }); Sentry.logger.warn("Config reloaded", { reason: "env-change", - changedKeys: ["API_TIMEOUT", "MAX_CONNECTIONS"] + changedKeys: ["API_TIMEOUT", "MAX_CONNECTIONS"], }); ``` +```python {tabTitle: Python} +from sentry_sdk import logger as sentry_logger + +sentry_logger.info("Feature flag evaluated", + flag="new-checkout-flow", + enabled=True, + user_id=user.id +) + +sentry_logger.warning("Config reloaded", + reason="env-change", + changed_keys=["API_TIMEOUT", "MAX_CONNECTIONS"] +) +``` + +```php {tabTitle: PHP} +\Sentry\logger()->info('Feature flag evaluated', attributes: [ + 'flag' => 'new-checkout-flow', + 'enabled' => true, + 'user_id' => $user->id, +]); + +\Sentry\logger()->warn('Config reloaded', attributes: [ + 'reason' => 'env-change', + 'changed_keys' => ['API_TIMEOUT', 'MAX_CONNECTIONS'], +]); +``` + **Search in Sentry:** `flag:new-checkout-flow` or `"Config reloaded"` ## Creating Alerts From Logs @@ -166,20 +350,40 @@ In development, set sample rates to 100% to catch everything. This helps you und **Development configuration:** -```javascript +```javascript {tabTitle: JavaScript} Sentry.init({ dsn: "...", environment: "development", - tracesSampleRate: 1.0, // 100% of traces + tracesSampleRate: 1.0, // 100% of traces // Capture all logs in development integrations: [ Sentry.captureConsoleIntegration({ - levels: ["log", "info", "warn", "error", "debug"] - }) - ] + levels: ["log", "info", "warn", "error", "debug"], + }), + ], }); ``` +```python {tabTitle: Python} +import sentry_sdk + +sentry_sdk.init( + dsn="...", + environment="development", + traces_sample_rate=1.0, # 100% of traces + enable_logs=True, +) +``` + +```php {tabTitle: PHP} +\Sentry\init([ + 'dsn' => '...', + 'environment' => 'development', + 'traces_sample_rate' => 1.0, // 100% of traces + 'enable_logs' => true, +]); +``` + Use verbose logging levels like `debug` (development diagnostics) and `trace` (fine-grained execution details) freely in development. You can [filter these out in production](/platforms/javascript/logs/#filter-logs) using `beforeSendLog` to only capture `info` and above. ### Production Logging @@ -190,28 +394,64 @@ Instead, log fewer messages with higher cardinality. Store events during executi **Don't do this:** -```javascript +```javascript {tabTitle: JavaScript} Sentry.logger.info("Checkout started", { userId: "882" }); Sentry.logger.info("Discount applied", { code: "WINTER20" }); Sentry.logger.error("Payment failed", { reason: "Insufficient Funds" }); ``` +```python {tabTitle: Python} +sentry_logger.info("Checkout started", user_id="882") +sentry_logger.info("Discount applied", code="WINTER20") +sentry_logger.error("Payment failed", reason="Insufficient Funds") +``` + +```php {tabTitle: PHP} +\Sentry\logger()->info('Checkout started', attributes: ['user_id' => '882']); +\Sentry\logger()->info('Discount applied', attributes: ['code' => 'WINTER20']); +\Sentry\logger()->error('Payment failed', attributes: ['reason' => 'Insufficient Funds']); +``` + These logs are trace-connected, but searching for the error won't return the userId or discount code from the same transaction. **Do this instead:** -```javascript +```javascript {tabTitle: JavaScript} Sentry.logger.error("Checkout failed", { userId: "882", orderId: "order_pc_991", - cartTotal: 142.50, + cartTotal: 142.5, discountCode: "WINTER20", paymentMethod: "stripe", errorReason: "Insufficient Funds", - itemCount: 4 + itemCount: 4, }); ``` +```python {tabTitle: Python} +sentry_logger.error("Checkout failed", + user_id="882", + order_id="order_pc_991", + cart_total=142.50, + discount_code="WINTER20", + payment_method="stripe", + error_reason="Insufficient Funds", + item_count=4 +) +``` + +```php {tabTitle: PHP} +\Sentry\logger()->error('Checkout failed', attributes: [ + 'user_id' => '882', + 'order_id' => 'order_pc_991', + 'cart_total' => 142.50, + 'discount_code' => 'WINTER20', + 'payment_method' => 'stripe', + 'error_reason' => 'Insufficient Funds', + 'item_count' => 4, +]); +``` + One log tells the whole story. Search for the error and get full context. ### Log Drains for Platform Logs @@ -224,10 +464,10 @@ If you can't install the Sentry SDK or need platform-level logs (CDN, database, ## Quick Reference -| Category | Level | Example Attributes | -|----------|-------|----------------| -| Auth events | `info`/`warn` | userId, authMethod, reason | -| Payments | `info`/`error` | orderId, amount, gateway, errorCode | -| External APIs | `info` | service, endpoint, durationMs | -| Background jobs | `info`/`error` | jobType, jobId, retryCount | -| Feature flags | `info` | flag, enabled, changedKeys | +| Category | Level | Example Attributes | +| --------------- | -------------- | ----------------------------------- | +| Auth events | `info`/`warn` | userId, authMethod, reason | +| Payments | `info`/`error` | orderId, amount, gateway, errorCode | +| External APIs | `info` | service, endpoint, durationMs | +| Background jobs | `info`/`error` | jobType, jobId, retryCount | +| Feature flags | `info` | flag, enabled, changedKeys | diff --git a/docs/guides/metrics.mdx b/docs/guides/metrics.mdx index 07181ed6f3b70..797f1596083be 100644 --- a/docs/guides/metrics.mdx +++ b/docs/guides/metrics.mdx @@ -10,23 +10,39 @@ You've set up [Sentry Metrics](/product/explore/metrics/). Now what? This guide Sentry supports three metric types: -| Type | Method | Use For | -|------|--------|---------| -| **Counter** | `Sentry.metrics.count()` | Events that happen (orders, clicks, errors) | -| **Gauge** | `Sentry.metrics.gauge()` | Current state (queue depth, connections) | -| **Distribution** | `Sentry.metrics.distribution()` | Values that vary (latency, sizes, amounts) | +| Type | Method | Use For | +| ---------------- | ------------------------------- | ------------------------------------------- | +| **Counter** | `Sentry.metrics.count()` | Events that happen (orders, clicks, errors) | +| **Gauge** | `Sentry.metrics.gauge()` | Current state (queue depth, connections) | +| **Distribution** | `Sentry.metrics.distribution()` | Values that vary (latency, sizes, amounts) | Every metric is trace-connected. When a metric spikes, click into samples to see the exact trace that produced it. -```javascript +```javascript {tabTitle: JavaScript} Sentry.metrics.count("checkout.failed", 1, { attributes: { user_tier: "premium", - failure_reason: "payment_declined" - } + failure_reason: "payment_declined", + }, }); ``` +```python {tabTitle: Python} +import sentry_sdk + +sentry_sdk.metrics.count("checkout.failed", 1, attributes={ + "user_tier": "premium", + "failure_reason": "payment_declined" +}) +``` + +```php {tabTitle: PHP} +\Sentry\traceMetrics()->count('checkout.failed', 1, [ + 'user_tier' => 'premium', + 'failure_reason' => 'payment_declined', +]); +``` + ## Where to Track Metrics Start with these five metrics and you'll spot issues before they become problems. @@ -35,17 +51,40 @@ Start with these five metrics and you'll spot issues before they become problems Track discrete events that matter to the business. These become your KPIs. -```javascript +```javascript {tabTitle: JavaScript} Sentry.metrics.count("checkout.completed", 1, { - attributes: { user_tier: "premium", payment_method: "card" } + attributes: { user_tier: "premium", payment_method: "card" }, }); Sentry.metrics.count("checkout.failed", 1, { - attributes: { user_tier: "premium", failure_reason: "payment_declined" } + attributes: { user_tier: "premium", failure_reason: "payment_declined" }, }); ``` +```python {tabTitle: Python} +import sentry_sdk + +sentry_sdk.metrics.count("checkout.completed", 1, attributes={ + "user_tier": "premium", "payment_method": "card" +}) + +sentry_sdk.metrics.count("checkout.failed", 1, attributes={ + "user_tier": "premium", "failure_reason": "payment_declined" +}) +``` + +```php {tabTitle: PHP} +\Sentry\traceMetrics()->count('checkout.completed', 1, [ + 'user_tier' => 'premium', 'payment_method' => 'card' +]); + +\Sentry\traceMetrics()->count('checkout.failed', 1, [ + 'user_tier' => 'premium', 'failure_reason' => 'payment_declined' +]); +``` + **Explore in Sentry:** + 1. Go to **Explore > Metrics** 2. Select `checkout.failed`, set **Aggregate** to `sum` 3. **Group by** `failure_reason` @@ -55,75 +94,186 @@ Sentry.metrics.count("checkout.failed", 1, { Track success and failure of critical operations. -```javascript +```javascript {tabTitle: JavaScript} Sentry.metrics.count("email.sent", 1, { - attributes: { email_type: "welcome", provider: "sendgrid" } + attributes: { email_type: "welcome", provider: "sendgrid" }, }); Sentry.metrics.count("email.failed", 1, { - attributes: { email_type: "welcome", error: "rate_limited" } + attributes: { email_type: "welcome", error: "rate_limited" }, }); Sentry.metrics.count("job.processed", 1, { - attributes: { job_type: "invoice-generation", queue: "billing" } + attributes: { job_type: "invoice-generation", queue: "billing" }, }); ``` +```python {tabTitle: Python} +import sentry_sdk + +sentry_sdk.metrics.count("email.sent", 1, attributes={ + "email_type": "welcome", "provider": "sendgrid" +}) + +sentry_sdk.metrics.count("email.failed", 1, attributes={ + "email_type": "welcome", "error": "rate_limited" +}) + +sentry_sdk.metrics.count("job.processed", 1, attributes={ + "job_type": "invoice-generation", "queue": "billing" +}) +``` + +```php {tabTitle: PHP} +\Sentry\traceMetrics()->count('email.sent', 1, [ + 'email_type' => 'welcome', 'provider' => 'sendgrid' +]); + +\Sentry\traceMetrics()->count('email.failed', 1, [ + 'email_type' => 'welcome', 'error' => 'rate_limited' +]); + +\Sentry\traceMetrics()->count('job.processed', 1, [ + 'job_type' => 'invoice-generation', 'queue' => 'billing' +]); +``` + **Explore in Sentry:** Add both `email.sent` and `email.failed`, group by `email_type`, compare the ratio. ### 3. Resource Utilization Track the current state of pools, queues, and connections. Call these periodically (e.g., every 30 seconds). -```javascript +```javascript {tabTitle: JavaScript} Sentry.metrics.gauge("queue.depth", await queue.size(), { - attributes: { queue_name: "notifications" } + attributes: { queue_name: "notifications" }, }); Sentry.metrics.gauge("pool.connections_active", pool.activeConnections, { - attributes: { pool_name: "postgres-primary" } + attributes: { pool_name: "postgres-primary" }, }); ``` +```python {tabTitle: Python} +import sentry_sdk + +sentry_sdk.metrics.gauge("queue.depth", queue.size(), attributes={ + "queue_name": "notifications" +}) + +sentry_sdk.metrics.gauge("pool.connections_active", pool.active_connections, attributes={ + "pool_name": "postgres-primary" +}) +``` + +```php {tabTitle: PHP} +use \Sentry\Metrics\Unit; + +\Sentry\traceMetrics()->gauge('queue.depth', $queue->size(), [ + 'queue_name' => 'notifications' +]); + +\Sentry\traceMetrics()->gauge('pool.connections_active', $pool->activeConnections, [ + 'pool_name' => 'postgres-primary' +]); +``` + **Explore in Sentry:** View `max(queue.depth)` over time to spot backlogs. ### 4. Latency and Performance Track values that vary and need percentile analysis. **Tip:** averages can hide outliers, use p90/p95/p99 instead. -```javascript +```javascript {tabTitle: JavaScript} Sentry.metrics.distribution("api.latency", responseTimeMs, { unit: "millisecond", - attributes: { endpoint: "/api/orders", method: "POST" } + attributes: { endpoint: "/api/orders", method: "POST" }, }); Sentry.metrics.distribution("db.query_time", queryDurationMs, { unit: "millisecond", - attributes: { table: "orders", operation: "select" } + attributes: { table: "orders", operation: "select" }, }); ``` +```python {tabTitle: Python} +import sentry_sdk + +sentry_sdk.metrics.distribution("api.latency", response_time_ms, + unit="millisecond", + attributes={"endpoint": "/api/orders", "method": "POST"} +) + +sentry_sdk.metrics.distribution("db.query_time", query_duration_ms, + unit="millisecond", + attributes={"table": "orders", "operation": "select"} +) +``` + +```php {tabTitle: PHP} +use \Sentry\Metrics\Unit; + +\Sentry\traceMetrics()->distribution('api.latency', $responseTimeMs, + ['endpoint' => '/api/orders', 'method' => 'POST'], + Unit::millisecond() +); + +\Sentry\traceMetrics()->distribution('db.query_time', $queryDurationMs, + ['table' => 'orders', 'operation' => 'select'], + Unit::millisecond() +); +``` + **Explore in Sentry:** View `p95(api.latency)` grouped by `endpoint` to find slow routes. ### 5. Business Values Track amounts, sizes, and quantities for analysis. -```javascript +```javascript {tabTitle: JavaScript} Sentry.metrics.distribution("order.amount", order.totalUsd, { unit: "usd", - attributes: { user_tier: "premium", region: "us-west" } + attributes: { user_tier: "premium", region: "us-west" }, }); Sentry.metrics.distribution("upload.size", fileSizeBytes, { unit: "byte", - attributes: { file_type: "image", source: "profile-update" } + attributes: { file_type: "image", source: "profile-update" }, }); ``` +```python {tabTitle: Python} +import sentry_sdk + +sentry_sdk.metrics.distribution("order.amount", order.total_usd, + unit="usd", + attributes={"user_tier": "premium", "region": "us-west"} +) + +sentry_sdk.metrics.distribution("upload.size", file_size_bytes, + unit="byte", + attributes={"file_type": "image", "source": "profile-update"} +) +``` + +```php {tabTitle: PHP} +use \Sentry\Metrics\Unit; + +\Sentry\traceMetrics()->distribution('order.amount', $order->totalUsd, + ['user_tier' => 'premium', 'region' => 'us-west'], + Unit::custom('usd') +); + +\Sentry\traceMetrics()->distribution('upload.size', $fileSizeBytes, + ['file_type' => 'image', 'source' => 'profile-update'], + Unit::byte() +); +``` + **Explore in Sentry:** View `avg(order.amount)` grouped by `region` to compare regional performance. {/* + ## Creating Alerts From Metrics 1. Go to **Explore > Metrics** @@ -136,7 +286,7 @@ Sentry.metrics.distribution("upload.size", fileSizeBytes, { 5. Configure notification channels and save Learn about [creating alerts](/product/new-monitors-and-alerts/alerts/) and best practices for [reducing noise and routing notifications](/product/new-monitors-and-alerts/alerts/best-practices/). -*/} +\*/} ## Alerts and Dashboard Widgets @@ -145,6 +295,7 @@ Learn about [creating alerts](/product/new-monitors-and-alerts/alerts/) and best You'll soon be able to: + - Create alert rules based on metric queries - Add metric visualizations to dashboards - Set up notifications when metrics cross thresholds @@ -152,20 +303,20 @@ You'll soon be able to: ## Quick Reference -| Category | Type | Method | Example Attributes | -|----------|------|--------|----------------| -| Business events | Counter | `count()` | user_tier, payment_method, failure_reason | -| Application health | Counter | `count()` | email_type, provider, job_type, queue | -| Resource utilization | Gauge | `gauge()` | queue_name, pool_name | -| Latency/performance | Distribution | `distribution()` | endpoint, method, table, operation | -| Business values | Distribution | `distribution()` | user_tier, region, file_type | +| Category | Type | Method | Example Attributes | +| -------------------- | ------------ | ---------------- | ----------------------------------------- | +| Business events | Counter | `count()` | user_tier, payment_method, failure_reason | +| Application health | Counter | `count()` | email_type, provider, job_type, queue | +| Resource utilization | Gauge | `gauge()` | queue_name, pool_name | +| Latency/performance | Distribution | `distribution()` | endpoint, method, table, operation | +| Business values | Distribution | `distribution()` | user_tier, region, file_type | ## When to Use Metrics vs Traces vs Logs -| Signal | Best For | Example Question | -|--------|----------|------------------| -| **Metrics** | Aggregated counts, rates, percentiles | "How many checkouts failed this hour?" | -| **Traces** | Request flow, latency breakdown | "Why was this specific request slow?" | -| **Logs** | Detailed context, debugging | "What happened right before this error?" | +| Signal | Best For | Example Question | +| ----------- | ------------------------------------- | ---------------------------------------- | +| **Metrics** | Aggregated counts, rates, percentiles | "How many checkouts failed this hour?" | +| **Traces** | Request flow, latency breakdown | "Why was this specific request slow?" | +| **Logs** | Detailed context, debugging | "What happened right before this error?" | All three are trace-connected. Start wherever makes sense and navigate to the others. diff --git a/docs/guides/querying-traces.mdx b/docs/guides/querying-traces.mdx index 63237d647b024..7716a78cf6b9e 100644 --- a/docs/guides/querying-traces.mdx +++ b/docs/guides/querying-traces.mdx @@ -76,10 +76,10 @@ Learn about [creating alerts](/product/new-monitors-and-alerts/alerts/) and best ## Quick Reference -| Category | Query | Visualize | -|----------|-------|-----------| -| Slow page loads | `span.op:pageload` | `p90(span.duration)` by transaction | -| Slow fetch requests | `span.op:http.client` | `avg(span.duration)` by URL | -| JS blocking UI | `span.op:ui.long-animation-frame` | `max(span.duration)` | -| Slow SPA navigation | `span.op:navigation` | `p90(span.duration)` by transaction | -| Heavy resources | `span.op:resource.*` | `avg(span.duration)` by description | +| Category | Query | Visualize | +| ------------------- | --------------------------------- | ----------------------------------- | +| Slow page loads | `span.op:pageload` | `p90(span.duration)` by transaction | +| Slow fetch requests | `span.op:http.client` | `avg(span.duration)` by URL | +| JS blocking UI | `span.op:ui.long-animation-frame` | `max(span.duration)` | +| Slow SPA navigation | `span.op:navigation` | `p90(span.duration)` by transaction | +| Heavy resources | `span.op:resource.*` | `avg(span.duration)` by description | diff --git a/docs/guides/session-replay.mdx b/docs/guides/session-replay.mdx index 037e1f78e692f..7aa29b48548ab 100644 --- a/docs/guides/session-replay.mdx +++ b/docs/guides/session-replay.mdx @@ -4,11 +4,12 @@ sidebar_order: 40 description: "Practical guidance on debugging errors and finding UX issues with Session Replay." --- -You've set up [Sentry Session Replay](/product/explore/session-replay/). Now what? Stack traces tell you *what* broke. Replay shows you *why*. This guide covers how to use replay to debug errors and spot UX problems before users report them. +You've set up [Sentry Session Replay](/product/explore/session-replay/). Now what? Stack traces tell you _what_ broke. Replay shows you _why_. This guide covers how to use replay to debug errors and spot UX problems before users report them. ## What Replay Captures Every replay connected to an error includes: + - **User actions** — clicks, navigation, form inputs - **Network requests** — API calls, responses, failures, latency - **Console logs** — warnings, errors, debug messages @@ -21,6 +22,7 @@ Every replay connected to an error includes: The AI Summary tab automatically generates a natural language summary of what happened during a session. Instead of watching the entire replay, you can read a text description that highlights key actions, navigation paths, and timestamps. Use AI Summary to: + - Quickly understand what a user did without watching the full replay - Jump to specific moments in the session by clicking timestamps in the summary - Share context with teammates who need the highlights, not the full recording @@ -116,12 +118,12 @@ Be selective. Never unmask form inputs, and review your [privacy configuration]( ## Quick Reference -| What You're Looking For | Filter | -|------------------------|--------| -| Sessions with errors | `count_errors:>0` | -| Specific user | `user.email:jane@example.com` | -| Specific page | `url:*/checkout*` | -| Rage clicks | `count_rage_clicks:>0` | -| Dead clicks | `count_dead_clicks:>0` | -| Mobile users | `device.family:iOS` | -| Slow sessions | Filter by URL, watch for slow interactions | +| What You're Looking For | Filter | +| ----------------------- | ------------------------------------------ | +| Sessions with errors | `count_errors:>0` | +| Specific user | `user.email:jane@example.com` | +| Specific page | `url:*/checkout*` | +| Rage clicks | `count_rage_clicks:>0` | +| Dead clicks | `count_dead_clicks:>0` | +| Mobile users | `device.family:iOS` | +| Slow sessions | Filter by URL, watch for slow interactions | From 9a55e2759259215f76ab0c1e54a4e9110dab73c6 Mon Sep 17 00:00:00 2001 From: paulj Date: Wed, 18 Feb 2026 15:32:58 -0500 Subject: [PATCH 14/21] docs(guides): Add .NET, Ruby, Flutter, Swift, Kotlin examples Expand practical guides with code examples for additional SDKs: - .NET (C#) spans, errors, logs, and metrics - Ruby spans, errors, logs, and metrics - Flutter (Dart) spans, errors, logs, and metrics - Swift spans, errors, logs, and metrics - Kotlin spans, errors, logs, and metrics Co-Authored-By: Claude --- docs/guides/custom-spans.mdx | 410 ++++++++++++++++++++++++ docs/guides/issues-errors.mdx | 336 ++++++++++++++++++++ docs/guides/logs.mdx | 564 ++++++++++++++++++++++++++++++++++ docs/guides/metrics.mdx | 332 +++++++++++++++++++- 4 files changed, 1641 insertions(+), 1 deletion(-) diff --git a/docs/guides/custom-spans.mdx b/docs/guides/custom-spans.mdx index e569066ee0282..91274f6d9e8c1 100644 --- a/docs/guides/custom-spans.mdx +++ b/docs/guides/custom-spans.mdx @@ -36,6 +36,57 @@ $spanContext = \Sentry\Tracing\SpanContext::make() }, $spanContext); ``` +```csharp {tabTitle: .NET} +using Sentry; + +var transaction = SentrySdk.StartTransaction("operation-name", "category"); +var span = transaction.StartChild("category", "operation-name"); +span.SetExtra("key", value); +// ... your code ... +span.Finish(); +transaction.Finish(); +``` + +```ruby {tabTitle: Ruby} +Sentry.with_child_span(op: :category, description: 'operation-name') do |span| + span.set_data(:key, value) + # ... your code ... +end +``` + +```dart {tabTitle: Flutter} +import 'package:sentry/sentry.dart'; + +final transaction = Sentry.startTransaction('operation-name', 'category'); +final span = transaction.startChild('category', description: 'operation-name'); +span.setData('key', value); +// ... your code ... +await span.finish(); +await transaction.finish(); +``` + +```swift {tabTitle: Swift} +import Sentry + +let transaction = SentrySDK.startTransaction(name: "operation-name", operation: "category") +let span = transaction.startChild(operation: "category", description: "operation-name") +span.setData(value: value, key: "key") +// ... your code ... +span.finish() +transaction.finish() +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +val transaction = Sentry.startTransaction("operation-name", "category") +val span = transaction.startChild("category", "operation-name") +span.setData("key", value) +// ... your code ... +span.finish() +transaction.finish() +``` + Numeric attributes become metrics you can aggregate with `sum()`, `avg()`, `p90()` in Trace Explorer. ## Where to Add Spans @@ -85,6 +136,71 @@ $spanContext = \Sentry\Tracing\SpanContext::make() }, $spanContext); ``` +```csharp {tabTitle: .NET} +var transaction = SentrySdk.StartTransaction("checkout-flow", "user.action"); +SentrySdk.ConfigureScope(scope => scope.Transaction = transaction); + +transaction.SetExtra("cart.itemCount", 3); +transaction.SetExtra("user.tier", "premium"); + +await ValidateCart(); +await ProcessPayment(); +await CreateOrder(); + +transaction.Finish(); +``` + +```ruby {tabTitle: Ruby} +Sentry.with_child_span(op: 'user.action', description: 'checkout-flow') do |span| + span.set_data('cart.itemCount', 3) + span.set_data('user.tier', 'premium') + + validate_cart + process_payment + create_order +end +``` + +```dart {tabTitle: Flutter} +final transaction = Sentry.startTransaction('checkout-flow', 'user.action'); +transaction.setData('cart.itemCount', 3); +transaction.setData('user.tier', 'premium'); + +await validateCart(); +await processPayment(); +await createOrder(); + +await transaction.finish(); +``` + +```swift {tabTitle: Swift} +import Sentry + +let transaction = SentrySDK.startTransaction(name: "checkout-flow", operation: "user.action") +transaction.setData(value: 3, key: "cart.itemCount") +transaction.setData(value: "premium", key: "user.tier") + +validateCart() +processPayment() +createOrder() + +transaction.finish() +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +val transaction = Sentry.startTransaction("checkout-flow", "user.action") +transaction.setData("cart.itemCount", 3) +transaction.setData("user.tier", "premium") + +validateCart() +processPayment() +createOrder() + +transaction.finish() +``` + **Query in Explore > Traces:** `span.op:user.action` grouped by `user.tier`, visualize `p90(span.duration)`. **Alert idea:** `p90(span.duration) > 10s` for checkout flows. @@ -149,6 +265,77 @@ $spanContext = \Sentry\Tracing\SpanContext::make() }, $spanContext); ``` +```csharp {tabTitle: .NET} +var transaction = SentrySdk.StartTransaction("shipping-rates-api", "http.client"); +SentrySdk.ConfigureScope(scope => scope.Transaction = transaction); + +transaction.SetExtra("http.url", "api.shipper.com/rates"); +transaction.SetExtra("request.itemCount", items.Count); + +var stopwatch = Stopwatch.StartNew(); +var response = await httpClient.GetAsync("https://api.shipper.com/rates"); + +transaction.SetExtra("http.status_code", (int)response.StatusCode); +transaction.SetExtra("response.timeMs", stopwatch.ElapsedMilliseconds); +transaction.Finish(); +``` + +```ruby {tabTitle: Ruby} +Sentry.with_child_span(op: 'http.client', description: 'shipping-rates-api') do |span| + span.set_data('http.url', 'api.shipper.com/rates') + span.set_data('request.itemCount', items.length) + + start = Process.clock_gettime(Process::CLOCK_MONOTONIC) + response = HTTParty.get('https://api.shipper.com/rates') + + span.set_data('http.status_code', response.code) + span.set_data('response.timeMs', ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000).to_i) +end +``` + +```dart {tabTitle: Flutter} +final transaction = Sentry.startTransaction('shipping-rates-api', 'http.client'); +transaction.setData('http.url', 'api.shipper.com/rates'); +transaction.setData('request.itemCount', items.length); + +final stopwatch = Stopwatch()..start(); +final response = await http.get(Uri.parse('https://api.shipper.com/rates')); + +transaction.setData('http.status_code', response.statusCode); +transaction.setData('response.timeMs', stopwatch.elapsedMilliseconds); +await transaction.finish(); +``` + +```swift {tabTitle: Swift} +import Sentry + +let transaction = SentrySDK.startTransaction(name: "shipping-rates-api", operation: "http.client") +transaction.setData(value: "api.shipper.com/rates", key: "http.url") +transaction.setData(value: items.count, key: "request.itemCount") + +let start = Date() +let response = try await fetchShippingRates() + +transaction.setData(value: response.statusCode, key: "http.status_code") +transaction.setData(value: Int(Date().timeIntervalSince(start) * 1000), key: "response.timeMs") +transaction.finish() +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +val transaction = Sentry.startTransaction("shipping-rates-api", "http.client") +transaction.setData("http.url", "api.shipper.com/rates") +transaction.setData("request.itemCount", items.size) + +val start = System.currentTimeMillis() +val response = fetchShippingRates() + +transaction.setData("http.status_code", response.code) +transaction.setData("response.timeMs", System.currentTimeMillis() - start) +transaction.finish() +``` + **Query in Explore > Traces:** `span.op:http.client response.timeMs:>2000` to find slow external calls. **Alert idea:** `p95(span.duration) > 3s` where `http.url` contains your critical dependencies. @@ -205,6 +392,67 @@ $results = \Sentry\trace(function () use ($dashboardQuery) { }, $spanContext); ``` +```csharp {tabTitle: .NET} +var transaction = SentrySdk.StartTransaction("load-user-dashboard", "db.query"); +SentrySdk.ConfigureScope(scope => scope.Transaction = transaction); + +transaction.SetExtra("db.system", "postgres"); +transaction.SetExtra("query.type", "aggregation"); +transaction.SetExtra("query.dateRange", "30d"); + +var results = await database.QueryAsync(dashboardQuery); +transaction.SetExtra("result.rowCount", results.Count); +transaction.Finish(); +``` + +```ruby {tabTitle: Ruby} +Sentry.with_child_span(op: 'db.query', description: 'load-user-dashboard') do |span| + span.set_data('db.system', 'postgres') + span.set_data('query.type', 'aggregation') + span.set_data('query.dateRange', '30d') + + results = database.execute(dashboard_query) + span.set_data('result.rowCount', results.length) +end +``` + +```dart {tabTitle: Flutter} +final transaction = Sentry.startTransaction('load-user-dashboard', 'db.query'); +transaction.setData('db.system', 'postgres'); +transaction.setData('query.type', 'aggregation'); +transaction.setData('query.dateRange', '30d'); + +final results = await database.query(dashboardQuery); +transaction.setData('result.rowCount', results.length); +await transaction.finish(); +``` + +```swift {tabTitle: Swift} +import Sentry + +let transaction = SentrySDK.startTransaction(name: "load-user-dashboard", operation: "db.query") +transaction.setData(value: "postgres", key: "db.system") +transaction.setData(value: "aggregation", key: "query.type") +transaction.setData(value: "30d", key: "query.dateRange") + +let results = try database.execute(dashboardQuery) +transaction.setData(value: results.count, key: "result.rowCount") +transaction.finish() +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +val transaction = Sentry.startTransaction("load-user-dashboard", "db.query") +transaction.setData("db.system", "postgres") +transaction.setData("query.type", "aggregation") +transaction.setData("query.dateRange", "30d") + +val results = database.query(dashboardQuery) +transaction.setData("result.rowCount", results.size) +transaction.finish() +``` + **Why this matters:** Without these attributes, you see "a database query took 2 seconds." With them, you know it was aggregating 30 days of data and returned 50,000 rows. That's actionable. **Query ideas in Explore > Traces:** @@ -283,6 +531,107 @@ public function processEmailDigest($job) } ``` +```csharp {tabTitle: .NET} +public async Task ProcessEmailDigest(Job job) +{ + var transaction = SentrySdk.StartTransaction($"job:{job.Type}", "queue.process"); + SentrySdk.ConfigureScope(scope => scope.Transaction = transaction); + + transaction.SetExtra("job.id", job.Id); + transaction.SetExtra("job.type", "email-digest"); + transaction.SetExtra("queue.name", "notifications"); + + var users = await GetDigestRecipients(); + transaction.SetExtra("job.recipientCount", users.Count); + + foreach (var user in users) + { + await SendDigest(user); + } + + transaction.SetExtra("job.status", "completed"); + transaction.Finish(); +} +``` + +```ruby {tabTitle: Ruby} +def process_email_digest(job) + Sentry.with_child_span(op: 'queue.process', description: "job:#{job.type}") do |span| + span.set_data('job.id', job.id) + span.set_data('job.type', 'email-digest') + span.set_data('queue.name', 'notifications') + + users = get_digest_recipients + span.set_data('job.recipientCount', users.length) + + users.each { |user| send_digest(user) } + + span.set_data('job.status', 'completed') + end +end +``` + +```dart {tabTitle: Flutter} +Future processEmailDigest(Job job) async { + final transaction = Sentry.startTransaction('job:${job.type}', 'queue.process'); + transaction.setData('job.id', job.id); + transaction.setData('job.type', 'email-digest'); + transaction.setData('queue.name', 'notifications'); + + final users = await getDigestRecipients(); + transaction.setData('job.recipientCount', users.length); + + for (final user in users) { + await sendDigest(user); + } + + transaction.setData('job.status', 'completed'); + await transaction.finish(); +} +``` + +```swift {tabTitle: Swift} +import Sentry + +func processEmailDigest(job: Job) { + let transaction = SentrySDK.startTransaction(name: "job:\(job.type)", operation: "queue.process") + transaction.setData(value: job.id, key: "job.id") + transaction.setData(value: "email-digest", key: "job.type") + transaction.setData(value: "notifications", key: "queue.name") + + let users = getDigestRecipients() + transaction.setData(value: users.count, key: "job.recipientCount") + + for user in users { + sendDigest(to: user) + } + + transaction.setData(value: "completed", key: "job.status") + transaction.finish() +} +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +fun processEmailDigest(job: Job) { + val transaction = Sentry.startTransaction("job:${job.type}", "queue.process") + transaction.setData("job.id", job.id) + transaction.setData("job.type", "email-digest") + transaction.setData("queue.name", "notifications") + + val users = getDigestRecipients() + transaction.setData("job.recipientCount", users.size) + + users.forEach { user -> + sendDigest(user) + } + + transaction.setData("job.status", "completed") + transaction.finish() +} +``` + **Query in Explore > Traces:** `span.op:queue.process` grouped by `job.type`, visualize `p90(span.duration)`. **Alert idea:** `p90(span.duration) > 60s` for queue processing. @@ -339,6 +688,67 @@ $response = \Sentry\trace(function () { }, $spanContext); ``` +```csharp {tabTitle: .NET} +var transaction = SentrySdk.StartTransaction("generate-summary", "ai.inference"); +SentrySdk.ConfigureScope(scope => scope.Transaction = transaction); + +transaction.SetExtra("ai.model", "gpt-4"); +transaction.SetExtra("ai.feature", "document-summary"); + +var response = await openai.ChatCompletion.CreateAsync(...); + +transaction.SetExtra("ai.tokens.total", response.Usage.TotalTokens); +transaction.Finish(); +``` + +```ruby {tabTitle: Ruby} +Sentry.with_child_span(op: 'ai.inference', description: 'generate-summary') do |span| + span.set_data('ai.model', 'gpt-4') + span.set_data('ai.feature', 'document-summary') + + response = openai.chat(...) + + span.set_data('ai.tokens.total', response.dig('usage', 'total_tokens')) +end +``` + +```dart {tabTitle: Flutter} +final transaction = Sentry.startTransaction('generate-summary', 'ai.inference'); +transaction.setData('ai.model', 'gpt-4'); +transaction.setData('ai.feature', 'document-summary'); + +final response = await openai.chat.completions.create(...); + +transaction.setData('ai.tokens.total', response.usage.totalTokens); +await transaction.finish(); +``` + +```swift {tabTitle: Swift} +import Sentry + +let transaction = SentrySDK.startTransaction(name: "generate-summary", operation: "ai.inference") +transaction.setData(value: "gpt-4", key: "ai.model") +transaction.setData(value: "document-summary", key: "ai.feature") + +let response = try await openai.chat.completions.create(...) + +transaction.setData(value: response.usage.totalTokens, key: "ai.tokens.total") +transaction.finish() +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +val transaction = Sentry.startTransaction("generate-summary", "ai.inference") +transaction.setData("ai.model", "gpt-4") +transaction.setData("ai.feature", "document-summary") + +val response = openai.chat.completions.create(...) + +transaction.setData("ai.tokens.total", response.usage.totalTokens) +transaction.finish() +``` + **Alert idea:** `p95(span.duration) > 5s` for AI inference. ## Quick Reference diff --git a/docs/guides/issues-errors.mdx b/docs/guides/issues-errors.mdx index b59a0fe71b74d..66189dca749c0 100644 --- a/docs/guides/issues-errors.mdx +++ b/docs/guides/issues-errors.mdx @@ -50,6 +50,76 @@ try { } ``` +```csharp {tabTitle: .NET} +try +{ + await ProcessOrder(order); +} +catch (Exception ex) +{ + SentrySdk.ConfigureScope(scope => + { + scope.SetTag("order_id", order.Id); + scope.SetTag("payment_method", order.PaymentMethod); + }); + SentrySdk.CaptureException(ex); + throw; +} +``` + +```ruby {tabTitle: Ruby} +begin + process_order(order) +rescue => e + Sentry.set_tags(order_id: order.id, payment_method: order.payment_method) + Sentry.capture_exception(e) + raise +end +``` + +```dart {tabTitle: Flutter} +try { + await processOrder(order); +} catch (error, stackTrace) { + Sentry.configureScope((scope) { + scope.setTag('order_id', order.id); + scope.setTag('payment_method', order.paymentMethod); + }); + await Sentry.captureException(error, stackTrace: stackTrace); + rethrow; +} +``` + +```swift {tabTitle: Swift} +import Sentry + +do { + try processOrder(order) +} catch { + SentrySDK.configureScope { scope in + scope.setTag(value: order.id, key: "order_id") + scope.setTag(value: order.paymentMethod, key: "payment_method") + } + SentrySDK.capture(error: error) + throw error +} +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +try { + processOrder(order) +} catch (e: Exception) { + Sentry.configureScope { scope -> + scope.setTag("order_id", order.id) + scope.setTag("payment_method", order.paymentMethod) + } + Sentry.captureException(e) + throw e +} +``` + **Levels:** `fatal`, `error`, `warning`, `info`, `debug` **Context:** Tags, user info, logs, and session replays help you debug faster. Tags are searchable, so use them for high-cardinality data like IDs, regions, and feature flags. @@ -208,6 +278,112 @@ sentry_sdk.capture_exception(error) \Sentry\captureException($error); ``` +```csharp {tabTitle: .NET} +// Set user globally (e.g., after login) +SentrySdk.ConfigureScope(scope => +{ + scope.User = new SentryUser { Id = user.Id, Email = user.Email }; +}); + +// Add tags and context per-event +SentrySdk.ConfigureScope(scope => +{ + scope.SetTag("order_id", order.Id); + scope.SetTag("payment_gateway", "stripe"); + scope.SetTag("region", user.Region); + scope.Contexts["order"] = new + { + total = order.Total, + items = order.Items.Count, + discount_code = order.DiscountCode + }; +}); +SentrySdk.CaptureException(error); +``` + +```ruby {tabTitle: Ruby} +# Set user globally (e.g., after login) +Sentry.set_user(id: user.id, email: user.email) + +# Add tags and context per-event +Sentry.set_tags( + order_id: order.id, + payment_gateway: 'stripe', + region: user.region +) +Sentry.set_context('order', { + total: order.total, + items: order.items.length, + discount_code: order.discount_code +}) +Sentry.capture_exception(error) +``` + +```dart {tabTitle: Flutter} +// Set user globally (e.g., after login) +Sentry.configureScope((scope) { + scope.setUser(SentryUser(id: user.id, email: user.email)); +}); + +// Add tags and context per-event +Sentry.configureScope((scope) { + scope.setTag('order_id', order.id); + scope.setTag('payment_gateway', 'stripe'); + scope.setTag('region', user.region); + scope.setContexts('order', { + 'total': order.total, + 'items': order.items.length, + 'discount_code': order.discountCode, + }); +}); +await Sentry.captureException(error); +``` + +```swift {tabTitle: Swift} +import Sentry + +// Set user globally (e.g., after login) +let sentryUser = User() +sentryUser.userId = user.id +sentryUser.email = user.email +SentrySDK.setUser(sentryUser) + +// Add tags and context per-event +SentrySDK.configureScope { scope in + scope.setTag(value: order.id, key: "order_id") + scope.setTag(value: "stripe", key: "payment_gateway") + scope.setTag(value: user.region, key: "region") + scope.setContext(value: [ + "total": order.total, + "items": order.items.count, + "discount_code": order.discountCode + ], key: "order") +} +SentrySDK.capture(error: error) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry +import io.sentry.protocol.User + +// Set user globally (e.g., after login) +Sentry.setUser(User().apply { + id = user.id + email = user.email +}) + +// Add tags and context per-event +Sentry.configureScope { scope -> + scope.setTag("order_id", order.id) + scope.setTag("payment_gateway", "stripe") + scope.setTag("region", user.region) + scope.setContexts("order.total", order.total) + scope.setContexts("order.items", order.items.size) + scope.setContexts("order.discount_code", order.discountCode) +} +Sentry.captureException(error) +``` + **Search in Sentry:** `order_id:order_123` or `payment_gateway:stripe region:us-west` ### Ignore Known Noise @@ -245,6 +421,85 @@ sentry_sdk.init( ]); ``` +```csharp {tabTitle: .NET} +SentrySdk.Init(options => +{ + options.Dsn = "..."; + options.SetBeforeSend((sentryEvent, hint) => + { + // Filter out specific error types + if (sentryEvent.Exception is NetworkException) + { + return null; + } + return sentryEvent; + }); +}); +``` + +```ruby {tabTitle: Ruby} +Sentry.init do |config| + config.dsn = '...' + config.before_send = lambda do |event, hint| + # Filter out specific error types + if hint[:exception].is_a?(NetworkError) + nil + else + event + end + end +end +``` + +```dart {tabTitle: Flutter} +await SentryFlutter.init( + (options) { + options.dsn = '...'; + options.beforeSend = (event, hint) { + // Filter out specific error types + if (event.exceptions?.any((e) => e.type == 'NetworkException') ?? false) { + return null; + } + return event; + }; + }, + appRunner: () => runApp(MyApp()), +); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.start { options in + options.dsn = "..." + options.beforeSend = { event in + // Filter out specific error types + if let exceptions = event.exceptions, + exceptions.contains(where: { $0.type == "NetworkError" }) { + return nil + } + return event + } +} +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.android.core.SentryAndroid +import io.sentry.SentryOptions.BeforeSendCallback + +SentryAndroid.init(context) { options -> + options.dsn = "..." + options.beforeSend = BeforeSendCallback { event, hint -> + // Filter out specific error types + if (event.exceptions?.any { it.type == "NetworkException" } == true) { + null + } else { + event + } + } +} +``` + You can also use beforeSend to filter errors dynamically: ```javascript {tabTitle: JavaScript} @@ -293,6 +548,87 @@ sentry_sdk.init( ]); ``` +```csharp {tabTitle: .NET} +SentrySdk.Init(options => +{ + options.Dsn = "..."; + options.SetBeforeSend((sentryEvent, hint) => + { + // Ignore specific error types + if (sentryEvent.Exception is InvalidOperationException) + { + return null; + } + return sentryEvent; + }); +}); +``` + +```ruby {tabTitle: Ruby} +Sentry.init do |config| + config.dsn = '...' + config.before_send = lambda do |event, hint| + # Ignore specific error types + if hint[:exception].is_a?(ArgumentError) + nil + else + event + end + end +end +``` + +```dart {tabTitle: Flutter} +await SentryFlutter.init( + (options) { + options.dsn = '...'; + options.beforeSend = (event, hint) { + // Ignore specific error types + final exception = hint?.exception; + if (exception is StateError) { + return null; + } + return event; + }; + }, + appRunner: () => runApp(MyApp()), +); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.start { options in + options.dsn = "..." + options.beforeSend = { event in + // Ignore specific error types + if let error = event.error as NSError?, + error.domain == "MyAppErrorDomain" { + return nil + } + return event + } +} +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.android.core.SentryAndroid +import io.sentry.SentryOptions.BeforeSendCallback + +SentryAndroid.init(context) { options -> + options.dsn = "..." + options.beforeSend = BeforeSendCallback { event, hint -> + // Ignore specific error types + val throwable = hint.originalThrowable + if (throwable is IllegalStateException) { + null + } else { + event + } + } +} +``` + ## Quick Reference | View | Search Query | Look For | diff --git a/docs/guides/logs.mdx b/docs/guides/logs.mdx index 661b3715b93dd..c2f7eb0708f42 100644 --- a/docs/guides/logs.mdx +++ b/docs/guides/logs.mdx @@ -23,6 +23,30 @@ logger.(message, attribute=value) \Sentry\logger()->(message, attributes: [...]); ``` +```csharp {tabTitle: .NET} +using Sentry; +SentrySdk.Logger.(message); +``` + +```ruby {tabTitle: Ruby} +Sentry.logger.(message) +``` + +```dart {tabTitle: Flutter} +import 'package:sentry/sentry.dart'; +Sentry.logger.(message); +``` + +```swift {tabTitle: Swift} +import Sentry +SentrySDK.logger.(message, attributes: [...]) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry +Sentry.logger().(message) +``` + **Levels:** `trace`, `debug`, `info`, `warn` (or `warning` in Python), `error`, `fatal` **Attributes:** Key-value pairs you can search and filter on. Consistency matters, so use whatever naming convention fits your codebase. @@ -56,6 +80,52 @@ sentry_logger.info("Order completed", ]); ``` +```csharp {tabTitle: .NET} +using Sentry; + +SentrySdk.Logger.Info("Order completed", logger => logger + .SetAttribute("orderId", "order_123") + .SetAttribute("userId", user.Id) + .SetAttribute("amount", 149.99) + .SetAttribute("paymentMethod", "stripe")); +``` + +```ruby {tabTitle: Ruby} +Sentry.logger.info('Order completed', + order_id: 'order_123', + user_id: user.id, + amount: 149.99, + payment_method: 'stripe' +) +``` + +```dart {tabTitle: Flutter} +Sentry.logger.info('Order completed', attributes: { + 'orderId': 'order_123', + 'userId': user.id, + 'amount': 149.99, + 'paymentMethod': 'stripe', +}); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.logger.info("Order completed", attributes: [ + "orderId": "order_123", + "userId": user.id, + "amount": 149.99, + "paymentMethod": "stripe" +]) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +Sentry.logger().info("Order completed orderId=%s userId=%s amount=%.2f", + "order_123", user.id, 149.99) +``` + Logs in Sentry are automatically trace-connected. Each log shows a trace ID that links to the full [trace view](/concepts/key-terms/tracing/trace-view/). ## Where to Add Logs @@ -110,6 +180,70 @@ sentry_logger.warning("Login failed", ]); ``` +```csharp {tabTitle: .NET} +SentrySdk.Logger.Info("User logged in", logger => logger + .SetAttribute("userId", user.Id) + .SetAttribute("authMethod", "oauth") + .SetAttribute("provider", "google")); + +SentrySdk.Logger.Warning("Login failed", logger => logger + .SetAttribute("email", maskedEmail) + .SetAttribute("reason", "invalid_password") + .SetAttribute("attemptCount", 3)); +``` + +```ruby {tabTitle: Ruby} +Sentry.logger.info('User logged in', + user_id: user.id, + auth_method: 'oauth', + provider: 'google' +) + +Sentry.logger.warn('Login failed', + email: masked_email, + reason: 'invalid_password', + attempt_count: 3 +) +``` + +```dart {tabTitle: Flutter} +Sentry.logger.info('User logged in', attributes: { + 'userId': user.id, + 'authMethod': 'oauth', + 'provider': 'google', +}); + +Sentry.logger.warn('Login failed', attributes: { + 'email': maskedEmail, + 'reason': 'invalid_password', + 'attemptCount': 3, +}); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.logger.info("User logged in", attributes: [ + "userId": user.id, + "authMethod": "oauth", + "provider": "google" +]) + +SentrySDK.logger.warn("Login failed", attributes: [ + "email": maskedEmail, + "reason": "invalid_password", + "attemptCount": 3 +]) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +Sentry.logger().info("User logged in userId=%s authMethod=%s", user.id, "oauth") + +Sentry.logger().warn("Login failed email=%s reason=%s", maskedEmail, "invalid_password") +``` + **Search in Sentry:** `userId:123 "logged in"` or `severity:warn authMethod:*` **Alert idea:** Alert when `severity:warn "Login failed"` spikes in a 5-minute window—this can indicate brute force attempts or auth provider issues. @@ -150,6 +284,54 @@ sentry_logger.error("Payment failed", ]); ``` +```csharp {tabTitle: .NET} +SentrySdk.Logger.Error("Payment failed", logger => logger + .SetAttribute("orderId", "order_123") + .SetAttribute("amount", 99.99) + .SetAttribute("gateway", "stripe") + .SetAttribute("errorCode", "card_declined") + .SetAttribute("cartItems", 3)); +``` + +```ruby {tabTitle: Ruby} +Sentry.logger.error('Payment failed', + order_id: 'order_123', + amount: 99.99, + gateway: 'stripe', + error_code: 'card_declined', + cart_items: 3 +) +``` + +```dart {tabTitle: Flutter} +Sentry.logger.error('Payment failed', attributes: { + 'orderId': 'order_123', + 'amount': 99.99, + 'gateway': 'stripe', + 'errorCode': 'card_declined', + 'cartItems': 3, +}); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.logger.error("Payment failed", attributes: [ + "orderId": "order_123", + "amount": 99.99, + "gateway": "stripe", + "errorCode": "card_declined", + "cartItems": 3 +]) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +Sentry.logger().error("Payment failed orderId=%s gateway=%s errorCode=%s", + "order_123", "stripe", "card_declined") +``` + **Search in Sentry:** `orderId:order_123` or `severity:error gateway:stripe` **Alert idea:** Alert when `severity:error gateway:*` spikes—this can indicate payment provider outages. @@ -221,6 +403,101 @@ $response = $shippingApi->getRates($items); ]); ``` +```csharp {tabTitle: .NET} +// Third-party API call +var stopwatch = Stopwatch.StartNew(); +var response = await shippingApi.GetRatesAsync(items); + +SentrySdk.Logger.Info("Shipping rates fetched", logger => logger + .SetAttribute("service", "shipping-provider") + .SetAttribute("endpoint", "/rates") + .SetAttribute("durationMs", stopwatch.ElapsedMilliseconds) + .SetAttribute("rateCount", response.Rates.Count)); + +// Webhook received +SentrySdk.Logger.Info("Webhook received", logger => logger + .SetAttribute("source", "stripe") + .SetAttribute("eventType", "payment_intent.succeeded") + .SetAttribute("paymentId", eventData.Object.Id)); +``` + +```ruby {tabTitle: Ruby} +# Third-party API call +start = Process.clock_gettime(Process::CLOCK_MONOTONIC) +response = shipping_api.get_rates(items) + +Sentry.logger.info('Shipping rates fetched', + service: 'shipping-provider', + endpoint: '/rates', + duration_ms: ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000).to_i, + rate_count: response.rates.length +) + +# Webhook received +Sentry.logger.info('Webhook received', + source: 'stripe', + event_type: 'payment_intent.succeeded', + payment_id: event['data']['object']['id'] +) +``` + +```dart {tabTitle: Flutter} +// Third-party API call +final stopwatch = Stopwatch()..start(); +final response = await shippingApi.getRates(items); + +Sentry.logger.info('Shipping rates fetched', attributes: { + 'service': 'shipping-provider', + 'endpoint': '/rates', + 'durationMs': stopwatch.elapsedMilliseconds, + 'rateCount': response.rates.length, +}); + +// Webhook received +Sentry.logger.info('Webhook received', attributes: { + 'source': 'stripe', + 'eventType': 'payment_intent.succeeded', + 'paymentId': event.data.object.id, +}); +``` + +```swift {tabTitle: Swift} +import Sentry + +// Third-party API call +let start = Date() +let response = try await shippingApi.getRates(items) + +SentrySDK.logger.info("Shipping rates fetched", attributes: [ + "service": "shipping-provider", + "endpoint": "/rates", + "durationMs": Int(Date().timeIntervalSince(start) * 1000), + "rateCount": response.rates.count +]) + +// Webhook received +SentrySDK.logger.info("Webhook received", attributes: [ + "source": "stripe", + "eventType": "payment_intent.succeeded", + "paymentId": event.data.object.id +]) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +// Third-party API call +val start = System.currentTimeMillis() +val response = shippingApi.getRates(items) + +Sentry.logger().info("Shipping rates fetched service=%s durationMs=%d", + "shipping-provider", System.currentTimeMillis() - start) + +// Webhook received +Sentry.logger().info("Webhook received source=%s eventType=%s", + "stripe", "payment_intent.succeeded") +``` + **Search in Sentry:** `service:shipping-provider durationMs:>2000` or `source:stripe` **Alert idea:** Alert when `service:* durationMs:>3000` to catch third-party slowdowns before they cascade. @@ -276,6 +553,76 @@ sentry_logger.error("Job failed", ]); ``` +```csharp {tabTitle: .NET} +SentrySdk.Logger.Info("Job started", logger => logger + .SetAttribute("jobType", "email-digest") + .SetAttribute("jobId", "job_456") + .SetAttribute("queue", "notifications")); + +SentrySdk.Logger.Error("Job failed", logger => logger + .SetAttribute("jobType", "email-digest") + .SetAttribute("jobId", "job_456") + .SetAttribute("retryCount", 3) + .SetAttribute("lastError", "SMTP timeout")); +``` + +```ruby {tabTitle: Ruby} +Sentry.logger.info('Job started', + job_type: 'email-digest', + job_id: 'job_456', + queue: 'notifications' +) + +Sentry.logger.error('Job failed', + job_type: 'email-digest', + job_id: 'job_456', + retry_count: 3, + last_error: 'SMTP timeout' +) +``` + +```dart {tabTitle: Flutter} +Sentry.logger.info('Job started', attributes: { + 'jobType': 'email-digest', + 'jobId': 'job_456', + 'queue': 'notifications', +}); + +Sentry.logger.error('Job failed', attributes: { + 'jobType': 'email-digest', + 'jobId': 'job_456', + 'retryCount': 3, + 'lastError': 'SMTP timeout', +}); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.logger.info("Job started", attributes: [ + "jobType": "email-digest", + "jobId": "job_456", + "queue": "notifications" +]) + +SentrySDK.logger.error("Job failed", attributes: [ + "jobType": "email-digest", + "jobId": "job_456", + "retryCount": 3, + "lastError": "SMTP timeout" +]) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +Sentry.logger().info("Job started jobType=%s jobId=%s queue=%s", + "email-digest", "job_456", "notifications") + +Sentry.logger().error("Job failed jobType=%s jobId=%s retryCount=%d", + "email-digest", "job_456", 3) +``` + **Search in Sentry:** `jobType:email-digest severity:error` **Alert idea:** Alert when `severity:error jobType:*` spikes—this can indicate queue processing issues or downstream failures. @@ -325,6 +672,67 @@ sentry_logger.warning("Config reloaded", ]); ``` +```csharp {tabTitle: .NET} +SentrySdk.Logger.Info("Feature flag evaluated", logger => logger + .SetAttribute("flag", "new-checkout-flow") + .SetAttribute("enabled", true) + .SetAttribute("userId", user.Id)); + +SentrySdk.Logger.Warning("Config reloaded", logger => logger + .SetAttribute("reason", "env-change") + .SetAttribute("changedKeys", new[] { "API_TIMEOUT", "MAX_CONNECTIONS" })); +``` + +```ruby {tabTitle: Ruby} +Sentry.logger.info('Feature flag evaluated', + flag: 'new-checkout-flow', + enabled: true, + user_id: user.id +) + +Sentry.logger.warn('Config reloaded', + reason: 'env-change', + changed_keys: ['API_TIMEOUT', 'MAX_CONNECTIONS'] +) +``` + +```dart {tabTitle: Flutter} +Sentry.logger.info('Feature flag evaluated', attributes: { + 'flag': 'new-checkout-flow', + 'enabled': true, + 'userId': user.id, +}); + +Sentry.logger.warn('Config reloaded', attributes: { + 'reason': 'env-change', + 'changedKeys': ['API_TIMEOUT', 'MAX_CONNECTIONS'], +}); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.logger.info("Feature flag evaluated", attributes: [ + "flag": "new-checkout-flow", + "enabled": true, + "userId": user.id +]) + +SentrySDK.logger.warn("Config reloaded", attributes: [ + "reason": "env-change", + "changedKeys": ["API_TIMEOUT", "MAX_CONNECTIONS"] +]) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +Sentry.logger().info("Feature flag evaluated flag=%s enabled=%b userId=%s", + "new-checkout-flow", true, user.id) + +Sentry.logger().warn("Config reloaded reason=%s", "env-change") +``` + **Search in Sentry:** `flag:new-checkout-flow` or `"Config reloaded"` ## Creating Alerts From Logs @@ -384,6 +792,59 @@ sentry_sdk.init( ]); ``` +```csharp {tabTitle: .NET} +SentrySdk.Init(options => +{ + options.Dsn = "..."; + options.Environment = "development"; + options.TracesSampleRate = 1.0; // 100% of traces + options.EnableLogs = true; +}); +``` + +```ruby {tabTitle: Ruby} +Sentry.init do |config| + config.dsn = '...' + config.environment = 'development' + config.traces_sample_rate = 1.0 # 100% of traces + config.enable_logs = true +end +``` + +```dart {tabTitle: Flutter} +await SentryFlutter.init( + (options) { + options.dsn = '...'; + options.environment = 'development'; + options.tracesSampleRate = 1.0; // 100% of traces + options.enableLogs = true; + }, + appRunner: () => runApp(MyApp()), +); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.start { options in + options.dsn = "..." + options.environment = "development" + options.tracesSampleRate = 1.0 // 100% of traces + options.enableLogs = true +} +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.android.core.SentryAndroid + +SentryAndroid.init(context) { options -> + options.dsn = "..." + options.environment = "development" + options.tracesSampleRate = 1.0 // 100% of traces + options.logs.enabled = true +} +``` + Use verbose logging levels like `debug` (development diagnostics) and `trace` (fine-grained execution details) freely in development. You can [filter these out in production](/platforms/javascript/logs/#filter-logs) using `beforeSendLog` to only capture `info` and above. ### Production Logging @@ -412,6 +873,36 @@ sentry_logger.error("Payment failed", reason="Insufficient Funds") \Sentry\logger()->error('Payment failed', attributes: ['reason' => 'Insufficient Funds']); ``` +```csharp {tabTitle: .NET} +SentrySdk.Logger.Info("Checkout started", l => l.SetAttribute("userId", "882")); +SentrySdk.Logger.Info("Discount applied", l => l.SetAttribute("code", "WINTER20")); +SentrySdk.Logger.Error("Payment failed", l => l.SetAttribute("reason", "Insufficient Funds")); +``` + +```ruby {tabTitle: Ruby} +Sentry.logger.info('Checkout started', user_id: '882') +Sentry.logger.info('Discount applied', code: 'WINTER20') +Sentry.logger.error('Payment failed', reason: 'Insufficient Funds') +``` + +```dart {tabTitle: Flutter} +Sentry.logger.info('Checkout started', attributes: {'userId': '882'}); +Sentry.logger.info('Discount applied', attributes: {'code': 'WINTER20'}); +Sentry.logger.error('Payment failed', attributes: {'reason': 'Insufficient Funds'}); +``` + +```swift {tabTitle: Swift} +SentrySDK.logger.info("Checkout started", attributes: ["userId": "882"]) +SentrySDK.logger.info("Discount applied", attributes: ["code": "WINTER20"]) +SentrySDK.logger.error("Payment failed", attributes: ["reason": "Insufficient Funds"]) +``` + +```kotlin {tabTitle: Kotlin} +Sentry.logger().info("Checkout started userId=%s", "882") +Sentry.logger().info("Discount applied code=%s", "WINTER20") +Sentry.logger().error("Payment failed reason=%s", "Insufficient Funds") +``` + These logs are trace-connected, but searching for the error won't return the userId or discount code from the same transaction. **Do this instead:** @@ -452,6 +943,79 @@ sentry_logger.error("Checkout failed", ]); ``` +```csharp {tabTitle: .NET} +SentrySdk.Logger.Error("Checkout failed", logger => logger + .SetAttribute("userId", "882") + .SetAttribute("orderId", "order_pc_991") + .SetAttribute("cartTotal", 142.50) + .SetAttribute("discountCode", "WINTER20") + .SetAttribute("paymentMethod", "stripe") + .SetAttribute("errorReason", "Insufficient Funds") + .SetAttribute("itemCount", 4)); +``` + +```ruby {tabTitle: Ruby} +Sentry.logger.error('Checkout failed', + user_id: '882', + order_id: 'order_pc_991', + cart_total: 142.50, + discount_code: 'WINTER20', + payment_method: 'stripe', + error_reason: 'Insufficient Funds', + item_count: 4 +) +``` + +```dart {tabTitle: Flutter} +Sentry.logger.error('Checkout failed', attributes: { + 'userId': '882', + 'orderId': 'order_pc_991', + 'cartTotal': 142.50, + 'discountCode': 'WINTER20', + 'paymentMethod': 'stripe', + 'errorReason': 'Insufficient Funds', + 'itemCount': 4, +}); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.logger.error("Checkout failed", attributes: [ + "userId": "882", + "orderId": "order_pc_991", + "cartTotal": 142.50, + "discountCode": "WINTER20", + "paymentMethod": "stripe", + "errorReason": "Insufficient Funds", + "itemCount": 4 +]) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry +import io.sentry.SentryAttribute +import io.sentry.SentryAttributes +import io.sentry.SentryLogLevel +import io.sentry.logger.SentryLogParameters + +Sentry.logger().log( + SentryLogLevel.ERROR, + SentryLogParameters.create( + SentryAttributes.of( + SentryAttribute.stringAttribute("userId", "882"), + SentryAttribute.stringAttribute("orderId", "order_pc_991"), + SentryAttribute.doubleAttribute("cartTotal", 142.50), + SentryAttribute.stringAttribute("discountCode", "WINTER20"), + SentryAttribute.stringAttribute("paymentMethod", "stripe"), + SentryAttribute.stringAttribute("errorReason", "Insufficient Funds"), + SentryAttribute.integerAttribute("itemCount", 4) + ) + ), + "Checkout failed" +) +``` + One log tells the whole story. Search for the error and get full context. ### Log Drains for Platform Logs diff --git a/docs/guides/metrics.mdx b/docs/guides/metrics.mdx index 797f1596083be..53cf3cec94eed 100644 --- a/docs/guides/metrics.mdx +++ b/docs/guides/metrics.mdx @@ -43,6 +43,41 @@ sentry_sdk.metrics.count("checkout.failed", 1, attributes={ ]); ``` +```csharp {tabTitle: .NET} +SentrySdk.Metrics.Counter("checkout.failed") + .Tag("user_tier", "premium") + .Tag("failure_reason", "payment_declined") + .Increment(); +``` + +```ruby {tabTitle: Ruby} +Sentry.metrics.count('checkout.failed', 1, + tags: { user_tier: 'premium', failure_reason: 'payment_declined' } +) +``` + +```dart {tabTitle: Flutter} +Sentry.metrics.count('checkout.failed', 1, attributes: { + 'user_tier': 'premium', + 'failure_reason': 'payment_declined', +}); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.metrics.count(key: "checkout.failed", value: 1, attributes: [ + "user_tier": "premium", + "failure_reason": "payment_declined" +]) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +Sentry.metrics().count("checkout.failed", 1.0) +``` + ## Where to Track Metrics Start with these five metrics and you'll spot issues before they become problems. @@ -83,6 +118,59 @@ sentry_sdk.metrics.count("checkout.failed", 1, attributes={ ]); ``` +```csharp {tabTitle: .NET} +SentrySdk.Metrics.Counter("checkout.completed") + .Tag("user_tier", "premium") + .Tag("payment_method", "card") + .Increment(); + +SentrySdk.Metrics.Counter("checkout.failed") + .Tag("user_tier", "premium") + .Tag("failure_reason", "payment_declined") + .Increment(); +``` + +```ruby {tabTitle: Ruby} +Sentry.metrics.count('checkout.completed', 1, + tags: { user_tier: 'premium', payment_method: 'card' } +) + +Sentry.metrics.count('checkout.failed', 1, + tags: { user_tier: 'premium', failure_reason: 'payment_declined' } +) +``` + +```dart {tabTitle: Flutter} +Sentry.metrics.count('checkout.completed', 1, attributes: { + 'user_tier': 'premium', + 'payment_method': 'card', +}); + +Sentry.metrics.count('checkout.failed', 1, attributes: { + 'user_tier': 'premium', + 'failure_reason': 'payment_declined', +}); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.metrics.count(key: "checkout.completed", value: 1, attributes: [ + "user_tier": "premium", "payment_method": "card" +]) + +SentrySDK.metrics.count(key: "checkout.failed", value: 1, attributes: [ + "user_tier": "premium", "failure_reason": "payment_declined" +]) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +Sentry.metrics().count("checkout.completed", 1.0) +Sentry.metrics().count("checkout.failed", 1.0) +``` + **Explore in Sentry:** 1. Go to **Explore > Metrics** @@ -138,6 +226,78 @@ sentry_sdk.metrics.count("job.processed", 1, attributes={ ]); ``` +```csharp {tabTitle: .NET} +SentrySdk.Metrics.Counter("email.sent") + .Tag("email_type", "welcome") + .Tag("provider", "sendgrid") + .Increment(); + +SentrySdk.Metrics.Counter("email.failed") + .Tag("email_type", "welcome") + .Tag("error", "rate_limited") + .Increment(); + +SentrySdk.Metrics.Counter("job.processed") + .Tag("job_type", "invoice-generation") + .Tag("queue", "billing") + .Increment(); +``` + +```ruby {tabTitle: Ruby} +Sentry.metrics.count('email.sent', 1, + tags: { email_type: 'welcome', provider: 'sendgrid' } +) + +Sentry.metrics.count('email.failed', 1, + tags: { email_type: 'welcome', error: 'rate_limited' } +) + +Sentry.metrics.count('job.processed', 1, + tags: { job_type: 'invoice-generation', queue: 'billing' } +) +``` + +```dart {tabTitle: Flutter} +Sentry.metrics.count('email.sent', 1, attributes: { + 'email_type': 'welcome', + 'provider': 'sendgrid', +}); + +Sentry.metrics.count('email.failed', 1, attributes: { + 'email_type': 'welcome', + 'error': 'rate_limited', +}); + +Sentry.metrics.count('job.processed', 1, attributes: { + 'job_type': 'invoice-generation', + 'queue': 'billing', +}); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.metrics.count(key: "email.sent", value: 1, attributes: [ + "email_type": "welcome", "provider": "sendgrid" +]) + +SentrySDK.metrics.count(key: "email.failed", value: 1, attributes: [ + "email_type": "welcome", "error": "rate_limited" +]) + +SentrySDK.metrics.count(key: "job.processed", value: 1, attributes: [ + "job_type": "invoice-generation", "queue": "billing" +]) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +Sentry.metrics().count("email.sent", 1.0) +Sentry.metrics().count("email.failed", 1.0) +Sentry.metrics().count("job.processed", 1.0) +``` + **Explore in Sentry:** Add both `email.sent` and `email.failed`, group by `email_type`, compare the ratio. ### 3. Resource Utilization @@ -178,6 +338,55 @@ use \Sentry\Metrics\Unit; ]); ``` +```csharp {tabTitle: .NET} +SentrySdk.Metrics.Gauge("queue.depth") + .Tag("queue_name", "notifications") + .Set(queue.Size); + +SentrySdk.Metrics.Gauge("pool.connections_active") + .Tag("pool_name", "postgres-primary") + .Set(pool.ActiveConnections); +``` + +```ruby {tabTitle: Ruby} +Sentry.metrics.gauge('queue.depth', queue.size, + tags: { queue_name: 'notifications' } +) + +Sentry.metrics.gauge('pool.connections_active', pool.active_connections, + tags: { pool_name: 'postgres-primary' } +) +``` + +```dart {tabTitle: Flutter} +Sentry.metrics.gauge('queue.depth', queue.size.toDouble(), attributes: { + 'queue_name': 'notifications', +}); + +Sentry.metrics.gauge('pool.connections_active', pool.activeConnections.toDouble(), attributes: { + 'pool_name': 'postgres-primary', +}); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.metrics.gauge(key: "queue.depth", value: Double(queue.size), attributes: [ + "queue_name": "notifications" +]) + +SentrySDK.metrics.gauge(key: "pool.connections_active", value: Double(pool.activeConnections), attributes: [ + "pool_name": "postgres-primary" +]) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry + +Sentry.metrics().gauge("queue.depth", queue.size.toDouble()) +Sentry.metrics().gauge("pool.connections_active", pool.activeConnections.toDouble()) +``` + **Explore in Sentry:** View `max(queue.depth)` over time to spot backlogs. ### 4. Latency and Performance @@ -224,6 +433,67 @@ use \Sentry\Metrics\Unit; ); ``` +```csharp {tabTitle: .NET} +SentrySdk.Metrics.Distribution("api.latency", responseTimeMs, + unit: MeasurementUnit.Duration.Millisecond) + .Tag("endpoint", "/api/orders") + .Tag("method", "POST"); + +SentrySdk.Metrics.Distribution("db.query_time", queryDurationMs, + unit: MeasurementUnit.Duration.Millisecond) + .Tag("table", "orders") + .Tag("operation", "select"); +``` + +```ruby {tabTitle: Ruby} +Sentry.metrics.distribution('api.latency', response_time_ms, + unit: 'millisecond', + tags: { endpoint: '/api/orders', method: 'POST' } +) + +Sentry.metrics.distribution('db.query_time', query_duration_ms, + unit: 'millisecond', + tags: { table: 'orders', operation: 'select' } +) +``` + +```dart {tabTitle: Flutter} +Sentry.metrics.distribution('api.latency', responseTimeMs, + unit: SentryMeasurementUnit.duration(SentryDurationUnit.milliSecond), + attributes: {'endpoint': '/api/orders', 'method': 'POST'}, +); + +Sentry.metrics.distribution('db.query_time', queryDurationMs, + unit: SentryMeasurementUnit.duration(SentryDurationUnit.milliSecond), + attributes: {'table': 'orders', 'operation': 'select'}, +); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.metrics.distribution(key: "api.latency", value: responseTimeMs, + unit: .millisecond, + attributes: ["endpoint": "/api/orders", "method": "POST"] +) + +SentrySDK.metrics.distribution(key: "db.query_time", value: queryDurationMs, + unit: .millisecond, + attributes: ["table": "orders", "operation": "select"] +) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry +import io.sentry.metrics.MetricsUnit + +Sentry.metrics().distribution("api.latency", responseTimeMs, + MetricsUnit.Duration.MILLISECOND) + +Sentry.metrics().distribution("db.query_time", queryDurationMs, + MetricsUnit.Duration.MILLISECOND) +``` + **Explore in Sentry:** View `p95(api.latency)` grouped by `endpoint` to find slow routes. ### 5. Business Values @@ -270,6 +540,66 @@ use \Sentry\Metrics\Unit; ); ``` +```csharp {tabTitle: .NET} +SentrySdk.Metrics.Distribution("order.amount", order.TotalUsd, + unit: MeasurementUnit.Custom("usd")) + .Tag("user_tier", "premium") + .Tag("region", "us-west"); + +SentrySdk.Metrics.Distribution("upload.size", fileSizeBytes, + unit: MeasurementUnit.Information.Byte) + .Tag("file_type", "image") + .Tag("source", "profile-update"); +``` + +```ruby {tabTitle: Ruby} +Sentry.metrics.distribution('order.amount', order.total_usd, + unit: 'usd', + tags: { user_tier: 'premium', region: 'us-west' } +) + +Sentry.metrics.distribution('upload.size', file_size_bytes, + unit: 'byte', + tags: { file_type: 'image', source: 'profile-update' } +) +``` + +```dart {tabTitle: Flutter} +Sentry.metrics.distribution('order.amount', order.totalUsd, + unit: SentryMeasurementUnit.custom('usd'), + attributes: {'user_tier': 'premium', 'region': 'us-west'}, +); + +Sentry.metrics.distribution('upload.size', fileSizeBytes.toDouble(), + unit: SentryMeasurementUnit.information(SentryInformationUnit.byte), + attributes: {'file_type': 'image', 'source': 'profile-update'}, +); +``` + +```swift {tabTitle: Swift} +import Sentry + +SentrySDK.metrics.distribution(key: "order.amount", value: order.totalUsd, + unit: .generic("usd"), + attributes: ["user_tier": "premium", "region": "us-west"] +) + +SentrySDK.metrics.distribution(key: "upload.size", value: Double(fileSizeBytes), + unit: .byte, + attributes: ["file_type": "image", "source": "profile-update"] +) +``` + +```kotlin {tabTitle: Kotlin} +import io.sentry.Sentry +import io.sentry.metrics.MetricsUnit + +Sentry.metrics().distribution("order.amount", order.totalUsd) + +Sentry.metrics().distribution("upload.size", fileSizeBytes.toDouble(), + MetricsUnit.Information.BYTE) +``` + **Explore in Sentry:** View `avg(order.amount)` grouped by `region` to compare regional performance. {/* @@ -286,7 +616,7 @@ use \Sentry\Metrics\Unit; 5. Configure notification channels and save Learn about [creating alerts](/product/new-monitors-and-alerts/alerts/) and best practices for [reducing noise and routing notifications](/product/new-monitors-and-alerts/alerts/best-practices/). -\*/} +*/} ## Alerts and Dashboard Widgets From d93b66886bcd5c55e0b4a1b5255aee481e7f3a8c Mon Sep 17 00:00:00 2001 From: paulj Date: Wed, 18 Feb 2026 15:43:01 -0500 Subject: [PATCH 15/21] fix(metrics): Add 'guides' to PageType to match productSidebarItems PageType documents that it matches productSidebarItems in sidebarNavigation.tsx, but 'guides' was missing after the guides section was added. Visits to /guides/ pages were still recorded with page_type 'guides' via an unsafe cast, so metrics received an undocumented value. Add 'guides' to the union so type and docs stay in sync. Co-Authored-By: Claude Co-authored-by: Cursor --- src/metrics.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/metrics.ts b/src/metrics.ts index 92dbeec10edb3..9ec480d581390 100644 --- a/src/metrics.ts +++ b/src/metrics.ts @@ -143,6 +143,7 @@ export const DocMetrics = { */ export type PageType = // Main product docs (from productSidebarItems in sidebarNavigation.tsx) + | 'guides' // Guides | 'account' // Account Settings | 'organization' // Organization Settings | 'product' // Product Walkthroughs From a46e3393403e8a8cd46c3c562e923dbc23c77747 Mon Sep 17 00:00:00 2001 From: Paul Jaffre Date: Thu, 19 Feb 2026 11:37:56 -0500 Subject: [PATCH 16/21] Apply suggestions from code review Co-authored-by: Shannon Anahata --- docs/guides/custom-spans.mdx | 2 +- docs/guides/logs.mdx | 4 ++-- docs/guides/metrics.mdx | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/guides/custom-spans.mdx b/docs/guides/custom-spans.mdx index 91274f6d9e8c1..d293115e91c39 100644 --- a/docs/guides/custom-spans.mdx +++ b/docs/guides/custom-spans.mdx @@ -87,7 +87,7 @@ span.finish() transaction.finish() ``` -Numeric attributes become metrics you can aggregate with `sum()`, `avg()`, `p90()` in Trace Explorer. +Numeric attributes become metrics you can aggregate with `sum()`, `avg()`, `p90()` in [Trace Explorer](https://sentry.io/orgredirect/organizations/:orgslug/explore/traces/). ## Where to Add Spans diff --git a/docs/guides/logs.mdx b/docs/guides/logs.mdx index c2f7eb0708f42..579a5417d1d34 100644 --- a/docs/guides/logs.mdx +++ b/docs/guides/logs.mdx @@ -27,7 +27,7 @@ logger.(message, attribute=value) using Sentry; SentrySdk.Logger.(message); ``` - +Logs in Sentry are automatically trace-connected. Each log shows a trace ID that links to the full [trace view](/concepts/key-terms/tracing/#traces-to-trace-view). ```ruby {tabTitle: Ruby} Sentry.logger.(message) ``` @@ -338,7 +338,7 @@ Sentry.logger().error("Payment failed orderId=%s gateway=%s errorCode=%s", ### 3. External APIs and Async Operations -Traces capture what your code does. Logs capture context about external triggers and async boundaries. Things like webhooks, scheduled tasks, and third-party API responses that traces can't automatically instrument. +Traces capture what your code does. Logs capture context about external triggers and async boundaries. These are things like webhooks, scheduled tasks, and third-party API responses that traces can't automatically instrument. ```javascript {tabTitle: JavaScript} // Third-party API call diff --git a/docs/guides/metrics.mdx b/docs/guides/metrics.mdx index 53cf3cec94eed..c7be39a80ceb5 100644 --- a/docs/guides/metrics.mdx +++ b/docs/guides/metrics.mdx @@ -173,7 +173,7 @@ Sentry.metrics().count("checkout.failed", 1.0) **Explore in Sentry:** -1. Go to **Explore > Metrics** +1. Go to [**Explore > Metrics**](https://sentry.io/orgredirect/organizations/:orgslug/explore/metrics/) 2. Select `checkout.failed`, set **Aggregate** to `sum` 3. **Group by** `failure_reason` 4. Click **Samples** to see individual events and their traces From f0133c0575aff7e96e390e6dd2b52c36bc75f84d Mon Sep 17 00:00:00 2001 From: paulj Date: Thu, 19 Feb 2026 13:36:07 -0500 Subject: [PATCH 17/21] more updates --- docs/guides/custom-spans.mdx | 10 ++--- docs/guides/issues-errors.mdx | 2 +- docs/guides/logs.mdx | 54 ++++++++++++++++++++--- docs/guides/metrics.mdx | 16 +++---- docs/guides/querying-traces.mdx | 12 ++--- src/components/imageLightbox/index.tsx | 9 ++-- src/components/platformSelector/index.tsx | 4 +- src/types/platform.tsx | 6 +-- 8 files changed, 78 insertions(+), 35 deletions(-) diff --git a/docs/guides/custom-spans.mdx b/docs/guides/custom-spans.mdx index d293115e91c39..19c35579cc11b 100644 --- a/docs/guides/custom-spans.mdx +++ b/docs/guides/custom-spans.mdx @@ -8,7 +8,7 @@ You've got your Sentry SDK [auto-instrumentation](/product/explore/trace-explore Auto-instrumentation captures HTTP, database, and framework operations. But it can't see business logic, third-party APIs without auto-instrumentation, or background jobs. This guide shows you where to add custom spans to fill in those gaps. -## The Pattern +## Anatomy of a Span ```javascript {tabTitle: JavaScript} Sentry.startSpan({ name: "operation-name", op: "category" }, async (span) => { @@ -201,7 +201,7 @@ createOrder() transaction.finish() ``` -**Query in Explore > Traces:** `span.op:user.action` grouped by `user.tier`, visualize `p90(span.duration)`. +**Query in [Explore > Traces](https://sentry.io/orgredirect/organizations/:orgslug/explore/traces/):** `span.op:user.action` grouped by `user.tier`, visualize `p90(span.duration)`. **Alert idea:** `p90(span.duration) > 10s` for checkout flows. @@ -336,7 +336,7 @@ transaction.setData("response.timeMs", System.currentTimeMillis() - start) transaction.finish() ``` -**Query in Explore > Traces:** `span.op:http.client response.timeMs:>2000` to find slow external calls. +**Query in [Explore > Traces](https://sentry.io/orgredirect/organizations/:orgslug/explore/traces/):** `span.op:http.client response.timeMs:>2000` to find slow external calls. **Alert idea:** `p95(span.duration) > 3s` where `http.url` contains your critical dependencies. @@ -455,7 +455,7 @@ transaction.finish() **Why this matters:** Without these attributes, you see "a database query took 2 seconds." With them, you know it was aggregating 30 days of data and returned 50,000 rows. That's actionable. -**Query ideas in Explore > Traces:** +**Query ideas in [Explore > Traces](https://sentry.io/orgredirect/organizations/:orgslug/explore/traces/):** - "Which aggregation queries are slowest?" Group by `query.type`, sort by `p90(span.duration)` - "Does date range affect performance?" Filter by name, group by `query.dateRange` @@ -632,7 +632,7 @@ fun processEmailDigest(job: Job) { } ``` -**Query in Explore > Traces:** `span.op:queue.process` grouped by `job.type`, visualize `p90(span.duration)`. +**Query in [Explore > Traces](https://sentry.io/orgredirect/organizations/:orgslug/explore/traces/):** `span.op:queue.process` grouped by `job.type`, visualize `p90(span.duration)`. **Alert idea:** `p90(span.duration) > 60s` for queue processing. diff --git a/docs/guides/issues-errors.mdx b/docs/guides/issues-errors.mdx index 66189dca749c0..29b871423cf7e 100644 --- a/docs/guides/issues-errors.mdx +++ b/docs/guides/issues-errors.mdx @@ -6,7 +6,7 @@ description: "Practical guidance on what errors to catch, how to search issues, Your Sentry SDK is sending errors to [Sentry Issues](/product/issues/) out of the box. Now what? This guide covers the high-value error patterns that help you catch problems before they impact users and fix issues faster. -## The Pattern +## Anatomy of an Error Sentry automatically captures unhandled errors. For handled errors, use `captureException()` and add context: diff --git a/docs/guides/logs.mdx b/docs/guides/logs.mdx index 579a5417d1d34..17a7e159a2e80 100644 --- a/docs/guides/logs.mdx +++ b/docs/guides/logs.mdx @@ -6,7 +6,7 @@ description: "Practical guidance on what to log, how to search logs, and when to You've set up [Sentry Logs](/product/explore/logs/). Now what? This guide covers the high-value logging patterns that help you debug faster and catch problems before users report them. -## The Pattern +## Anatomy of a Log Every structured log follows the same format: @@ -27,7 +27,9 @@ logger.(message, attribute=value) using Sentry; SentrySdk.Logger.(message); ``` + Logs in Sentry are automatically trace-connected. Each log shows a trace ID that links to the full [trace view](/concepts/key-terms/tracing/#traces-to-trace-view). + ```ruby {tabTitle: Ruby} Sentry.logger.(message) ``` @@ -137,12 +139,14 @@ Start with these five areas and you'll catch most issues before users do. Login flows are invisible until something breaks. Log successes and failures to spot patterns like brute force attempts, OAuth misconfigurations, or MFA issues. ```javascript {tabTitle: JavaScript} +// After successful authentication Sentry.logger.info("User logged in", { userId: user.id, authMethod: "oauth", provider: "google", }); +// After authentication fails Sentry.logger.warn("Login failed", { email: maskedEmail, reason: "invalid_password", @@ -153,12 +157,14 @@ Sentry.logger.warn("Login failed", { ```python {tabTitle: Python} from sentry_sdk import logger as sentry_logger +# After successful authentication sentry_logger.info("User logged in", user_id=user.id, auth_method="oauth", provider="google" ) +# After authentication fails sentry_logger.warning("Login failed", email=masked_email, reason="invalid_password", @@ -167,12 +173,14 @@ sentry_logger.warning("Login failed", ``` ```php {tabTitle: PHP} +// After successful authentication \Sentry\logger()->info('User logged in', attributes: [ 'user_id' => $user->id, 'auth_method' => 'oauth', 'provider' => 'google', ]); +// After authentication fails \Sentry\logger()->warn('Login failed', attributes: [ 'email' => $maskedEmail, 'reason' => 'invalid_password', @@ -181,11 +189,13 @@ sentry_logger.warning("Login failed", ``` ```csharp {tabTitle: .NET} +// After successful authentication SentrySdk.Logger.Info("User logged in", logger => logger .SetAttribute("userId", user.Id) .SetAttribute("authMethod", "oauth") .SetAttribute("provider", "google")); +// After authentication fails SentrySdk.Logger.Warning("Login failed", logger => logger .SetAttribute("email", maskedEmail) .SetAttribute("reason", "invalid_password") @@ -193,12 +203,14 @@ SentrySdk.Logger.Warning("Login failed", logger => logger ``` ```ruby {tabTitle: Ruby} +# After successful authentication Sentry.logger.info('User logged in', user_id: user.id, auth_method: 'oauth', provider: 'google' ) +# After authentication fails Sentry.logger.warn('Login failed', email: masked_email, reason: 'invalid_password', @@ -207,12 +219,14 @@ Sentry.logger.warn('Login failed', ``` ```dart {tabTitle: Flutter} +// After successful authentication Sentry.logger.info('User logged in', attributes: { 'userId': user.id, 'authMethod': 'oauth', 'provider': 'google', }); +// After authentication fails Sentry.logger.warn('Login failed', attributes: { 'email': maskedEmail, 'reason': 'invalid_password', @@ -223,12 +237,14 @@ Sentry.logger.warn('Login failed', attributes: { ```swift {tabTitle: Swift} import Sentry +// After successful authentication SentrySDK.logger.info("User logged in", attributes: [ "userId": user.id, "authMethod": "oauth", "provider": "google" ]) +// After authentication fails SentrySDK.logger.warn("Login failed", attributes: [ "email": maskedEmail, "reason": "invalid_password", @@ -239,12 +255,14 @@ SentrySDK.logger.warn("Login failed", attributes: [ ```kotlin {tabTitle: Kotlin} import io.sentry.Sentry +// After successful authentication Sentry.logger().info("User logged in userId=%s authMethod=%s", user.id, "oauth") +// After authentication fails Sentry.logger().warn("Login failed email=%s reason=%s", maskedEmail, "invalid_password") ``` -**Search in Sentry:** `userId:123 "logged in"` or `severity:warn authMethod:*` +**Query in [Explore > Logs](https://sentry.io/orgredirect/organizations/:orgslug/explore/logs/):** `userId:123 "logged in"` or `severity:warn authMethod:*` **Alert idea:** Alert when `severity:warn "Login failed"` spikes in a 5-minute window—this can indicate brute force attempts or auth provider issues. @@ -253,6 +271,7 @@ Sentry.logger().warn("Login failed email=%s reason=%s", maskedEmail, "invalid_pa Money paths need visibility even when they succeed. When payments fail, you need context fast. ```javascript {tabTitle: JavaScript} +// After payment gateway returns an error Sentry.logger.error("Payment failed", { orderId: "order_123", amount: 99.99, @@ -265,6 +284,7 @@ Sentry.logger.error("Payment failed", { ```python {tabTitle: Python} from sentry_sdk import logger as sentry_logger +# After payment gateway returns an error sentry_logger.error("Payment failed", order_id="order_123", amount=99.99, @@ -275,6 +295,7 @@ sentry_logger.error("Payment failed", ``` ```php {tabTitle: PHP} +// After payment gateway returns an error \Sentry\logger()->error('Payment failed', attributes: [ 'order_id' => 'order_123', 'amount' => 99.99, @@ -285,6 +306,7 @@ sentry_logger.error("Payment failed", ``` ```csharp {tabTitle: .NET} +// After payment gateway returns an error SentrySdk.Logger.Error("Payment failed", logger => logger .SetAttribute("orderId", "order_123") .SetAttribute("amount", 99.99) @@ -294,6 +316,7 @@ SentrySdk.Logger.Error("Payment failed", logger => logger ``` ```ruby {tabTitle: Ruby} +# After payment gateway returns an error Sentry.logger.error('Payment failed', order_id: 'order_123', amount: 99.99, @@ -304,6 +327,7 @@ Sentry.logger.error('Payment failed', ``` ```dart {tabTitle: Flutter} +// After payment gateway returns an error Sentry.logger.error('Payment failed', attributes: { 'orderId': 'order_123', 'amount': 99.99, @@ -316,6 +340,7 @@ Sentry.logger.error('Payment failed', attributes: { ```swift {tabTitle: Swift} import Sentry +// After payment gateway returns an error SentrySDK.logger.error("Payment failed", attributes: [ "orderId": "order_123", "amount": 99.99, @@ -328,11 +353,12 @@ SentrySDK.logger.error("Payment failed", attributes: [ ```kotlin {tabTitle: Kotlin} import io.sentry.Sentry +// After payment gateway returns an error Sentry.logger().error("Payment failed orderId=%s gateway=%s errorCode=%s", "order_123", "stripe", "card_declined") ``` -**Search in Sentry:** `orderId:order_123` or `severity:error gateway:stripe` +**Query in [Explore > Logs](https://sentry.io/orgredirect/organizations/:orgslug/explore/logs/):** `orderId:order_123` or `severity:error gateway:stripe` **Alert idea:** Alert when `severity:error gateway:*` spikes—this can indicate payment provider outages. @@ -498,7 +524,7 @@ Sentry.logger().info("Webhook received source=%s eventType=%s", "stripe", "payment_intent.succeeded") ``` -**Search in Sentry:** `service:shipping-provider durationMs:>2000` or `source:stripe` +**Query in [Explore > Logs](https://sentry.io/orgredirect/organizations/:orgslug/explore/logs/):** `service:shipping-provider durationMs:>2000` or `source:stripe` **Alert idea:** Alert when `service:* durationMs:>3000` to catch third-party slowdowns before they cascade. @@ -507,6 +533,7 @@ Sentry.logger().info("Webhook received source=%s eventType=%s", Jobs run outside the request context. Without logs, failed jobs are invisible until someone notices missing data. ```javascript {tabTitle: JavaScript} +// Inside background job handler Sentry.logger.info("Job started", { jobType: "email-digest", jobId: "job_456", @@ -524,6 +551,7 @@ Sentry.logger.error("Job failed", { ```python {tabTitle: Python} from sentry_sdk import logger as sentry_logger +# Inside background job handler sentry_logger.info("Job started", job_type="email-digest", job_id="job_456", @@ -539,6 +567,7 @@ sentry_logger.error("Job failed", ``` ```php {tabTitle: PHP} +// Inside background job handler \Sentry\logger()->info('Job started', attributes: [ 'job_type' => 'email-digest', 'job_id' => 'job_456', @@ -554,6 +583,7 @@ sentry_logger.error("Job failed", ``` ```csharp {tabTitle: .NET} +// Inside background job handler SentrySdk.Logger.Info("Job started", logger => logger .SetAttribute("jobType", "email-digest") .SetAttribute("jobId", "job_456") @@ -567,6 +597,7 @@ SentrySdk.Logger.Error("Job failed", logger => logger ``` ```ruby {tabTitle: Ruby} +# Inside background job handler Sentry.logger.info('Job started', job_type: 'email-digest', job_id: 'job_456', @@ -582,6 +613,7 @@ Sentry.logger.error('Job failed', ``` ```dart {tabTitle: Flutter} +// Inside background job handler Sentry.logger.info('Job started', attributes: { 'jobType': 'email-digest', 'jobId': 'job_456', @@ -599,6 +631,7 @@ Sentry.logger.error('Job failed', attributes: { ```swift {tabTitle: Swift} import Sentry +// Inside background job handler SentrySDK.logger.info("Job started", attributes: [ "jobType": "email-digest", "jobId": "job_456", @@ -616,6 +649,7 @@ SentrySDK.logger.error("Job failed", attributes: [ ```kotlin {tabTitle: Kotlin} import io.sentry.Sentry +// Inside background job handler Sentry.logger().info("Job started jobType=%s jobId=%s queue=%s", "email-digest", "job_456", "notifications") @@ -623,7 +657,7 @@ Sentry.logger().error("Job failed jobType=%s jobId=%s retryCount=%d", "email-digest", "job_456", 3) ``` -**Search in Sentry:** `jobType:email-digest severity:error` +**Query in [Explore > Logs](https://sentry.io/orgredirect/organizations/:orgslug/explore/logs/):** `jobType:email-digest severity:error` **Alert idea:** Alert when `severity:error jobType:*` spikes—this can indicate queue processing issues or downstream failures. @@ -632,6 +666,7 @@ Sentry.logger().error("Job failed jobType=%s jobId=%s retryCount=%d", When something breaks after a deploy, the first question is "what changed?" Logging flag evaluations and config reloads gives you that answer instantly. ```javascript {tabTitle: JavaScript} +// When feature flag is checked or config changes Sentry.logger.info("Feature flag evaluated", { flag: "new-checkout-flow", enabled: true, @@ -647,6 +682,7 @@ Sentry.logger.warn("Config reloaded", { ```python {tabTitle: Python} from sentry_sdk import logger as sentry_logger +# When feature flag is checked or config changes sentry_logger.info("Feature flag evaluated", flag="new-checkout-flow", enabled=True, @@ -660,6 +696,7 @@ sentry_logger.warning("Config reloaded", ``` ```php {tabTitle: PHP} +// When feature flag is checked or config changes \Sentry\logger()->info('Feature flag evaluated', attributes: [ 'flag' => 'new-checkout-flow', 'enabled' => true, @@ -673,6 +710,7 @@ sentry_logger.warning("Config reloaded", ``` ```csharp {tabTitle: .NET} +// When feature flag is checked or config changes SentrySdk.Logger.Info("Feature flag evaluated", logger => logger .SetAttribute("flag", "new-checkout-flow") .SetAttribute("enabled", true) @@ -684,6 +722,7 @@ SentrySdk.Logger.Warning("Config reloaded", logger => logger ``` ```ruby {tabTitle: Ruby} +# When feature flag is checked or config changes Sentry.logger.info('Feature flag evaluated', flag: 'new-checkout-flow', enabled: true, @@ -697,6 +736,7 @@ Sentry.logger.warn('Config reloaded', ``` ```dart {tabTitle: Flutter} +// When feature flag is checked or config changes Sentry.logger.info('Feature flag evaluated', attributes: { 'flag': 'new-checkout-flow', 'enabled': true, @@ -712,6 +752,7 @@ Sentry.logger.warn('Config reloaded', attributes: { ```swift {tabTitle: Swift} import Sentry +// When feature flag is checked or config changes SentrySDK.logger.info("Feature flag evaluated", attributes: [ "flag": "new-checkout-flow", "enabled": true, @@ -727,13 +768,14 @@ SentrySDK.logger.warn("Config reloaded", attributes: [ ```kotlin {tabTitle: Kotlin} import io.sentry.Sentry +// When feature flag is checked or config changes Sentry.logger().info("Feature flag evaluated flag=%s enabled=%b userId=%s", "new-checkout-flow", true, user.id) Sentry.logger().warn("Config reloaded reason=%s", "env-change") ``` -**Search in Sentry:** `flag:new-checkout-flow` or `"Config reloaded"` +**Query in [Explore > Logs](https://sentry.io/orgredirect/organizations/:orgslug/explore/logs/):** `flag:new-checkout-flow` or `"Config reloaded"` ## Creating Alerts From Logs diff --git a/docs/guides/metrics.mdx b/docs/guides/metrics.mdx index c7be39a80ceb5..9bf5a0c792814 100644 --- a/docs/guides/metrics.mdx +++ b/docs/guides/metrics.mdx @@ -6,7 +6,7 @@ description: "Practical guidance on what metrics to track, how to explore them, You've set up [Sentry Metrics](/product/explore/metrics/). Now what? This guide covers the high-value metric patterns that give you visibility into application health and how to drill into traces when something looks off. -## The Pattern +## Anatomy of a Metric Sentry supports three metric types: @@ -16,7 +16,7 @@ Sentry supports three metric types: | **Gauge** | `Sentry.metrics.gauge()` | Current state (queue depth, connections) | | **Distribution** | `Sentry.metrics.distribution()` | Values that vary (latency, sizes, amounts) | -Every metric is trace-connected. When a metric spikes, click into samples to see the exact trace that produced it. +Every metric is trace-connected. When a metric spikes, click into samples to see the exact [trace](/concepts/key-terms/tracing/trace-view/) that produced it. ```javascript {tabTitle: JavaScript} Sentry.metrics.count("checkout.failed", 1, { @@ -298,7 +298,7 @@ Sentry.metrics().count("email.failed", 1.0) Sentry.metrics().count("job.processed", 1.0) ``` -**Explore in Sentry:** Add both `email.sent` and `email.failed`, group by `email_type`, compare the ratio. +**Query in [Explore > Metrics](https://sentry.io/orgredirect/organizations/:orgslug/explore/metrics/):** Add both `email.sent` and `email.failed`, group by `email_type`, compare the ratio. ### 3. Resource Utilization @@ -387,7 +387,7 @@ Sentry.metrics().gauge("queue.depth", queue.size.toDouble()) Sentry.metrics().gauge("pool.connections_active", pool.activeConnections.toDouble()) ``` -**Explore in Sentry:** View `max(queue.depth)` over time to spot backlogs. +**Query in [Explore > Metrics](https://sentry.io/orgredirect/organizations/:orgslug/explore/metrics/):** View `max(queue.depth)` over time to spot backlogs. ### 4. Latency and Performance @@ -494,7 +494,7 @@ Sentry.metrics().distribution("db.query_time", queryDurationMs, MetricsUnit.Duration.MILLISECOND) ``` -**Explore in Sentry:** View `p95(api.latency)` grouped by `endpoint` to find slow routes. +**Query in [Explore > Metrics](https://sentry.io/orgredirect/organizations/:orgslug/explore/metrics/):** View `p95(api.latency)` grouped by `endpoint` to find slow routes. ### 5. Business Values @@ -600,9 +600,9 @@ Sentry.metrics().distribution("upload.size", fileSizeBytes.toDouble(), MetricsUnit.Information.BYTE) ``` -**Explore in Sentry:** View `avg(order.amount)` grouped by `region` to compare regional performance. +**Query in [Explore > Metrics](https://sentry.io/orgredirect/organizations/:orgslug/explore/metrics/):** View `avg(order.amount)` grouped by `region` to compare regional performance. -{/* +{/\* ## Creating Alerts From Metrics @@ -616,7 +616,7 @@ Sentry.metrics().distribution("upload.size", fileSizeBytes.toDouble(), 5. Configure notification channels and save Learn about [creating alerts](/product/new-monitors-and-alerts/alerts/) and best practices for [reducing noise and routing notifications](/product/new-monitors-and-alerts/alerts/best-practices/). -*/} +\*/} ## Alerts and Dashboard Widgets diff --git a/docs/guides/querying-traces.mdx b/docs/guides/querying-traces.mdx index 7716a78cf6b9e..4c4ad88f1c095 100644 --- a/docs/guides/querying-traces.mdx +++ b/docs/guides/querying-traces.mdx @@ -6,6 +6,8 @@ description: "Find performance issues using data Sentry captures automatically a You've enabled [Sentry Tracing](/product/explore/trace-explorer/). Now what? Sentry's auto-instrumentation captures a lot without custom code. This guide shows you how to query that data to find performance issues. + + ## What's Auto-Instrumented With `browserTracingIntegration()` enabled, Sentry automatically captures: @@ -21,7 +23,7 @@ Start with these five queries and you'll catch most performance issues before us ### 1. Slow Page Loads: Pages taking too long to become interactive hurt first impressions -**Query in Explore > Traces:** `span.op:pageload` & **Visualize:** `p90(span.duration)` grouped by `transaction` to compare routes. +**Query in [Explore > Traces](https://sentry.io/orgredirect/organizations/:orgslug/explore/traces/):** `span.op:pageload` & **Visualize:** `p90(span.duration)` grouped by `transaction` to compare routes. - **What to look for:** Routes with p90 over 3 seconds. Explore sample traces to see the breakdown. Usually it's slow API calls, heavy JavaScript, or large images. @@ -29,7 +31,7 @@ Start with these five queries and you'll catch most performance issues before us ### 2. Slow API Calls: Fetch/XHR requests are often the bottleneck in modern web apps -**Query in Explore > Traces:** `span.op:http.client` & **Visualize:** `avg(span.duration)` grouped by `span.description` (the URL). +**Query in [Explore > Traces](https://sentry.io/orgredirect/organizations/:orgslug/explore/traces/):** `span.op:http.client` & **Visualize:** `avg(span.duration)` grouped by `span.description` (the URL). - **What to look for:** Endpoints with avg duration over 1 second or p95 over 2 seconds. Check if it's the backend or network latency by looking at sample traces. @@ -37,7 +39,7 @@ Start with these five queries and you'll catch most performance issues before us ### 3. JavaScript Blocking the UI: Long animation frames mean JavaScript execution is freezing the interface -**Query in Explore > Traces:** `span.op:ui.long-animation-frame` & **Visualize:** Sort by `span.duration` to find the worst offenders. +**Query in [Explore > Traces](https://sentry.io/orgredirect/organizations/:orgslug/explore/traces/):** `span.op:ui.long-animation-frame` & **Visualize:** Sort by `span.duration` to find the worst offenders. - **What to look for:** Frames over 200ms. This is what causes jank and unresponsiveness. Look at the stack trace in sample traces to find the expensive operation. @@ -45,7 +47,7 @@ Start with these five queries and you'll catch most performance issues before us ### 4. Slow SPA Navigation: After the initial load, how fast do users move between pages? -**Query in Explore > Traces:** `span.op:navigation` & **Visualize:** `p90(span.duration)` grouped by `transaction` to compare route performance. +**Query in [Explore > Traces](https://sentry.io/orgredirect/organizations/:orgslug/explore/traces/):** `span.op:navigation` & **Visualize:** `p90(span.duration)` grouped by `transaction` to compare route performance. - **What to look for:** Navigation over 1 second feels sluggish. Click into traces to see if it's data fetching, component rendering, or something else. @@ -53,7 +55,7 @@ Start with these five queries and you'll catch most performance issues before us ### 5. Heavy Resources: Large JS bundles, stylesheets, or images slowing down your site -**Query in Explore > Traces:** `span.op:resource.script` (JavaScript), `span.op:resource.css` (stylesheets), or `span.op:resource.img` (images) & **Visualize:** `avg(span.duration)` to find the heaviest assets. +**Query in [Explore > Traces](https://sentry.io/orgredirect/organizations/:orgslug/explore/traces/):** `span.op:resource.script` (JavaScript), `span.op:resource.css` (stylesheets), or `span.op:resource.img` (images) & **Visualize:** `avg(span.duration)` to find the heaviest assets. - **What to look for:** Resources taking over 1 second. Check the span description to see which files. Often it's third-party scripts or unoptimized images. diff --git a/src/components/imageLightbox/index.tsx b/src/components/imageLightbox/index.tsx index a0c82a73feb2a..3ebff606c177a 100644 --- a/src/components/imageLightbox/index.tsx +++ b/src/components/imageLightbox/index.tsx @@ -6,10 +6,11 @@ import Image from 'next/image'; import {Lightbox} from 'sentry-docs/components/lightbox'; import {isAllowedRemoteImage, isExternalImage} from 'sentry-docs/config/images'; -interface ImageLightboxProps extends Omit< - React.HTMLProps, - 'ref' | 'src' | 'width' | 'height' | 'alt' -> { +interface ImageLightboxProps + extends Omit< + React.HTMLProps, + 'ref' | 'src' | 'width' | 'height' | 'alt' + > { alt: string; imgPath: string; src: string; diff --git a/src/components/platformSelector/index.tsx b/src/components/platformSelector/index.tsx index a6fc0375ced35..e578b2fe5b794 100644 --- a/src/components/platformSelector/index.tsx +++ b/src/components/platformSelector/index.tsx @@ -140,8 +140,8 @@ export function PlatformSelector({ const isPlatformPage = Boolean( pathname?.startsWith('/platforms/') && - // /platforms/something - pathname.length > '/platforms/'.length + // /platforms/something + pathname.length > '/platforms/'.length ); // Only show stored platform after mount to prevent hydration mismatch // Server doesn't have localStorage, so this must wait until client-side diff --git a/src/types/platform.tsx b/src/types/platform.tsx index bb58fddd9eebb..a980badcc893e 100644 --- a/src/types/platform.tsx +++ b/src/types/platform.tsx @@ -37,10 +37,8 @@ export interface Platform extends PlatformConfig { * Guide inherits most fields from {@link Platform} object, but it is not quite * the same thing as a platform. */ -export interface PlatformGuide extends Omit< - Platform, - 'guides' | 'integrations' | 'type' -> { +export interface PlatformGuide + extends Omit { /** * The key is the fully qualified name of the guide: `${platformKey}.${guideName}` */ From f60ef2c4532e70d4fbbb04be257df37c63e8493f Mon Sep 17 00:00:00 2001 From: paulj Date: Thu, 19 Feb 2026 13:57:34 -0500 Subject: [PATCH 18/21] add next steps to product walkthru pages --- docs/guides/custom-spans.mdx | 4 ++++ docs/guides/issues-errors.mdx | 4 ++++ docs/guides/logs.mdx | 4 ++++ docs/guides/metrics.mdx | 3 --- docs/guides/querying-traces.mdx | 4 ++++ docs/guides/session-replay.mdx | 4 ++++ 6 files changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/guides/custom-spans.mdx b/docs/guides/custom-spans.mdx index 19c35579cc11b..7bf53290f01cb 100644 --- a/docs/guides/custom-spans.mdx +++ b/docs/guides/custom-spans.mdx @@ -760,3 +760,7 @@ transaction.finish() | Database | `db.query` | query.type, result.rowCount | | Background jobs | `queue.process` | job.type, job.id, queue.name | | AI/LLM | `ai.inference` | ai.model, ai.tokens.total | + +## Next Steps + +Explore the [product walkthrough guides](/product/) to learn more about the Sentry interface and discover additional tips. diff --git a/docs/guides/issues-errors.mdx b/docs/guides/issues-errors.mdx index 29b871423cf7e..27f87685e825f 100644 --- a/docs/guides/issues-errors.mdx +++ b/docs/guides/issues-errors.mdx @@ -637,3 +637,7 @@ SentryAndroid.init(context) { options -> | New regressions | `is:unresolved` (sort by Age) | Issues that first appeared recently | | Environment issues | `environment:production` | Prod-only config or data issues | | High user impact | `is:unresolved` (sort by Users) | Issues affecting many users | + +## Next Steps + +Explore the [product walkthrough guides](/product/) to learn more about the Sentry interface and discover additional tips. diff --git a/docs/guides/logs.mdx b/docs/guides/logs.mdx index 17a7e159a2e80..20385a7ab150f 100644 --- a/docs/guides/logs.mdx +++ b/docs/guides/logs.mdx @@ -1077,3 +1077,7 @@ If you can't install the Sentry SDK or need platform-level logs (CDN, database, | External APIs | `info` | service, endpoint, durationMs | | Background jobs | `info`/`error` | jobType, jobId, retryCount | | Feature flags | `info` | flag, enabled, changedKeys | + +## Next Steps + +Explore the [product walkthrough guides](/product/) to learn more about the Sentry interface and discover additional tips. diff --git a/docs/guides/metrics.mdx b/docs/guides/metrics.mdx index 9bf5a0c792814..fe355ae04d046 100644 --- a/docs/guides/metrics.mdx +++ b/docs/guides/metrics.mdx @@ -602,8 +602,6 @@ Sentry.metrics().distribution("upload.size", fileSizeBytes.toDouble(), **Query in [Explore > Metrics](https://sentry.io/orgredirect/organizations/:orgslug/explore/metrics/):** View `avg(order.amount)` grouped by `region` to compare regional performance. -{/\* - ## Creating Alerts From Metrics 1. Go to **Explore > Metrics** @@ -616,7 +614,6 @@ Sentry.metrics().distribution("upload.size", fileSizeBytes.toDouble(), 5. Configure notification channels and save Learn about [creating alerts](/product/new-monitors-and-alerts/alerts/) and best practices for [reducing noise and routing notifications](/product/new-monitors-and-alerts/alerts/best-practices/). -\*/} ## Alerts and Dashboard Widgets diff --git a/docs/guides/querying-traces.mdx b/docs/guides/querying-traces.mdx index 4c4ad88f1c095..326d6b144bc9a 100644 --- a/docs/guides/querying-traces.mdx +++ b/docs/guides/querying-traces.mdx @@ -85,3 +85,7 @@ Learn about [creating alerts](/product/new-monitors-and-alerts/alerts/) and best | JS blocking UI | `span.op:ui.long-animation-frame` | `max(span.duration)` | | Slow SPA navigation | `span.op:navigation` | `p90(span.duration)` by transaction | | Heavy resources | `span.op:resource.*` | `avg(span.duration)` by description | + +## Next Steps + +Explore the [product walkthrough guides](/product/) to learn more about the Sentry interface and discover additional tips. diff --git a/docs/guides/session-replay.mdx b/docs/guides/session-replay.mdx index 7aa29b48548ab..cf36fb46c48c3 100644 --- a/docs/guides/session-replay.mdx +++ b/docs/guides/session-replay.mdx @@ -127,3 +127,7 @@ Be selective. Never unmask form inputs, and review your [privacy configuration]( | Dead clicks | `count_dead_clicks:>0` | | Mobile users | `device.family:iOS` | | Slow sessions | Filter by URL, watch for slow interactions | + +## Next Steps + +Explore the [product walkthrough guides](/product/) to learn more about the Sentry interface and discover additional tips. From e2ef43de107e1255f89cb851561b17ef80fb2491 Mon Sep 17 00:00:00 2001 From: paulj Date: Thu, 19 Feb 2026 13:58:39 -0500 Subject: [PATCH 19/21] fix metric alert merge wonk --- docs/guides/metrics.mdx | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/docs/guides/metrics.mdx b/docs/guides/metrics.mdx index fe355ae04d046..f20099592719b 100644 --- a/docs/guides/metrics.mdx +++ b/docs/guides/metrics.mdx @@ -602,19 +602,6 @@ Sentry.metrics().distribution("upload.size", fileSizeBytes.toDouble(), **Query in [Explore > Metrics](https://sentry.io/orgredirect/organizations/:orgslug/explore/metrics/):** View `avg(order.amount)` grouped by `region` to compare regional performance. -## Creating Alerts From Metrics - -1. Go to **Explore > Metrics** -2. Build your query (e.g., `checkout.failed` grouped by `failure_reason`) -3. Click **Save As** - **Alert** -4. Choose a threshold type: - - **Static:** Alert when count exceeds a value - - **Percent Change:** Alert when count changes relative to a previous period - - **Anomaly:** Let Sentry detect unusual patterns -5. Configure notification channels and save - -Learn about [creating alerts](/product/new-monitors-and-alerts/alerts/) and best practices for [reducing noise and routing notifications](/product/new-monitors-and-alerts/alerts/best-practices/). - ## Alerts and Dashboard Widgets From a288e360a2a38c2e36a08ea71406c44cfcaf2601 Mon Sep 17 00:00:00 2001 From: "getsantry[bot]" <66042841+getsantry[bot]@users.noreply.github.com> Date: Thu, 19 Feb 2026 18:59:41 +0000 Subject: [PATCH 20/21] [getsentry/action-github-commit] Auto commit --- src/components/imageLightbox/index.tsx | 9 ++++----- src/components/platformSelector/index.tsx | 4 ++-- src/types/platform.tsx | 6 ++++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/components/imageLightbox/index.tsx b/src/components/imageLightbox/index.tsx index 3ebff606c177a..a0c82a73feb2a 100644 --- a/src/components/imageLightbox/index.tsx +++ b/src/components/imageLightbox/index.tsx @@ -6,11 +6,10 @@ import Image from 'next/image'; import {Lightbox} from 'sentry-docs/components/lightbox'; import {isAllowedRemoteImage, isExternalImage} from 'sentry-docs/config/images'; -interface ImageLightboxProps - extends Omit< - React.HTMLProps, - 'ref' | 'src' | 'width' | 'height' | 'alt' - > { +interface ImageLightboxProps extends Omit< + React.HTMLProps, + 'ref' | 'src' | 'width' | 'height' | 'alt' +> { alt: string; imgPath: string; src: string; diff --git a/src/components/platformSelector/index.tsx b/src/components/platformSelector/index.tsx index e578b2fe5b794..a6fc0375ced35 100644 --- a/src/components/platformSelector/index.tsx +++ b/src/components/platformSelector/index.tsx @@ -140,8 +140,8 @@ export function PlatformSelector({ const isPlatformPage = Boolean( pathname?.startsWith('/platforms/') && - // /platforms/something - pathname.length > '/platforms/'.length + // /platforms/something + pathname.length > '/platforms/'.length ); // Only show stored platform after mount to prevent hydration mismatch // Server doesn't have localStorage, so this must wait until client-side diff --git a/src/types/platform.tsx b/src/types/platform.tsx index a980badcc893e..bb58fddd9eebb 100644 --- a/src/types/platform.tsx +++ b/src/types/platform.tsx @@ -37,8 +37,10 @@ export interface Platform extends PlatformConfig { * Guide inherits most fields from {@link Platform} object, but it is not quite * the same thing as a platform. */ -export interface PlatformGuide - extends Omit { +export interface PlatformGuide extends Omit< + Platform, + 'guides' | 'integrations' | 'type' +> { /** * The key is the fully qualified name of the guide: `${platformKey}.${guideName}` */ From 06a7ccbda075c3736944aefee23212348cb8c9dd Mon Sep 17 00:00:00 2001 From: paulj Date: Thu, 19 Feb 2026 14:28:53 -0500 Subject: [PATCH 21/21] cleanup --- docs/guides/logs.mdx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/guides/logs.mdx b/docs/guides/logs.mdx index 20385a7ab150f..da80fcb0c747c 100644 --- a/docs/guides/logs.mdx +++ b/docs/guides/logs.mdx @@ -779,8 +779,6 @@ Sentry.logger().warn("Config reloaded reason=%s", "env-change") ## Creating Alerts From Logs -{/* TODO: replace with Arcade */} - 1. Go to **Explore > Logs** 2. Enter your search query (e.g., `severity:error gateway:*`) 3. Click **Save As** - **Alert** @@ -887,7 +885,7 @@ SentryAndroid.init(context) { options -> } ``` -Use verbose logging levels like `debug` (development diagnostics) and `trace` (fine-grained execution details) freely in development. You can [filter these out in production](/platforms/javascript/logs/#filter-logs) using `beforeSendLog` to only capture `info` and above. +Use verbose logging levels like `debug` (development diagnostics) and `trace` (fine-grained execution details) freely in development. You can filter these out in production using beforeSendLog to only capture `info` and above. ### Production Logging