Conceptos básicos de observabilidad
10 ejemplos para empezar con la observabilidad: 7 básicos y 3 intermedios.
Prerrequisitos
uv venv && source .venv/bin/activate
uv pip install "structlog>=24.0" "prometheus-client>=0.21" "opentelemetry-sdk>=1.29"- Python 3.14.0 con bibliotecas comunes de observabilidad instaladas.
Ejemplos básicos
1. Línea de registro estructurada
Los registros JSON son buscables en Loki, CloudWatch y ELK.
import json
import logging
logging.basicConfig(level=logging.INFO, format="%(message)s")
log = logging.getLogger("api")
log.info(json.dumps({"event": "order_created", "order_id": "ord_1", "ms": 42}))- Un objeto JSON por línea (NDJSON) es el estándar de ingesta.
- Incluya campos de dominio (
order_id), no solo cadenas de mensajes. - El nivel de registro sigue siendo importante para filtrar el ruido.
Relacionado: Registro estructurado - configuración de structlog
2. ID de correlación de solicitud
Vincule las líneas de registro a una única solicitud HTTP.
import uuid
from contextvars import ContextVar
request_id: ContextVar[str] = ContextVar("request_id", default="-")
def set_request_id() -> str:
rid = str(uuid.uuid4())
request_id.set(rid)
return rid- Pase
X-Request-IDdesde la pasarela (gateway) o genérelo en el borde (edge). - ContextVar propaga el ID a través de llamadas asíncronas de FastAPI en la misma tarea.
- Incluya
request_iden cada registro de esa solicitud.
Relacionado: Trazado distribuido - IDs de traza
3. Métrica de contador
Cuente eventos para paneles de tasa y ratio de errores.
from prometheus_client import Counter
ORDERS_CREATED = Counter("orders_created_total", "Órdenes creadas")
def create_order() -> None:
ORDERS_CREATED.inc()- El contador solo aumenta; úselo para totales.
- El sufijo de nombre
_totales una convención de Prometheus. - Exporte el punto de conexión
/metricspara su extracción (scraping).
Relacionado: Métricas - histogramas y medidores (gauges)
4. Temporizador / Histograma de latencia
Mida cuánto tiempo tardan las operaciones.
import time
start = time.perf_counter()
# ... trabajo ...
elapsed_ms = (time.perf_counter() - start) * 1000perf_counteres monotónico para duraciones.- Prefiera métricas de histograma sobre la temporización manual en producción.
- Registre umbrales lentos solo cuando excedan el SLO.
Relacionado: Monitorización de rendimiento (APM) - SLOs de latencia
5. Punto de conexión de estado (Health Endpoint)
Los balanceadores de carga necesitan una respuesta OK barata.
from fastapi import FastAPI
app = FastAPI()
@app.get("/health/live")
def live():
return {"status": "ok"}- Liveness (viva): el proceso está activo.
- Readiness (listo): puede servir tráfico (agregue una verificación de base de datos en una ruta separada).
- Mantenga la liveness rápida; sin llamadas externas.
Relacionado: Salud y preparación (Health & Readiness) - diseño de sondeos (probes)
6. Niveles de registro
Use niveles para separar la señal del ruido.
import logging
log = logging.getLogger("worker")
log.debug("detalle para desarrollo")
log.info("trabajo finalizado")
log.warning("reintentando")
log.error("falló permanentemente")- INFO es el predeterminado en producción; DEBUG a través de una bandera de entorno.
- ERROR debería activar alertas cuando la tasa aumenta.
- No registre secretos en ningún nivel.
Relacionado: Mejores prácticas de observabilidad - reglas de registro
7. Registro de excepciones
Capture rastreos de pila (stack traces) con contexto.
import logging
log = logging.getLogger("api")
try:
risky()
except Exception:
log.exception("pago fallido", extra={"order_id": "1"})log.exceptionincluye el rastreo automáticamente.- Agregue contexto de negocio en el diccionario
extra(el formateador JSON debe incluirlo). - Empareje con el seguimiento de errores para la agregación.
Relacionado: Seguimiento de errores - Sentry
Ejemplos intermedios
8. Esquema de métricas RED
Tasa, Errores, Duración por punto de conexión.
# Tasa: contador requests_total
# Errores: contador requests_failed_total
# Duración: histograma request_duration_seconds- El método RED es una verificación rápida para servicios impulsados por solicitudes.
- Use el método USE (Utilización, Saturación, Errores) para trabajadores y pools de bases de datos.
- Elija el método que coincida con el tipo de servicio.
Relacionado: Métricas - cubos de histograma (buckets)
9. Concepto de Span de Traza
Una ID de traza, múltiples spans entre servicios.
[Span de API] -> [Span de DB] -> [Span de publicación SQS]
- Los spans tienen relaciones padre/hijo.
- OpenTelemetry estandariza las cabeceras de propagación.
- Muestree trazas en producción para controlar costos.
Relacionado: Trazado distribuido - OpenTelemetry
10. Los tres pilares juntos
Flujo de incidentes: alerta de métrica → logs con request_id → cascada de trazas.
# 1. Alerta: tasa_error > 1%
# 2. Consulta de logs: request_id="abc" AND level=ERROR
# 3. UI de traza: trace_id del campo de log- Correlacione campos (
trace_id,request_id) entre los pilares. - Los paneles enlazan a la búsqueda de logs y la UI de trazas.
- Los runbooks documentan este flujo para el personal de guardia (on-call).
Relacionado: Mejores prácticas de observabilidad - higiene del personal de guardia (on-call)
Versiones de la pila: Esta página se escribió para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+ y uv 0.6+.