AWS Builder Center

5 formulas de Metric Math que convierten metricas crudas en SLIs

De mis previos blogs Sabes cual estadistica usar y cual SLI definir. Ahora falta la formula que conecta una metrica cruda de CloudWatch con el SLI que alimenta tu SLO.

La pieza que falta

En el primer blog de esta serie cubrimos las 12 estadisticas de Amazon CloudWatch y cuando usar cada una. En el segundo, vimos como una mala eleccion de estadistica rompe toda la cadena SLO. Pero queda una pregunta practica: ¿como calculas el SLI a partir de las metricas que CloudWatch ya esta recolectando?
La respuesta es Metric Math: expresiones matematicas que combinan multiples metricas de CloudWatch para crear series de tiempo derivadas. Puedes visualizarlas en dashboards, usarlas en alarmas, y construir SLIs compuestos sin publicar metricas custom adicionales.
AWS tiene dos blogs que cubren la sintaxis de Metric Math:
Este post no repite esa sintaxis. Se enfoca en lo que esos blogs no cubren: las 5 formulas especificas que convierten metricas crudas en los SLIs de tu SLO.

Antes de empezar: la convencion

En todas las formulas, los IDs de metrica (m1, m2...) siguen la convencion de CloudWatch Metric Math:
Plain text
m1, m2, m3... = metricas crudas de CloudWatch
e1, e2, e3... = expresiones de Metric Math
PERIOD(m1) = el periodo de la metrica en segundos

Cada formula incluye: la expresion exacta, las metricas de entrada con su estadistica, un ejemplo numerico, y cuando la formula miente.

Formula 1: Tasa de errores (Error Rate)

Pregunta que responde: "¿Que porcentaje de solicitudes fallaron?"
Metricas de entrada:
Plain text
m1 = HTTPCode_Target_5XX_Count [Statistic: Sum]
m2 = RequestCount [Statistic: Sum]

Expresion:
Plain text
e1 = (m1 / m2) * 100

Ejemplo numerico: en un periodo de 5 minutos, tu Application Load Balancer recibio 10,000 solicitudes (m2 = 10,000) y 50 devolvieron 5xx (m1 = 50). La tasa de errores es (50 / 10,000) * 100 = 0.5%.
Variante para API Gateway: API Gateway ya publica esta tasa como la estadistica Average de  5XXError . No necesitas Metric Math para obtenerla. Pero si quieres calcularla tu mismo, por ejemplo para combinar errores de multiples APIs:
Plain text
m1 = 5XXError [Statistic: Sum]
m2 = Count [Statistic: SampleCount]
e1 = (m1 / m2) * 100

"The Sum statistic represents this metric, namely, the total count of the 5XXError errors in the given period. The Average statistic represents the 5XXError error rate." -  API Gateway metrics and dimensions 
Cuando esta formula miente: cuando m2 (RequestCount) es 0. Division por cero. CloudWatch descarta el data point silenciosamente. No ves un error; ves un hueco en la grafica. Si alarmas sobre esta expresion, periodos sin trafico producen INSUFFICIENT_DATA, no "0% de errores." Usa FILL(e1, 0) si quieres tratar periodos sin trafico como saludables, pero hazlo con cuidado: estas asumiendo que "sin trafico = sin problemas," lo cual no siempre es cierto.

Formula 2: Disponibilidad (Availability)

Pregunta que responde: "¿Que porcentaje de solicitudes fueron exitosas?"
Es la inversa de la tasa de errores, pero expresada como la definio Application Signals:
"Availability represents the successful responses divided by the total requests. It is calculated as (1 - Fault Rate)*100, where Fault responses are 5xx errors. 4XX responses are treated as successful." -  CloudWatch Service Level Objectives 
Metricas de entrada:
Plain text
m1 = HTTPCode_Target_5XX_Count [Statistic: Sum]
m2 = RequestCount [Statistic: Sum]

Expresion:
Plain text
e1 = ((m2 - m1) / m2) * 100

Ejemplo numerico: 10,000 solicitudes, 50 errores 5xx. Disponibilidad = ((10,000 - 50) / 10,000) * 100 = 99.5%.
¿Por que no simplemente 100 - error_rate? Puedes hacerlo (e1 = 100 - e_error_rate). Pero la formula directa es mas clara para auditoria porque los numeros de entrada (solicitudes exitosas / solicitudes totales) son los que un stakeholder entiende.
Cuando esta formula miente: misma trampa que la Formula 1. Division por cero cuando no hay trafico. Y un matiz adicional: si tu servicio devuelve 200 OK pero con datos incorrectos (un bug logico), la disponibilidad es 100% y el usuario sufre. La disponibilidad mide fallos de infraestructura, no fallos de logica.
La tasa de errores te dice cuanto falla. La disponibilidad te dice cuanto funciona. Pero ninguna de las dos te dice si lo que funciona es rapido o lento. Para eso necesitas medir latencia.

Formula 3: Cumplimiento de latencia (Latency Compliance)

Pregunta que responde: "¿Que fraccion del tiempo mi latencia esta dentro del objetivo?"
Esto es la version Metric Math del concepto de PR(:threshold) del Blog 1, aplicada a alarmas period-based en vez de request-based.
Metricas de entrada:
Plain text
m1 = TargetResponseTime [Statistic: p99]

Expresion:
Plain text
e1 = IF(m1 \<= 0.5, 1, 0)

Donde 0.5 es tu umbral en segundos (500ms). Cada periodo donde p99 esta dentro del umbral produce 1 (cumple); fuera produce 0 (no cumple).
Para ver el cumplimiento acumulado a lo largo del dia:
Plain text
e2 = RUNNING_SUM(e1)
e3 = RUNNING_SUM(e1 * 0 + 1)
e4 = (e2 / e3) * 100

Donde e2 cuenta periodos que cumplen, e3 cuenta periodos totales (el truco de  e1 * 0 + 1  genera un 1 por cada data point), y e4 es el porcentaje de cumplimiento.
Ejemplo numerico: en 8 horas (480 periodos de 1 minuto), tu p99 cumplio el umbral de 500ms en 472 periodos. Cumplimiento = (472 / 480) * 100 = 98.3%.
Cuando esta formula miente: esta midiendo cumplimiento por periodo, no por solicitud. Un periodo de 1 minuto con p99 = 499ms "cumple" aunque dentro de ese minuto hubo solicitudes individuales que tardaron 2 segundos. La estadistica p99 ya descarta el 1% peor. Si necesitas cumplimiento por solicitud real, necesitas PR(:threshold) como estadistica nativa (Blog 1), no Metric Math.
Hay un segundo problema: si m1 no tiene datos en un periodo (por ejemplo, cero trafico), CloudWatch trata el valor faltante como 0. Eso significa que IF(0 <= 0.5, 1, 0) = 1, y el periodo se cuenta como "cumple." Si tu servicio se cayo y dejo de publicar metricas, la formula muestra 100% de cumplimiento durante la caida. Para evitarlo, usa DATAPOINT_COUNT(m1) en vez del truco de  e1 * 0 + 1  para contar periodos reales:  e3 = TIME_SERIES(DATAPOINT_COUNT(m1)) . Esto excluye periodos sin datos, lo cual es mas honesto.
Las tres formulas anteriores miden que tan bien responde tu servicio. Pero ninguna mide si tu servicio tiene capacidad de seguir respondiendo. Eso es saturacion.

Formula 4: Presion de saturacion (Saturation Pressure)

Pregunta que responde: "¿Que porcentaje de mi capacidad maxima estoy usando?"
Metricas de entrada:
Plain text
m1 = ConcurrentExecutions [Statistic: Maximum]

Expresion:
Plain text
e1 = (m1 / TIME_SERIES(1000)) * 100

Donde 1000 es tu limite de concurrencia de cuenta (ajustalo a tu valor real). TIME_SERIES() convierte el escalar en una serie de tiempo para que la division funcione.
Ejemplo numerico: tu AWS Lambda ConcurrentExecutions llego a 800 en un periodo. Presion = (800 / 1000) * 100 = 80%. Estas al 80% de tu limite.
Para Amazon SQS queue depth (saturacion de procesamiento):
Plain text
m1 = ApproximateNumberOfMessagesVisible [Statistic: Maximum]
e1 = m1

Aqui no necesitas formula. Maximum del medidor instantaneo ya es tu SLI (Blog 1). Pero si quieres expresar la profundidad relativa a un umbral operativo:
Plain text
e1 = (m1 / TIME_SERIES(10000)) * 100

Donde 10,000 es tu umbral operativo (por ejemplo, el punto donde empiezas a perder SLO de latencia).
Cuando esta formula miente: cuando el limite cambia y tu no actualizas la constante en TIME_SERIES(). Si AWS aumenta tu quota de 1,000 a 3,000 y la formula sigue diciendo TIME_SERIES(1000), tu dashboard muestra 100% de presion cuando en realidad estas al 33%. Documenta la constante y revisala trimestralmente.

Formula 5: Rellenar huecos (Fill the Gaps)

Pregunta que responde: "¿Como hago que mis metricas sparse no rompan dashboards y alarmas?"
Esta no es un SLI, pero es la formula que hace que las otras 4 funcionen en produccion. Las metricas de error son inherentemente sparse: si no hay errores, no hay data points.
Expresion basica:
Plain text
e1 = FILL(m1, 0)

Rellena periodos sin datos con 0. Util para metricas de conteo de errores donde "sin datos = sin errores."
Expresion para metricas de latencia:
Plain text
e1 = FILL(m1, REPEAT)

Usa el ultimo valor conocido. No inventa datos; repite el mas reciente. Util para dashboards donde los huecos confunden visualmente.
Expresion para interpolacion:
Plain text
e1 = FILL(m1, LINEAR)

Calcula el valor intermedio entre el data point anterior y el siguiente. Util para metricas de capacidad que cambian gradualmente.
"You can use the REPEAT keyword to fill missing values with the most recent actual value of the metric before the missing value." -  CloudWatch Metric Math: FILL function 
Cuando FILL miente:
FILL(m1, 0) en una metrica de errores dice "cero errores" cuando la realidad es "no se." Si el agente de CloudWatch dejo de publicar porque el servidor se cayo, no hay errores porque no hay nada. Cero es optimista. En alarmas, AWS advierte que FILL puede causar que la alarma se quede pegada en OK o en ALARM si el data point mas reciente siempre falta por un ligero retraso en la publicacion.
La regla: usa FILL en dashboards para claridad visual. En alarmas, prefiere la configuracion de "treat missing data as" del propio alarma en vez de FILL, porque el alarma tiene logica nativa para manejar datos faltantes.

Lo que Metric Math NO puede hacer

Antes de que intentes resolver todo con formulas, tres limites claros:
  1. No puede calcular percentiles de multiples metricas. No puedes escribir  PERCENTILE([m1, m2, m3], 99) . Percentiles son una estadistica de CloudWatch (Blog 1), no una funcion de Metric Math. Si necesitas p99 de la latencia combinada de tres servicios, necesitas publicar una metrica custom que agregue las latencias antes de calcular el percentil.
  1. No puede reemplazar PR(:threshold). PR es una estadistica nativa que opera sobre los datos crudos dentro de un periodo. Metric Math opera sobre los valores estadisticos ya calculados (un numero por periodo). La Formula 3 simula el concepto a nivel de periodo, pero no a nivel de solicitud individual.
  1. No puede cruzar cuentas automaticamente. Metric Math opera dentro del contexto de la solicitud GetMetricData. Para formulas cross-account, necesitas CloudWatch cross-account observability (OAM) configurado primero.
Estas limitaciones definen la frontera entre lo que resuelves con estadisticas (Blog 1), lo que resuelves con SLOs nativos (Blog 2), y lo que resuelves con Metric Math (este blog).

Resumen: de la metrica al SLI en una tabla

SLI
Formula
Metricas de entrada
Estadistica
Tasa de errores
 (m1/m2)*100 
5XX Count + RequestCount
Sum + Sum
Disponibilidad
 ((m2-m1)/m2)*100 
5XX Count + RequestCount
Sum + Sum
Cumplimiento de latencia
 IF(m1\<=threshold,1,0) 
TargetResponseTime
p99
Presion de saturacion
 (m1/TIME_SERIES(limit))*100 
ConcurrentExecutions
Maximum
Rellenar huecos
 FILL(m1, 0)  /  REPEAT  /  LINEAR 
Cualquier metrica sparse
Depende del caso

Empieza hoy

  1. Prueba la Formula 1 en tu ALB: abre la  consola de Amazon CloudWatch , navega a Metrics, selecciona ApplicationELB, agrega  RequestCount  (Sum) y  HTTPCode_Target_5XX_Count  (Sum), luego agrega una expresion matematica:  (m1/m2)*100 . Veras tu tasa de errores en tiempo real.
  1. Construye la Formula 2 sobre la 1 para tener disponibilidad:  ((m2-m1)/m2)*100 . Agrega un widget con esta expresion a tu dashboard.
  1. Crea una alarma de cumplimiento con la Formula 3:  IF(m1\<=0.5,1,0)  sobre tu p99 de latencia. Configura la alarma para que se active cuando el valor sea 0 (periodo incumplido).
  1. Revisa las constantes en tus formulas de saturacion (Formula 4). ¿El limite en TIME_SERIES() refleja tu quota actual?

Recursos

Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article