Sentry: Triage y Resolución de Errores
Dominá Sentry para el seguimiento de errores en producción. Cubre integración del SDK en Python, Node.js y Java, release tracking, source maps, performance monitoring y alertas.
Introducción
Sentry captura excepciones, crashes y problemas de performance en producción. Cuando ocurre un error, recolecta el stack trace, el contexto del request, la información del usuario y los breadcrumbs que lo precedieron. Esta guía cubre la integración del SDK en Python, Node.js y Java, el seguimiento de releases con source maps, el monitoreo de performance, reglas de alerta y un flujo de trabajo práctico para triagear y resolver issues.
Si ya conocés Sentry, podés ir directo a seguimiento de releases y source maps o a reglas de alerta.
Requisitos Previos
Antes de empezar, asegurate de tener lo siguiente:
- Una cuenta de Sentry (cloud o self-hosted). El tier gratuito cubre 5,000 errores por mes, suficiente para la mayoría de los side projects y equipos pequeños.
- El SDK de Sentry para tu lenguaje:
sentry-sdk(Python),@sentry/node(Node.js), osentry-spring(Java). Conseguilo víapip,npm, omaven. - Una integración de framework si usás una: Flask, Django, Express, Fastify, Spring Boot, o Quarkus. Sentry trae integraciones first-class para cada una.
sentry-cliinstalado globalmente si planeás hacer release tracking y upload de source maps. Instalalo connpm install -g @sentry/clio descargá el binario de la página de releases de Sentry CLI.- Un string DSN de los settings de tu proyecto en Sentry. Se ve así:
https://your-key@sentry.io/123.
Cómo Funciona Sentry
- Un error ocurre en tu aplicación.
- El SDK de Sentry captura la excepción junto con el stack trace, el contexto del request, el usuario, breadcrumbs y tags de entorno y release.
- El SDK envía el evento al servidor de Sentry.
- Sentry deduplica y agrupa errores similares en issues.
- Sentry notifica a tu equipo por Slack, email o PagerDuty.
- Un developer triagea el issue, identifica la causa raíz y deployea un fix.
- Sentry marca el issue como resuelto cuando el nuevo release deja de reportar el error.
Los source maps convierten stack traces minificados en nombres de archivo y números de línea legibles. Sin ellos, debuggear errores de frontend o Node.js empaquetado se vuelve un juego de adivinanzas.
Integración del SDK
Python: Flask/Django
# sentry_config.py — Sentry SDK para Python
import sentry_sdk
from sentry_sdk.integrations.flask import FlaskIntegration
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
from sentry_sdk.integrations.redis import RedisIntegration
from sentry_sdk.integrations.celery import CeleryIntegration
def init_sentry():
sentry_sdk.init(
dsn="https://your-dsn@sentry.io/123",
environment="production",
release="order-service@1.2.3",
# Sampleá 100% de errors, 10% de transactions para performance
traces_sample_rate=0.1,
sample_rate=1.0,
integrations=[
FlaskIntegration(),
SqlalchemyIntegration(),
RedisIntegration(),
CeleryIntegration(),
],
# Mandá PII (email, IP) — habilitá con caution
send_default_pii=True,
# Before send hook para filtrar sensitive data
before_send=filter_sensitive_data,
)
def filter_sensitive_data(event, hint):
"""Remové sensitive data antes de mandar a Sentry."""
if "request" in event:
headers = event["request"].get("headers", {})
# Remové authorization headers
for key in list(headers.keys()):
if key.lower() in ("authorization", "cookie", "x-api-key"):
headers[key] = "[REDACTED]"
# Remové sensitive body fields
body = event["request"].get("data", {})
if isinstance(body, dict):
for key in ("password", "credit_card", "ssn"):
if key in body:
body[key] = "[REDACTED]"
return event
# Manual error capture
from sentry_sdk import capture_exception, capture_message, set_user, add_breadcrumb
class OrderService:
def create_order(self, user_id: int, items: list[dict]) -> dict:
# Seteá user context
set_user({"id": str(user_id), "email": "user@example.com"})
# Agregá breadcrumbs para debugging
add_breadcrumb(
category="order",
message=f"Creating order for user {user_id} with {len(items)} items",
level="info",
)
try:
order = self._process_order(user_id, items)
add_breadcrumb(category="order", message="Order created successfully", level="info")
return order
except PaymentError as e:
# Captureá con extra context
capture_exception(e, {
"extra": {
"user_id": user_id,
"items_count": len(items),
"total_amount": sum(i["price"] * i["quantity"] for i in items),
},
"tags": {"error_type": "payment", "severity": "high"},
})
raise
except Exception as e:
capture_exception(e)
raise
Node.js: Express
// sentry.ts — Sentry SDK para Node.js
import * as Sentry from "@sentry/node";
import { nodeProfilingIntegration } from "@sentry/profiling-node";
export function initSentry() {
Sentry.init({
dsn: "https://your-dsn@sentry.io/123",
environment: process.env.NODE_ENV || "development",
release: `api-gateway@${process.env.APP_VERSION || "1.0.0"}`,
tracesSampleRate: 0.1,
profilesSampleRate: 0.1,
integrations: [
nodeProfilingIntegration(),
Sentry.httpIntegration(),
Sentry.expressIntegration(),
],
beforeSend(event) {
// Redactéa sensitive headers
if (event.request?.headers) {
delete event.request.headers.authorization;
delete event.request.headers.cookie;
}
// Redactéa sensitive body fields
if (event.request?.data && typeof event.request.data === "object") {
delete event.request.data.password;
delete event.request.data.creditCard;
}
return event;
},
});
}
// Express middleware — debe ir antes de routes
import express from "express";
const app = express();
Sentry.setupExpressErrorHandler(app);
// Manual error capture
import { captureException, setUser, addBreadcrumb } from "@sentry/node";
class OrderService {
async createOrder(userId: string, items: OrderItem[]): Promise<Order> {
Sentry.setUser({ id: userId, email: "user@example.com" });
Sentry.addBreadcrumb({
category: "order",
message: `Creating order for user ${userId} with ${items.length} items`,
level: "info",
});
try {
const order = await this.processOrder(userId, items);
Sentry.addBreadcrumb({
category: "order",
message: "Order created successfully",
level: "info",
});
return order;
} catch (error) {
Sentry.captureException(error, {
extra: {
userId,
itemCount: items.length,
totalAmount: items.reduce((sum, i) => sum + i.price * i.quantity, 0),
},
tags: { errorType: "order_creation", severity: "high" },
});
throw error;
}
}
}
// Custom error handler
app.use((err: Error, req: express.Request, res: express.Response, next: express.NextFunction) => {
Sentry.captureException(err);
res.status(500).json({ error: "Internal server error" });
});
Java: Spring Boot
// SentryConfig.java — Sentry SDK para Spring Boot
import io.sentry.Sentry;
import io.sentry.spring.tracing.SentryTracingConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SentryConfig {
@Bean
public Sentry.OptionsConfiguration sentryOptions() {
return options -> {
options.setDsn("https://your-dsn@sentry.io/123");
options.setEnvironment("production");
options.setRelease("order-service@1.2.3");
options.setTracesSampleRate(0.1);
options.setBeforeSend((event, hint) -> {
// Redactéa sensitive data
if (event.getRequest() != null) {
event.getRequest().getHeaders().remove("Authorization");
event.getRequest().getHeaders().remove("Cookie");
}
return event;
});
};
}
}
// Service code con manual capture
@Service
public class OrderService {
public Order createOrder(Long userId, List<OrderItem> items) {
Sentry.setUser(new Sentry.User(
String.valueOf(userId),
"user@example.com",
null,
null
));
Sentry.addBreadcrumb("Creating order for user " + userId, "order");
try {
Order order = processOrder(userId, items);
Sentry.addBreadcrumb("Order created successfully", "order");
return order;
} catch (PaymentException e) {
Sentry.captureException(e, Scope -> {
Scope.setExtra("user_id", userId);
Scope.setExtra("items_count", items.size());
Scope.setTag("error_type", "payment");
});
throw e;
}
}
}
Release Tracking y Source Maps
Release tracking
# Creá un Sentry release
sentry-cli releases new "order-service@1.2.3"
# Asociá commits con el release
sentry-cli releases set-commits "order-service@1.2.3" \
--auto
# Finalizá el release
sentry-cli releases finalize "order-service@1.2.3"
# Markéa deployment
sentry-cli releases deploys "order-service@1.2.3" new \
--env production \
--url "https://order-service.example.com"
Source maps para JavaScript
// webpack.config.js — Subí source maps a Sentry
const SentryWebpackPlugin = require("@sentry/webpack-plugin");
module.exports = {
devtool: "source-map",
plugins: [
new SentryWebpackPlugin({
org: "your-org",
project: "api-gateway",
authToken: process.env.SENTRY_AUTH_TOKEN,
release: "api-gateway@1.2.3",
include: "./dist",
ignore: ["node_modules", "webpack.config.js"],
// Stripéa server-side code paths
urlPrefix: "~/static/js",
}),
],
};
CI/CD integration
# .github/workflows/deploy.yml — Sentry release en CI
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- name: Create Sentry release
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
run: |
npm run build
npx sentry-cli releases new "api-gateway@${{ github.sha }}"
npx sentry-cli releases set-commits "api-gateway@${{ github.sha }}" --auto
npx sentry-cli releases files "api-gateway@${{ github.sha }}" upload-sourcemaps ./dist
npx sentry-cli releases finalize "api-gateway@${{ github.sha }}"
- name: Deploy
run: npm run deploy
- name: Mark Sentry deploy
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
run: |
npx sentry-cli releases deploys "api-gateway@${{ github.sha }}" new \
--env production
Monitoreo de Performance
# Python: Custom transactions y spans
import sentry_sdk
@sentry_sdk.trace
def process_order(user_id: int, items: list[dict]) -> dict:
with sentry_sdk.start_span(op="db", description="query_user") as span:
user = db.query(User).get(user_id)
span.set_data("user.id", user_id)
with sentry_sdk.start_span(op="http.client", description="charge_payment") as span:
payment = payment_client.charge(user_id, total)
span.set_data("payment.amount", payment["amount"])
with sentry_sdk.start_span(op="db", description="save_order") as span:
order = order_repo.create(user_id, items, payment["id"])
span.set_data("order.id", order["id"])
return order
// Node.js: Custom spans
import * as Sentry from "@sentry/node";
async function processOrder(userId: string, items: OrderItem[]): Promise<Order> {
return Sentry.startSpan({ op: "function", name: "process_order" }, async () => {
const user = await Sentry.startSpan(
{ op: "db", name: "query_user" },
async () => await userRepo.findById(userId)
);
const payment = await Sentry.startSpan(
{ op: "http.client", name: "charge_payment" },
async () => await paymentService.charge(userId, total)
);
const order = await Sentry.startSpan(
{ op: "db", name: "save_order" },
async () => await orderRepo.create({ userId, items, paymentId: payment.id })
);
return order;
});
}
Reglas de Alerta
# Sentry alert rules (configurado en Sentry UI o via API)
# Example: Alertéa en high error rate
rules:
- name: "High error rate"
conditions:
- event_level: error
- threshold: 10 # errors en 1 hour
actions:
- notify_slack: "#alerts"
- notify_email: ["oncall@company.com"]
- name: "New error in production"
conditions:
- event_level: error
- environment: production
- is_new: true
actions:
- notify_slack: "#engineering"
- create_issue: true
- name: "Performance regression"
conditions:
- metric: p95_duration
- threshold: 2000 # ms
- comparison: greater_than
actions:
- notify_slack: "#performance"
Flujo de Triage
- Recibí una alerta por Slack, email o PagerDuty.
- Abrí el issue en Sentry.
- Revisá los datos clave:
- Stack trace para identificar el código que falla.
- Breadcrumbs para entender qué llevó al error.
- Contexto de usuario para saber quién se vio afectado.
- Contexto del request para ver el input que lo disparó.
- Release tag para detectar qué versión introdujo el bug.
- Tags para filtrar por entorno, servicio y tipo de error.
- Asigná el issue a un developer.
- Vinculalo a un ticket de Jira o GitHub.
- Escribí el fix y hacé el deploy.
- Sentry detecta el fix en el nuevo release y cierra el issue si no llegan eventos en 72 horas.
No todos los issues necesitan la misma urgencia. Ordenalos por impacto: cuántos usuarios pegaron el error, con qué
frecuencia se dispara, y si bloquea un path crítico. Un error de pago que pega a 1,000 usuarios por hora es un P0. Un
glitch de CSS que afecta a 3 usuarios por semana es un P3. Las views de “frequent issues” y “regression” de Sentry te
ayudan a spottear los de alto impacto rápido. Tageá los issues con priority:p0, priority:p1, etc. así tu equipo
puede filtrar la queue por urgencia en lugar de por recency.
Buenas Prácticas
Seteá el tag release en cada deployment. Sentry lo usa para auto-resolver issues una vez que el fix está en producción.
Subí source maps para JavaScript y TypeScript minificados de forma que los stack traces apunten al código fuente real. Usá
before_send para redactar PII como contraseñas, tokens y números de tarjetas.
Seteá el contexto del usuario temprano en el ciclo del request, así sabés quién se vio afectado. Agregá breadcrumbs para
operaciones clave como consultas a base de datos, llamadas a APIs y cambios de estado. Usá tags como service,
endpoint, feature_flag y user_tier para filtrar. Si también usás el stack de Grafana para dashboards, consultá la
guía completa de Observability con Grafana. Para
structured logging que complemente la captura de errores de Sentry, revisá la
guía completa de Structured Logging. Si estás traceando requests entre
servicios, la guía completa de Distributed Tracing explica cómo
correlacionar eventos de Sentry con trace IDs.
Sampleá transacciones con criterio: 10% para servicios de alto tráfico y 100% para los de bajo tráfico. Agrupá errores similares con fingerprinting custom cuando el agrupamiento default no alcanza. Configurá alertas sobre nuevos errores para atrapar regresiones antes de que los usuarios las reporten, y filtrá por entorno para que los errores de desarrollo no lleguen al proyecto de producción.
Errores Comunes
No hacer seguimiento de releases imposibilita saber qué versión introdujo un bug. Siempre seteá release cuando
inicializás el SDK.
Sin source maps, los stack traces minificados son casi inútiles. Subí source maps como parte de tu pipeline de CI, no manualmente después del deploy.
Enviar demasiada data con sample rates altos genera ruido. Usá 10% de trace sampling para servicios de alto tráfico y subilo a 100% solo para paths críticos o de bajo volumen.
No redactar PII filtra contraseñas, tokens e información personal a Sentry. Usá el hook before_send para borrar campos
sensibles antes de que el evento salga de tu servidor.
Ignorar los breadcrumbs borra el camino hacia el error. Agregalos en operaciones importantes y mantené los mensajes lo suficientemente cortos como para escanearlos rápido.
Usar un solo proyecto de Sentry para todo mezcla errores de codebases distintos. Creá proyectos separados por servicio o equipo para que el triage sea enfocado.
Estrategias de Sampling
El sampling controla cuántas transacciones y errores recibe Sentry. Si lo configurás mal, te ahogás en ruido o te
pierdes los errores que importan. El SDK te da dos knobs: sample_rate para errores y traces_sample_rate para
transacciones.
Los errores deberían ir al 100% (sample_rate=1.0) en producción. Querés cada crash, siempre. El volumen es
naturalmente menor que el de transacciones, y perderte un error significa perderte un bug que afecta a usuarios.
Las transacciones son distintas. Una API de alto tráfico puede generar millones de transacciones por hora, y el
pricing de Sentry escala con el volumen de eventos. Seteá traces_sample_rate=0.1 (10%) para servicios de alto
tráfico. Para paths de bajo tráfico o críticos (pagos, auth, endpoints admin), subilo a 1.0 (100%) así atrapás
cada request lento.
# Sampling dinámico basado en ruta
def traces_sampler(sampling_context):
transaction = sampling_context.get("transaction_context", {})
name = transaction.get("name", "")
# 100% para paths críticos
if name.startswith("/api/payment") or name.startswith("/api/auth"):
return 1.0
# 1% para health checks y assets estáticos
if name.startswith("/health") or name.startswith("/static"):
return 0.01
# 10% para el resto
return 0.1
sentry_sdk.init(
dsn="https://your-dsn@sentry.io/123",
traces_sample_rate=0.1,
traces_sampler=traces_sampler,
)
El sampling dinámico te permite overridear el rate global por transacción. La función sampler recibe contexto sobre la transacción (name, URL, method, headers) y devuelve un rate entre 0.0 y 1.0. Esto mantiene los costos bajos en endpoints ruidosos mientras conservás visibilidad completa en los críticos.
Fingerprinting Custom
Sentry agrupa errores por similitud de stack trace. La mayoría de las veces funciona, pero algunos errores necesitan agrupamiento manual. Un timeout de base de datos lanzado desde el mismo code path pero con queries distintas se divide en docenas de issues. El fingerprinting custom lo arregla overrideando el agrupamiento default.
# Python: Fingerprint custom via before_send
def before_send(event, hint):
if "exception" in event:
exc = event["exception"]["values"][0]
# Agrupar todos los timeouts de base de datos juntos
if exc.get("type") == "TimeoutError":
event["fingerprint"] = ["database-timeout"]
# Agrupar por tipo de error y endpoint
elif exc.get("type") == "HTTPError":
endpoint = event.get("request", {}).get("url", "unknown")
event["fingerprint"] = ["http-error", endpoint]
return event
sentry_sdk.init(
dsn="https://your-dsn@sentry.io/123",
before_send=before_send,
)
// Node.js: Fingerprint custom via beforeSend
function beforeSend(event: any) {
if (event.exception?.values?.[0]) {
const exc = event.exception.values[0];
if (exc.type === "TimeoutError") {
event.fingerprint = ["database-timeout"];
} else if (exc.type === "HTTPError") {
const endpoint = event.request?.url || "unknown";
event.fingerprint = ["http-error", endpoint];
}
}
return event;
}
Sentry.init({
dsn: "https://your-dsn@sentry.io/123",
beforeSend,
});
Seteá fingerprints en before_send cuando el agrupamiento default esparce errores similares en demasiados issues.
Mantené los fingerprints cortos y descriptivos: ["database-timeout"], ["http-error", endpoint],
["payment-failure", error_code]. Evitá fingerprints que cambien por request (URLs con IDs, timestamps) porque
derrotan el agrupamiento.
Troubleshooting de Source Maps
Los source maps se rompen más seguido de lo que funcionan. Cuando lo hacen, ves stack traces minificados como
app.a1b2c3d.js:1:4567 en lugar de OrderService.ts:42. Así se debuggean.
Check 1: ¿Se subieron los source maps? Corré sentry-cli releases files "your-release" list y verificá que los
archivos .map aparezcan. Si no, el step de upload en tu CI falló silenciosamente.
Check 2: ¿El tag de release coincide? El valor de release del SDK debe matchear el release al que subiste los
source maps. Un mismatch (ej: api-gateway@1.2.3 vs api-gateway@abc123) significa que Sentry no encuentra los maps.
Check 3: ¿El urlPrefix es correcto? El urlPrefix en el comando de upload debe matchear cómo tu servidor sirve
los archivos. Si tu JS vive en https://cdn.example.com/static/js/app.js, seteá urlPrefix: "~/static/js". Un prefix
incorrecto significa que Sentry busca los maps en la URL equivocada.
Check 4: ¿Los source maps son válidos? Corré npx source-map-explorer dist/app.js dist/app.js.map localmente. Si
falla, tu build tool generó maps rotos. Revisá tu setting devtool: "source-map" en webpack o vite.
# Debuggear upload de source maps
sentry-cli releases files "api-gateway@1.2.3" list
sentry-cli releases files "api-gateway@1.2.3" upload-sourcemaps ./dist \
--url-prefix "~/static/js" \
--rewrite \
--validate
El flag --validate chequea que los maps subidos sean válidos antes de finalizar. Usalo en CI para atrapar uploads
rotos antes de que lleguen a producción.
Privacy y Scrubbing de PII
Sentry captura bodies de request, headers y contexto de usuario por default. Es genial para debugging, pero significa que contraseñas, tokens y data personal pueden filtrarse en tu proyecto de Sentry. GDPR y CCPA hacen de esto un problema legal, no solo técnico.
El hook before_send es tu última línea de defensa. Corre antes de que cada evento salga de tu servidor, dándote la
chance de stripear campos sensibles. El hook recibe el evento completo y un hint con la excepción original.
# Python: Scrubbing comprehensivo de PII
import re
SENSITIVE_HEADERS = {"authorization", "cookie", "x-api-key", "x-auth-token"}
SENSITIVE_BODY_FIELDS = {"password", "confirm_password", "credit_card", "ssn", "api_key", "token"}
SENSITIVE_QUERY_PARAMS = {"token", "api_key", "session_id"}
def scrub_pii(event, hint):
# Scrub headers
request = event.get("request", {})
headers = request.get("headers", {})
for key in list(headers.keys()):
if key.lower() in SENSITIVE_HEADERS:
headers[key] = "[REDACTED]"
# Scrub body fields
body = request.get("data", {})
if isinstance(body, dict):
for key in SENSITIVE_BODY_FIELDS:
if key in body:
body[key] = "[REDACTED]"
# Scrub query string
query_string = request.get("query_string", "")
if query_string:
for param in SENSITIVE_QUERY_PARAMS:
query_string = re.sub(
rf"{param}=[^&]+",
f"{param}=[REDACTED]",
query_string,
flags=re.IGNORECASE,
)
request["query_string"] = query_string
# Scrub user email to just domain
user = event.get("user", {})
if "email" in user:
email = user["email"]
if "@" in email:
domain = email.split("@")[1]
user["email"] = f"[redacted]@{domain}"
return event
sentry_sdk.init(
dsn="https://your-dsn@sentry.io/123",
before_send=scrub_pii,
send_default_pii=False,
)
Seteá send_default_pii=False para que Sentry no recolecte IPs y cookies por default. Después usá
before_send para agregar solo lo que necesitás, scrubbado. Para entornos de alta compliance (healthcare, finance),
combiná esto con una instancia self-hosted de Sentry así la data de eventos nunca sale de tu infraestructura.
Testeá tu scrubbing con eventos sintéticos antes de deployear. Mandá un evento fake con un campo password y
verificá que llegue a Sentry como [REDACTED]. Un hook before_send roto que crashea silenciosamente va a dropear
eventos enteros, así que siempre devolvé el evento (incluso en error) y loggeá los fallos aparte.
Resumen
- Seteá el tag
releaseen cada init del SDK así Sentry auto-resuelve issues cuando el fix llega a producción. - Subí source maps en CI, no manualmente, así los stack traces minificados quedan legibles.
- Usá
before_sendpara redactar PII (contraseñas, tokens, tarjetas) antes de que los eventos salgan de tu servidor. - Sampleá transacciones al 10% para servicios de alto tráfico, 100% para los de bajo tráfico o paths críticos.
- Agregá breadcrumbs alrededor de consultas a DB, llamadas a APIs y cambios de estado para reconstruir el camino al error.
- Separá proyectos de Sentry por servicio o equipo así el triage queda enfocado.
- Configurá alertas sobre nuevos errores así las regresiones no esperan a que un usuario las reporte.
- Usá fingerprinting custom cuando el agrupamiento default no alcanza.
See Also
- Documentación oficial de Sentry: referencia completa de SDKs, CLI y integraciones de plataforma.
- SDK de Sentry para Python: setup de Python, integraciones y monitoreo de performance.
- SDK de Sentry para Node.js: setup de Node.js, integraciones Express/Fastify y source maps.
- SDK de Sentry para Java: integración Spring Boot, tracing y captura manual.
- Documentación de Sentry CLI: release management, upload de source maps y deploys.
- Guía de source maps de Sentry: cómo funcionan los source maps y cómo subirlos.
Preguntas frecuentes
¿Qué es Sentry?
Sentry es una plataforma de seguimiento de errores y monitoreo de performance. Captura excepciones, crashes y problemas de performance con stack traces, breadcrumbs, contexto de usuario y seguimiento de releases.
¿En qué se diferencia Sentry del logging?
El logging registra eventos en un sistema de agregación para auditoría y debugging. Sentry captura errores y problemas de performance con contexto enriquecido, así que podés triagear más rápido. Usá ambos.
¿Qué son los breadcrumbs?
Los breadcrumbs son una traza de eventos que preceden a un error. Incluyen requests HTTP, consultas a base de datos, clics de UI y mensajes de log Te muestran la secuencia de acciones que causó el issue.
¿Cómo resuelve Sentry los issues?
Sentry resuelve un issue cuando se deployea un nuevo release y no llegan eventos nuevos durante un período configurado, habitualmente 72 horas. También podés resolverlos a mano.
¿Cuál es el modelo de precios de Sentry?
Sentry ofrece un tier gratuito, tiers pagos Team y Business, y planes Enterprise. Los precios escalan según la cantidad de eventos que enviés, y podés self-hostear la versión open-source si necesitás control total.
¿Por qué debería usar Sentry en lugar de solo logging?
El logging registra eventos para auditoría y debugging, pero no agrupa, deduplica ni alerta sobre errores. Sentry agrega la capa de triage: agrupa errores similares en issues, te muestra el commit exacto que introdujo el bug, y avisa a tu equipo cuando algo nuevo rompe. Usá ambos: logs para auditoría, Sentry para triage de errores.
¿Es posible self-hostear Sentry?
Sí. La versión open-source de Sentry se puede self-hostear con Docker. La versión self-hosted tiene la mayoría de lo que ofrece el tier cloud, pero gestionás upgrades, storage y scaling vos mismo. Para equipos de menos de 50 engineers, el tier gratuito cloud suele ser más simple.
Recursos Relacionados
Logging Estructurado: logs JSON, correlation IDs, agregación
Dominá structured logging con JSON format, correlation IDs, log levels y aggregation. Cubre Python structlog, Node.js pino, Java SLF4J, stacks ELK y Loki.
GuideTrazado distribuido: OpenTelemetry, Jaeger y Zipkin
Domina el trazado distribuido con OpenTelemetry, Jaeger y Zipkin. Propagación de trazas entre servicios, contexto de span, estrategias de muestreo y depuración en producción.
RecipeMonitoreo de Usuarios Reales (RUM) con web-vitals
Monitorea experiencias reales de usuarios con Core Web Vitals, session replay y análisis de performance para identificar cuellos de botella del mundo real.
GuideMonitoring y Alerting
Construir un production monitoring stack. Cubre Prometheus, Grafana, AlertManager, metrics instrumentation, alert rules, runbooks, SLI/SLO/SLA, distributed tracing con Jaeger, log aggregation y on-call best practices con ejemplos practicos de configuracion.
GuideObservabilidad con el Grafana Stack
Configura metrics, logs y traces con Grafana, Prometheus, Loki y Tempo. Cubre instrumentación, dashboards, alerting y distributed tracing para sistemas en producción.
GuidePrometheus y Grafana: métricas, dashboards y alertas
Instrumenta servicios con métricas de Prometheus, consúltalas en PromQL, construye dashboards en Grafana y publica reglas de alerta que no oscilan.