ruta backend / módulo 5

M5 — Observabilidad

Outcome del módulo: cuando el servicio falla, lo ves en un dashboard antes de que alguien te avise. Sin esto, operás a ciegas.

Diferencia clave: monitoring = ver métricas que definiste de antemano. Observabilidad = poder responder preguntas nuevas sobre el sistema sin re-deployar, a partir de lo que emite.


Concepto 1 — Los 3 pilares (logs, métricas, traces)

Idea núcleo: tres señales complementarias. Logs = qué pasó (evento). Métricas = cuánto/cuántos (agregado). Traces = por dónde pasó una request (recorrido).

Entender (capa 1)

Texto:

Visual:

flowchart TD
    Q[¿qué pregunta respondo?] --> L[Logs<br/>¿qué pasó exactamente aquí?]
    Q --> M[Métricas<br/>¿cuánto/con qué frecuencia?]
    Q --> T[Traces<br/>¿por dónde pasó y dónde tardó?]

Video: Observability Explained | Logs, Metrics & Traces (The Three Pillars) — SystemDR

Ejemplo (log plano → estructurado):

# ❌ imposible de consultar/filtrar en agregado
print(f"user {uid} pagó {amount}")

# ✅ estructurado: cada campo es consultable
import structlog
log = structlog.get_logger()
log.info("payment_succeeded", user_id=uid, amount=amount, currency="COP")

Fijar (capa 2)

Nota atómica:

Feynman: “Las métricas son el tablero del auto (velocidad, temperatura): ves que algo sube. El trace es el GPS de tu viaje: por dónde fuiste y dónde te trabaste. Los logs son el diario detallado de cada parada.”

Aplicar (capa 3)

Convertí los print de un servicio a logs estructurados con structlog. Emití una métrica de contador (ej: pagos exitosos) y consultala.

Límites


Concepto 2 — OpenTelemetry (el estándar)

Idea núcleo: OTel es el estándar vendor-neutral para instrumentar las 3 señales una sola vez y exportarlas a cualquier backend (Grafana, Jaeger, Datadog…).

Entender (capa 1)

Texto: instrumentás con la API de OpenTelemetry (spans, métricas, logs con contexto) y configurás un exporter. Cambiás de herramienta de visualización sin re-instrumentar. Un span representa una operación con inicio/fin; los spans se anidan formando el trace; el contexto se propaga entre servicios (trace-id) para seguir la request de punta a punta.

Visual:

flowchart LR
    CODE[app instrumentada con OTel SDK] --> COL[OTel Collector] --> B1[Grafana/Tempo]
    COL --> B2[Jaeger]
    COL --> B3[otro backend]

Video: OpenTelemetry & Python: Manual Instrumentation for Beginners — Adam Gardner

Ejemplo:

from opentelemetry import trace
tracer = trace.get_tracer(__name__)

def checkout(cart):
    with tracer.start_as_current_span("checkout") as span:
        span.set_attribute("cart.items", len(cart))
        with tracer.start_as_current_span("charge_payment"):
            charge(cart)                 # span anidado: se ve su tiempo aparte

Fijar (capa 2)

Nota atómica:

Feynman: “El trace es la factura detallada de un viaje: cada span es un tramo con su costo de tiempo. Ves que el viaje total fue 2s y que 1.8s se fueron en un solo tramo (la DB).”

Aplicar (capa 3)

Instrumentá un endpoint con OTel: un span padre + un span anidado para la llamada a DB. Verificá en el visualizador que ves el desglose de tiempo por tramo.

Límites


Concepto 3 — Métricas: Prometheus, Grafana, Sentry

Idea núcleo: Prometheus recolecta métricas, Grafana las grafica, Sentry captura errores con contexto.

Entender (compacto):

from prometheus_client import Counter
payments = Counter("payments_total", "pagos", ["status"])
payments.labels(status="success").inc()

Video: How to set up Prometheus monitoring for your services — Google Cloud Tech Nota atómica: Front: ¿counter, gauge o histogram para latencia? Back: histogram — captura la distribución y permite calcular percentiles (p95/p99), que es lo que importa en latencia (el promedio miente). Counter para conteos monótonos, gauge para valores que suben y bajan (memoria, conexiones). Feynman: “El promedio de latencia es como decir ‘en promedio el restaurante atiende rápido’ mientras 1 de cada 20 clientes espera una hora. El p99 te muestra a ese cliente furioso.” Aplicar: exponé métricas Prometheus en un servicio, graficá latencia p95 y error rate en Grafana. Integrá Sentry y provocá una excepción para verla capturada. Límites: demasiadas labels de alta cardinalidad (ej: user_id) explotan Prometheus; labels acotadas.


Concepto 4 — SLO / SLI / error budget

Idea núcleo: definir “estar sano” con números. SLI = la medida. SLO = el objetivo. Error budget = cuánto podés fallar antes de frenar features.

Entender (capa 1)

Texto:

Visual:

flowchart LR
    SLI[SLI · % requests OK medido] --> SLO[SLO · objetivo 99.9%]
    SLO --> EB[Error budget · 0.1% = 43min/mes]
    EB --> DEC{¿budget gastado?}
    DEC -->|sí| FREEZE[frenar features · estabilizar]
    DEC -->|no| SHIP[seguir shippeando]

Video: SLO vs SLI vs SLA vs Error Budget | Google SRE in Plain English — Tech Tutorials with Piyush

Fijar (capa 2)

Nota atómica:

Feynman: “El error budget es el saldo de una tarjeta de ‘permiso para fallar’. Mientras te quede saldo, gastás en features nuevas. Si lo agotás, no comprás más hasta reponerlo estabilizando.”

Aplicar (capa 3)

Definí 1 SLI (ej: latencia < 300ms) y 1 SLO (99%) para un servicio. Calculá su error budget mensual y armá el cálculo de consumo actual.

Límites


Concepto 5 — Alerting que sirve

Idea núcleo: alertar sobre síntomas del usuario, no sobre causas internas. Una alerta que no requiere acción es ruido que entrena a ignorar.

Entender (compacto):

flowchart TD
    A{¿esto degrada la experiencia del usuario AHORA?} -->|sí| PAGE[alerta accionable + runbook]
    A -->|no| DASH[dashboard, no alerta]

Nota atómica: Front: ¿sobre qué se debe alertar? Back: sobre síntomas que afectan al usuario (error rate, latencia, SLO en riesgo), no sobre causas internas (CPU, memoria) que no siempre implican problema. Cada alerta debe ser accionable y tener runbook; lo demás va a dashboard. Feynman: “Alertar por CPU alta es como que suene la alarma de incendio cada vez que prendés la estufa. Alertás cuando hay humo donde no debe (el usuario sufre), no por cada uso normal.” Aplicar: configurá 1 alerta sobre error rate (síntoma) con umbral y un runbook de 3 pasos. Provocá el fallo y verificá que dispara. Límites: umbrales muy sensibles = fatiga; muy laxos = te enterás tarde. Se calibran con datos reales.


Checklist de dominio M5

Marcás cuando podés explicar (Feynman) + aplicar:

Salida verificable del módulo: un servicio instrumentado con OTel (logs estructurados + 1 métrica histogram + 1 trace con span anidado), un dashboard con latencia p95 y error rate, 1 SLO definido con su error budget, y 1 alerta accionable que dispara al provocar un fallo.