AWS Certified CloudOps Engineer - Associate

Fundamentos de las alarmas de CloudWatch

Cómo decide una alarma de CloudWatch cambiar de estado: period, evaluation periods, datapoints to alarm, el rango de evaluación al que alcanza en silencio y el ajuste de datos faltantes que define si el silencio significa salud o falla.

Intermedio 22 minutos 6 Objetivos de aprendizaje
  1. Identificar los ajustes que componen una alarma de métrica y explicar qué controla cada uno
  2. Explicar por qué una alarma ejecuta sus acciones solo al cambiar de estado, y nombrar la única excepción
  3. Configurar una alarma M de N y predecir su estado a partir de una secuencia de datapoints
  4. Elegir el tratamiento de datos faltantes correcto para una métrica dada y justificarlo
  5. Diagnosticar una alarma atascada en INSUFFICIENT_DATA
  6. Comparar alarmas de umbral fijo, de metric math y de detección de anomalías

Dos alarmas, la misma noche, la misma cuenta. La primera nunca se disparó mientras la cola de pagos se acumuló durante 40 minutos. La segunda se disparó 14 veces entre las 02:00 y las 03:00 sin que pasara nada real. Las armaron ingenieros que sabían perfectamente qué significan CPUUtilization y ApproximateAgeOfOldestMessage. Ninguno sabía cómo decide CloudWatch que una alarma cambia de estado.

Ahí se ganan y se pierden las alarmas. Una métrica es una lista de números, y ya sabes cómo los guarda CloudWatch. Una alarma es una pequeña máquina de estados encima de esa lista, y casi todo reclamo sobre alarmas en producción se rastrea a uno de cuatro ajustes que viven adentro.

De qué está hecha una alarma

Una alarma de métrica vigila una métrica (o una expresión de metric math) y mantiene uno de tres estados. Para decidir cuál, necesita respuestas a seis preguntas:

AjusteLa pregunta que responde
Métrica y dimensiones¿Qué números estoy vigilando?
Statistic¿Cómo colapso un lote de valores crudos en un solo número?
Period¿Qué tan ancho es un lote, en segundos?
Threshold y operador de comparación¿Qué cuenta como malo?
Evaluation Periods (N)¿Cuántos datapoints recientes miro?
Datapoints to Alarm (M)¿Cuántos de esos tienen que estar mal para que reaccione?

Hay un séptimo ajuste, el tratamiento de datos faltantes, que solo importa cuando la métrica se queda muda. Tiene su propia sección más abajo porque causa más sorpresas que los otros seis juntos.

Una alarma con valores reales: vigila CPUUtilization de la instancia i-0a1b2c3d4e5f67890, toma el Average de cada period de 60 segundos, considera malo un period cuyo promedio pase de 80 y ve a ALARM cuando 3 de los últimos 5 periods fueron malos.

aws cloudwatch put-metric-alarm \
  --alarm-name "checkout-api-cpu-high" \
  --namespace AWS/EC2 \
  --metric-name CPUUtilization \
  --dimensions Name=InstanceId,Value=i-0a1b2c3d4e5f67890 \
  --statistic Average \
  --period 60 \
  --threshold 80 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 5 \
  --datapoints-to-alarm 3 \
  --treat-missing-data missing \
  --alarm-actions arn:aws:sns:eu-west-1:111122223333:ops-critical

Tres estados, y la regla que casi todos entienden mal

Una alarma siempre está exactamente en uno de estos:

  • OK: la métrica está dentro del umbral.
  • ALARM: la métrica está fuera del umbral.
  • INSUFFICIENT_DATA: la alarma recién arrancó, la métrica no está disponible, o no hay suficientes datos para decidir.

INSUFFICIENT_DATA no es un error. Una alarma nueva empieza ahí por diseño, y un volumen EBS que existe pero no está conectado a ninguna instancia deja de publicar métricas, que es una razón perfectamente sana para que su alarma se quede en ese estado.

Ahora la regla: una alarma ejecuta sus acciones solo cuando cambia de estado. No en cada period. No cada minuto. Una vez, en la transición.

Es tentador suponer que una alarma atascada en ALARM te sigue avisando, y que un teléfono callado significa que el problema se resolvió. Ninguna de las dos cosas es cierta. La alarma mandó una notificación cuando cruzó a ALARM y desde entonces está ahí sentada en silencio. Si tu proceso necesita recordatorios mientras un incidente sigue abierto, esa repetición sale de tu herramienta de guardias, no de CloudWatch.

Hay exactamente una excepción, y al examen le gusta: en las acciones de Auto Scaling, la alarma sigue ejecutando la acción una vez por minuto mientras permanezca en el nuevo estado. Es deliberado, porque una política de escalado que se dispara una vez y después se calla nunca terminaría de escalar un grupo muy sobrecargado.

Period, Evaluation Periods y Datapoints to Alarm

Estos tres ajustes producen tanto la alarma que "nunca se disparó" como la que "se disparó 14 veces", así que conviene trabajarlos con números en vez de definiciones.

Period es cuánto tiempo cubre cada datapoint. Los valores válidos son 10, 20, 30 o cualquier múltiplo de 60 segundos.

Evaluation Periods (N) es cuántos de los datapoints más recientes mira la alarma.

Datapoints to Alarm (M) es cuántos de esos N tienen que estar incumpliendo para que la alarma pase a ALARM. Los puntos incumplidores no tienen que ser consecutivos. Solo tienen que caer dentro de la ventana de los últimos N.

Cuando M es igual a N tienes una alarma de "periods consecutivos": todos los puntos de la ventana deben incumplir. Cuando M es menor que N tienes una alarma M de N, y tolera un respiro sano en medio de una racha mala.

El intervalo de evaluación es simplemente N multiplicado por el period. Cuatro de cinco datapoints con period de 1 minuto son un intervalo de 5 minutos. Tres de tres con period de 10 minutos son un intervalo de 30 minutos.

Para cualquier period de un minuto o más, la alarma se evalúa cada minuto y la ventana se desliza. Con period de 5 minutos y 1 evaluation period, el final del minuto 5 evalúa los minutos 1 a 5, y el final del minuto 6 evalúa los minutos 2 a 6. Si el period es de 10, 20 o 30 segundos, la alarma se evalúa cada 10 segundos.

Dos cuotas limitan qué tan atrás puede mirar una alarma. Period multiplicado por Evaluation Periods puede ser como máximo 604.800 segundos (siete días) en alarmas con period de al menos una hora, y como máximo 86.400 segundos (un día) para cualquier period más corto. Y una alarma cuya ventana supera un día se vuelve una alarma de varios días, que se evalúa solo una vez por hora y toma en cuenta métricas hasta la hora actual en el minuto :00. Un job que falla a las 10:02 no mueve esa alarma a las 10:03; la alarma reacciona a las 11:03.

Datos faltantes: qué significa el silencio

Cada datapoint de la ventana es una de tres cosas: no incumple, incumple, o está faltante. Las dos primeras son obvias. La tercera es un juicio que solo tú puedes hacer, porque CloudWatch no tiene forma de saber si una métrica que se calló significa "todo está bien" o "lo que publica esta métrica está muerto".

Así que se lo dices, con uno de cuatro ajustes:

AjusteLos puntos faltantes se tratan comoÚsalo cuando
notBreachingbuenos, dentro del umbralla métrica solo publica cuando algo sale mal
breachingmalos, incumpliendo el umbralel silencio significa que murió quien reporta, y eso es un incidente
ignoreno se evalúan; se mantiene el estado actualprefieres conservar el último estado conocido antes que adivinar
missingdatos insuficientes; la alarma va a INSUFFICIENT_DATA si todos los puntos faltanel valor predeterminado, y la respuesta honesta cuando no sabes

El predeterminado es missing. Vale la pena memorizar dos excepciones. Las alarmas sobre métricas del namespace AWS/DynamoDB usan ignore como predeterminado. Y AWS recomienda específicamente missing para alarmas que detienen, terminan, reinician o recuperan instancias EC2, porque el reporte de métricas de EC2 se puede interrumpir un momento en una instancia perfectamente sana, y no quieres que un hueco en el reporte termine un servidor de producción.

Elecciones concretas: ThrottledRequests de DynamoDB publica un datapoint solo cuando una solicitud es limitada, así que notBreaching es lo correcto. Una alarma que dispara el rollback de un despliegue vigila una métrica que reporta de forma continua, así que un hueco probablemente significa que la app dejó de responder, y ahí breaching es lo correcto.

El rango de evaluación, y por qué tu ajuste de datos faltantes se ignora tan seguido

Acá está la parte que hace que las alarmas se comporten de formas que los ajustes no predicen a simple vista.

Cada vez que una alarma evalúa, CloudWatch recupera más datapoints que Evaluation Periods. El marco temporal de esos puntos extra se llama rango de evaluación. En una alarma con 3 evaluation periods, el rango de evaluación es de 5 datapoints.

Después aplica tres reglas en orden:

  1. Si no falta ningún punto del rango de evaluación, evalúa los N más recientes e ignora los extra.
  2. Si faltan algunos pero el total de puntos reales recuperados es al menos N, evalúa los N datapoints reales más recientes, alcanzando hacia atrás entre los extra. Tu ajuste de datos faltantes no se usa para nada.
  3. Solo si los puntos reales siguen siendo menos que N, CloudWatch rellena los huecos con tu tratamiento de datos faltantes, y aun así usa la menor cantidad posible de puntos sustituidos.

Piénsalo como un profesor que califica tus últimas 3 tareas. Si dos de esas 3 nunca se entregaron, el profesor alcanza hacia atrás la cuarta y la quinta tarea en vez de poner cero en las que faltan. La analogía se rompe en un punto: el profesor seguiría alcanzando hacia atrás indefinidamente, mientras que CloudWatch llega solo hasta el borde del rango de evaluación y después recurre a tu ajuste.

Por eso dos ingenieros pueden poner breaching y notBreaching sobre la misma métrica intermitente y ver ambas alarmas comportarse igual durante semanas.

Adentro hay una pieza de lógica más, llamada evitación del estado prematuro de alarma. Con Datapoints to Alarm en 3, los datos - - - - X (cuatro faltantes y luego uno incumpliendo) no pasan de inmediato a ALARM, porque el siguiente punto podría ser sano. Pero los datos - - X - - sí pasan a ALARM incluso con el tratamiento missing, porque el punto incumplidor disponible más antiguo tiene al menos la antigüedad del valor de M y todo lo más reciente incumple o falta. No esperes que la tabla de datos faltantes por sí sola prediga estos bordes.

Alarmas de alta resolución

Pon el period en 10, 20 o 30 segundos y creaste una alarma de alta resolución, evaluada cada 10 segundos y cobrada a una tarifa más alta que una alarma normal.

Usa esos periods solo para métricas publicadas con resolución de almacenamiento de 1, o sea tus propias métricas personalizadas de alta resolución. Apunta una alarma de 10 segundos a una métrica de resolución estándar y CloudWatch igual intenta juntar datos cada 10 segundos, no encuentra nada en cinco de cada seis intentos y deja caer la alarma en INSUFFICIENT_DATA de forma regular. Obtienes una alarma poco confiable y el precio premium al mismo tiempo.

Más allá de un número fijo

No toda pregunta tiene un umbral fijo, y CloudWatch te da dos caminos.

Las alarmas de metric math vigilan la salida de una expresión en vez de una métrica cruda. El caso clásico es una tasa de error, porque "500 errores" significa algo completamente distinto con 600 solicitudes que con 6 millones:

{
  "Metrics": [
    { "Id": "errors",   "MetricStat": { "Metric": { "Namespace": "MyService", "MetricName": "ConnectionsFailed" }, "Period": 60, "Stat": "Sum" }, "ReturnData": false },
    { "Id": "attempts", "MetricStat": { "Metric": { "Namespace": "MyService", "MetricName": "ConnectionAttempts" }, "Period": 60, "Stat": "Sum" }, "ReturnData": false },
    { "Id": "error_rate", "Expression": "(errors/attempts)*100", "ReturnData": true, "Label": "Tasa de error de conexión" }
  ],
  "Threshold": 40,
  "ComparisonOperator": "GreaterThanThreshold",
  "EvaluationPeriods": 3
}

Exactamente un elemento del arreglo Metrics pone ReturnData en true, y esa es la expresión que la alarma vigila.

Las alarmas de detección de anomalías no tienen umbral fijo. CloudWatch entrena un modelo de machine learning con hasta dos semanas de datos pasados de la métrica, aprende sus patrones por hora, por día y por semana junto con su tendencia de fondo, y produce una banda de valores esperados. La alarma se dispara cuando la métrica sale por arriba de la banda, por abajo, o fuera en cualquier dirección.

{
  "Metrics": [
    { "Id": "m1", "ReturnData": true, "MetricStat": { "Metric": { "Namespace": "AWS/EC2", "MetricName": "CPUUtilization" }, "Stat": "Average", "Period": 60 } },
    { "Id": "t1", "Expression": "ANOMALY_DETECTION_BAND(m1, 3)" }
  ],
  "ThresholdMetricId": "t1",
  "ComparisonOperator": "LessThanLowerOrGreaterThanUpperThreshold",
  "EvaluationPeriods": 2
}

El 3 es el umbral de detección de anomalías, y un número más alto produce una banda más gruesa y menos alertas. Cuatro detalles deciden si esta es la herramienta correcta:

  • El modelo es específico de una métrica y de un statistic. Un modelo entrenado sobre Average no te dice nada sobre Maximum.
  • Puedes excluir períodos de tiempo del entrenamiento, que es como evitas que la prueba de carga del mes pasado le enseñe al modelo que un pico de 10x es normal.
  • Las alarmas basadas en un modelo de detección de anomalías no admiten acciones de Auto Scaling.
  • Cada alarma de detección de anomalías se factura como tres métricas de alarma de resolución estándar (la métrica más los límites superior e inferior), así que unos 0,30 USD al mes contra 0,10 USD de una alarma de métrica simple.

La detección de anomalías se gana su lugar en métricas con una forma diaria marcada, como el conteo de solicitudes de una app de consumo. Es la herramienta equivocada para una métrica en la que cualquier valor distinto de cero ya es malo.

Diagnosticar una alarma que no sale de INSUFFICIENT_DATA

Este es el ticket de alarmas más común, y tiene una lista corta de causas:

  • El period es más corto que la resolución de la métrica. El monitoreo básico de EC2 publica cada 5 minutos, así que un period de 60 segundos deja cuatro de cada cinco periods vacíos.
  • El conjunto de dimensiones nunca se publicó. Una alarma se puede crear antes de que exista su métrica personalizada, y se queda feliz en INSUFFICIENT_DATA para siempre si las dimensiones no coinciden exactamente con lo que publicas.
  • Se especificó un Unit que la métrica nunca usa. AWS recomienda omitir Unit por completo, porque un desajuste produce una alarma atascada en vez de un error.
  • El recurso está genuinamente ocioso. Volúmenes EBS desconectados, funciones Lambda sin invocaciones y Auto Scaling groups en cero instancias dejan de publicar.

El historial de alarma se guarda 30 días, y describe-alarm-history muestra cada transición de estado con su timestamp. Es tu primera parada cuando alguien pregunta si una alarma se disparó alguna vez.

aws cloudwatch describe-alarm-history \
  --alarm-name "checkout-api-cpu-high" \
  --history-item-type StateUpdate \
  --max-records 10

Consejos para el examen

  • "La alarma siguió en ALARM pero solo recibimos un correo" nunca es un bug. Las acciones se disparan al cambiar de estado. La única acción que se vuelve a ejecutar mientras el estado se mantiene es una acción de Auto Scaling, una vez por minuto.
  • Lee con cuidado cómo está redactado el umbral. "3 periods consecutivos" significa M igual a N; "3 de 5" significa M igual a 3 y N igual a 5, y los puntos incumplidores pueden estar dispersos.
  • Mapea las opciones de datos faltantes contra la naturaleza de la métrica: una métrica que solo publica al fallar apunta a notBreaching; una métrica de reporte continuo donde el silencio es sospechoso apunta a breaching; las alarmas de stop, terminate, reboot y recover de EC2 apuntan a missing, que además es el predeterminado global.
  • Un period de 10, 20 o 30 segundos significa alarma de alta resolución, y solo funciona sobre métricas guardadas con resolución de 1 segundo. Un enunciado que menciona a la vez un period por debajo del minuto y una métrica publicada por AWS está describiendo una alarma rota.
  • Si un escenario dice "ningún umbral fijo funciona, el nivel normal cambia según la hora del día", la respuesta es detección de anomalías, y recuerda que no puede manejar Auto Scaling.
  • Una ventana de alarma mayor a un día se evalúa cada hora contra datos hasta la hora en punto, y el total se topa en siete días.

La regla que te llevas: el estado de una alarma lo decide una ventana deslizante de los últimos N datapoints, y todo lo que se siente impredecible en las alarmas viene de lo que hace CloudWatch cuando esa ventana tiene huecos. Lo siguiente es seguir la notificación desde la alarma hacia Amazon SNS, donde te espera otro conjunto de fallas silenciosas.