Módulo 3: Observability As Sli Input

7. De telemetría cruda a un SLI medido

Descripción

Esta es la lección que cierra el hilo de todo este módulo. SLO.md (Módulo 2, lección 8) definió el SLI, eligió el SLO, y midió el presupuesto de error sobre un dataset fijo de 30 días —con una advertencia explícita en su propia sección "Consequences": "not a live number [...] but the evidence this SLO was chosen with". Las lecciones 3 a 6 de este módulo construyeron, pilar por pilar, un pipeline real de telemetría sobre el mismo batch fijo de 20 invocaciones. Esta lección le da a error_budget_calculator.py —la misma función compute_sli(), sin ningún cambio de código— los números de ese pipeline, en vez del dataset committeado a mano. La calculadora corre de verdad, dos veces, con dos preguntas distintas.

Conexión con el módulo

La lección 6 terminó con un número confirmado, tres veces, por tres caminos distintos (CloudWatch representativo en la lección 3, logs reales en la lección 4, Prometheus real en la lección 6): 20 invocaciones, 3 errores. Esta lección es la primera vez que ese número entra a la misma función matemática que SLO.md ya usó — el punto exacto donde "observabilidad" y "SRE" dejan de ser dos palabras separadas.


Paso 1 — Corrida 1: el batch de este módulo, solo, sin contexto

La pregunta más directa: si le das a compute_sli() exactamente los dos números que Prometheus confirmó en la lección 6 —total_valid=20, total_good=17—, tratados como si fueran el mes completo, ¿qué dice la calculadora?

# --- Corrida 1: SOLO la telemetria de este modulo, como si fuera el mes completo ---
M3_TELEMETRY_BATCH = [(31, 20, 17)]  # (dia, eventos_validos, eventos_buenos)

report_1 = budget_report(M3_TELEMETRY_BATCH)
print_report(report_1, "process-shipment-manifest -- M3 telemetry batch only")

Qué esperar (literal — budget_report() y print_report() son las mismas funciones exactas de scripts/error_budget_calculator.py, Módulo 2, lección 4, sin ningún cambio):

--- process-shipment-manifest -- M3 telemetry batch only ---
Eventos validos:         20
Eventos buenos:          17
SLI medido:              85.0000%
SLO objetivo:            99.9%
Presupuesto (mensual):   43.2 minutos
Consumido en el periodo: 6480.00 minutos (15000.0% del presupuesto)
Presupuesto restante:    -6436.80 minutos

Un SLI de 85%, un presupuesto consumido al 15.000% — quince mil por ciento—. Antes de reaccionar a ese número, la siguiente sección explica exactamente por qué es la lectura equivocada de este dato, y qué lectura sí es correcta.


Por qué 85% NO es el SLI mensual de Andes Cargo, y por qué la calculadora tiene razón de todas formas

compute_sli() no cometió ningún error — hizo exactamente lo que se le pidió, con los números que se le dieron. El error, si lo hay, está en la pregunta, no en la respuesta. Dos razones concretas por las que este resultado no reemplaza el 99,9098% que SLO.md ya citó:

El tamaño de la muestra. SLO.md mide un SLI sobre 12.195 eventos válidos, distribuidos en 30 días reales. Esta corrida mide un SLI sobre 20 eventos, en una ventana de minutos. Una proporción de 3 errores sobre 20 eventos es estadísticamente muy distinta de una proporción de 3 errores sobre 12.195 —el mismo error absoluto, en un denominador radicalmente más pequeño, produce un porcentaje que no dice nada confiable sobre el comportamiento típico del sistema—.

El diseño del batch. El batch de la lección 3 tiene, a propósito, un 15% de eventos malformados —tres errores inyectados deliberadamente en posiciones fijas para verificar que el pipeline de observabilidad los detecta—. Ningún día real de tráfico de Andes Cargo debería parecerse a esto; es, por diseño, una prueba de esfuerzo del pipeline, no una muestra de tráfico de clientes. Tratar este batch como "un mes normal" sería, literalmente, el mismo error que la lección 3 ya advirtió en su sección de errores comunes.

La pregunta correcta, entonces, no es "¿reemplaza este 85% al 99,9098% de SLO.md?" —no lo reemplaza—. Es: ¿qué le pasaría al SLI real, medido sobre el dataset completo del Módulo 2, si este mismo día de telemetría real se agregara como un día más?


Paso 2 — Corrida 2: el dataset real del Módulo 2, extendido con un día real de este módulo

from scripts.error_budget_calculator import TRAFFIC_30_DAYS, budget_report, print_report

# --- Corrida 2: el dataset real de 30 dias (M2.4) + el dato real de este modulo, como dia 31 ---
combined_dataset = TRAFFIC_30_DAYS + M3_TELEMETRY_BATCH

report_2 = budget_report(combined_dataset)
print_report(report_2, "process-shipment-manifest -- 31 dias (30 dataset + telemetria real M3)")

Qué esperar (literal):

--- process-shipment-manifest -- 31 dias (30 dataset + telemetria real M3) ---
Eventos validos:         12215
Eventos buenos:          12201
SLI medido:              99.8854%
SLO objetivo:            99.9%
Presupuesto (mensual):   43.2 minutos
Consumido en el periodo: 49.51 minutos (114.6% del presupuesto)
Presupuesto restante:    -6.31 minutos

Este es el número que sí importa. El dataset del Módulo 2 ya dejaba solo 4,23 minutos de presupuesto sin usar —90,2% ya consumido, con solo cuatro días para cerrar el mes—. Agregar un solo día más, con la misma proporción de errores que el pipeline de este módulo confirmó de verdad (3 de 20, 15%), no solo consume esos 4,23 minutos restantes: los agota y deja un déficit de 6,31 minutos. El SLI mensual cae de 99,9098% a 99,8854% — por primera vez en esta guía, por debajo del SLO de 99,9% que SLO.md fijó.


Lo que esta corrida es, y lo que no es

Es importante ser preciso aquí, con la misma disciplina que SLO.md ya exigió de sí mismo: esta corrida no modifica SLO.md. El documento sigue citando, como su medición de referencia, el dataset original de 30 días del Módulo 2 —esa cifra no cambia retroactivamente porque este módulo agregó un día ilustrativo—. Lo que esta corrida demuestra es algo distinto y más importante para el resto de esta guía: la misma función, sin ningún cambio de código, responde correctamente cuando la telemetría real que este módulo produjo se integra correctamente —como un día más de un dataset ya existente, no como un reemplazo aislado de todo el mes—. Esa distinción —integrar telemetría real en el lugar correcto de la fórmula, en vez de sustituir con ella un contexto que no tiene— es, en sí misma, la lección técnica de esta lección.

El Módulo 4 va a construir sobre exactamente este resultado: una alerta de burn rate que dispara cuando el presupuesto se consume a una velocidad como la que este día ilustrativo mostró —tres errores en un puñado de minutos es, sostenido, una velocidad de consumo muy por encima de lo que un mes completo permite—.


Errores comunes

Citar el 85% de la Corrida 1 como "el SLI de Andes Cargo" fuera de contexto (el error que esta lección existe para prevenir). Qué pasa: alguien, después de esta lección, repite el número 85% en una conversación —por ejemplo, en el proyecto de la lección 8— sin la aclaración de que viene de un batch de 20 invocaciones diseñado a propósito con una alta tasa de error. Cómo detectarlo: si mencionas "85%" sin decir, en la misma frase, "un batch pequeño de verificación, no tráfico real de un mes". Cómo corregirlo: el SLI de referencia de Andes Cargo sigue siendo el que SLO.md ya fijó —99,9098% sobre el dataset original—, y el número que de verdad importa de esta lección es el de la Corrida 2: 99,8854%, el resultado de integrar correctamente un día real de telemetría en el contexto del dataset completo.

Pensar que la Corrida 2 actualiza SLO.md automáticamente (de confundir un ejercicio ilustrativo con un cambio de documento). Qué pasa: alguien concluye que, después de esta lección, SLO.md debería reescribirse con el nuevo SLI de 99,8854%. Cómo detectarlo: si tu plan es editar SLO.md inmediatamente después de esta lección. Cómo corregirlo: esta corrida es deliberadamente ilustrativa —muestra qué le pasaría al SLI si este día específico de telemetría real se agregara al dataset—, no un proceso de actualización continua de SLO.md. Ese documento cita, con toda intención, una medición de referencia fija tomada en el Módulo 2; el Módulo 4 es el que construye la maquinaria de alerting que reacciona a datos que sí cambian con el tiempo, sin necesidad de reescribir SLO.md cada vez.

Asumir que compute_sli() necesita cambios de código para aceptar datos reales (de subestimar el diseño de la calculadora del Módulo 2). Qué pasa: alguien, al ver que esta lección usa datos de un pipeline de observabilidad en vez de un dataset committeado, espera que la función compute_sli() en sí misma tenga que modificarse. Cómo detectarlo: si tu plan es "editar error_budget_calculator.py para que acepte datos de Prometheus". Cómo corregirlo: el Ejercicio 3 de la lección 4 del Módulo 2 ya explicó por qué budget_report() recibe slo y window_minutes como parámetros, no como constantes fijas — el mismo principio de diseño aplica aquí: compute_sli() solo necesita una lista de tuplas (día, válidos, buenos), sin importar si esos números vinieron de un dataset escrito a mano o de una consulta PromQL real. Ningún código cambia entre el Módulo 2 y esta lección — solo cambia de dónde vienen los números que se le pasan.


Ejercicios

Ejercicio 1 — Calcula, sin ejecutar código, cuántos minutos de presupuesto consumiría el día 31 por sí solo (no el dataset completo de 31 días, solo ese único día), usando la misma lógica de error_budget_minutes() aplicada a una ventana de 24 horas en vez de 30 días.

Ver solución

Si tratáramos el día 31 como una ventana independiente de 24 horas (1.440 minutos), con una tasa de error observada de 15% (3 de 20): minutes_consumed = 0.15 × 1440 = 216 minutos. Comparado contra un presupuesto diario hipotético de (1 - 0.999) × 1440 = 1.44 minutos, ese único día, si se sostuviera, consumiría 150 veces el presupuesto diario completo — un número todavía más alarmante que el 15.000% de la Corrida 1, precisamente porque una ventana diaria hace que cualquier ráfaga corta de errores se vea proporcionalmente enorme. Este cálculo confirma, con otro ángulo, la misma lección: la ventana de tiempo importa tanto como la proporción de errores al leer cualquier resultado de budget_report().

Ejercicio 2 — Explica, con tus propias palabras, por qué la Corrida 2 (99,8854%) es un número más confiable que la Corrida 1 (85%), aunque ambas usen datos 100% reales de este módulo. No es una pregunta sobre qué dato es "más real" — ambos lo son.

Ver solución

La confiabilidad no depende de si el dato de entrada es real —ambas corridas usan el mismo total_valid=20, total_good=17, genuinamente medido por Prometheus en la lección 6—. Depende de si el contexto estadístico en el que ese dato se interpreta es el correcto. La Corrida 1 trata 20 eventos como si representaran un mes completo de comportamiento típico del sistema —una generalización que ningún tamaño de muestra tan pequeño puede sostener, y que además ignora que el batch fue diseñado a propósito con una tasa de error alta—. La Corrida 2 integra esos mismos 20 eventos reales como lo que genuinamente son —un día más, dentro de un dataset de 12.195 eventos ya existente—, dejando que el peso relativo de ese día dentro del total sea proporcional a su tamaño real. Es la diferencia entre "un dato real, mal contextualizado" y "el mismo dato real, correctamente contextualizado" — ambas corridas son honestas sobre el origen del dato, pero solo una es honesta sobre lo que ese dato puede, y no puede, decir por sí solo.

Ejercicio 3 — Predice, sin ejecutar código, qué pasaría con el SLI combinado si el batch de este módulo hubiera tenido 20 invocaciones, todas exitosas (0 errores), en vez de 3 fallidas. ¿El SLI resultante sería mayor, menor, o igual al 99,9098% original de SLO.md? ¿Por qué?

Ver solución

El SLI resultante sería ligeramente mayor al 99,9098% original. Con total_valid = 12195 + 20 = 12215 y total_good = 12184 + 20 = 12204 (los 12.184 buenos originales más los 20 nuevos, todos buenos): SLI = 12204 / 12215 ≈ 99,9099% — una fracción de punto porcentual por encima del original, porque agregar eventos con una tasa de éxito perfecta (100%), aunque sea un grupo pequeño, siempre mueve el promedio agregado ligeramente hacia arriba, nunca hacia abajo. Este ejercicio confirma, con el caso contrario al de esta lección, el mismo mecanismo: el SLI agregado se mueve en la dirección de la tasa de éxito del dato nuevo que se agrega, con una magnitud proporcional al tamaño relativo de ese dato nuevo frente al total ya existente — 20 eventos sobre 12.195 mueven la aguja, pero solo un poco, en cualquier dirección.


Resumen y siguiente paso

Esta lección cerró el hilo central de este módulo: le dio a error_budget_calculator.py —sin ningún cambio de código— los números que el pipeline real de observabilidad de las lecciones 3 a 6 produjo. La primera corrida, con el batch de 20 invocaciones tratado de forma aislada, dio un resultado alarmante (SLI 85%, presupuesto consumido al 15.000%) que resultó ser una lectura equivocada, no un error de la calculadora — el batch es una prueba de esfuerzo del pipeline, no una muestra representativa de un mes. La segunda corrida, integrando ese mismo día real como un día más del dataset completo del Módulo 2, dio el resultado que sí importa: el SLI mensual cae a 99,8854%, por primera vez por debajo del SLO de 99,9% — un déficit real de 6,31 minutos, no un ejercicio hipotético.

Antes de avanzar deberías poder: explicar por qué el 85% de la Corrida 1 no reemplaza al 99,9098% de SLO.md; recitar el resultado exacto de la Corrida 2 (99,8854%, déficit de 6,31 minutos); y explicar por qué ningún código de error_budget_calculator.py cambió entre el Módulo 2 y esta lección.

La lección 8, el proyecto de este módulo, documenta el pipeline completo —de dónde viene cada dato, qué instrumento lo produce, qué consulta lo lee— como el primer runbook operativo de observabilidad de Andes Cargo, y guarda el panel de Grafana de la lección 6 como un artefacto reproducible.

Recursos

  1. Este mismo repositorio, Módulo 2, lección 4 (04-hands-on-the-error-budget-calculator.md) — error_budget_calculator.py, sin ningún cambio de código en esta lección.
  2. Este mismo repositorio, Módulo 2, lección 8 (08-project-andes-cargos-slo-md.md) — SLO.md, la sección "Consequences" que esta lección cierra.
  3. Este mismo repositorio, Módulo 3, lección 6 (06-hands-on-prometheus-and-grafana-the-stack-the-market-asks-for.md) — la fuente real de total_valid=20, total_good=17 que esta lección usa.
  4. Google SRE Workbook — Implementing SLOs — la fórmula de error budget que ambas corridas de esta lección aplican, sin cambios, sobre datos de origen distinto.