Decidiendo cómo alertar con Grafana
Crónicas de monitoreo (con esfuerzo y superación)
En este post resolveré el gran misterio sobre cuál es la mejor forma de generar alertas en Grafana, mediante el análisis de un caso hipotético.
Pero antes…
¿Qué es Grafana?
Una herramienta Open Source que te permite visualizar, monitorear y analizar información obtenida desde múltiples data storage como Graphite, Influxdb y Prometheus.
Funciona como una aplicación Web, la cual utiliza dashboards que representan distintos tipos de métricas obtenidas de los data storages. Permite hacerte un idea de lo que pasa con tu infraestructura y/o servicios, de una forma elegante y estética.
Un dashboard agrupa un conjunto de paneles en base a variables que pueden ser un grupo de servidores o aplicaciones, visualizando de mejor manera la información de estos. Un panel muestra información detallada en forma de gráfico sobre las métricas recolectadas por a una o más queries.
También permite el generar y enviar alertas en base a eventos definidos en los paneles. Esta característica tiende a pasar desapercibida, ya que el enfoque principal de Grafana es la visualización, lo cual logra bastante bien. Sin mencionar el montón de plugins que posee.
Debido a que no ubico la mascota del logo de Grafana, puse lo que mas me hacia sentido, una Jirafa.
Creando alertas 🚨
Se logra mediante la definición de reglas asociadas a un panel, utilizando como condición una query en conjunto a los valores con los cuales debe ser comparada.
Esto permite dar mayor flexibilidad para alertar ciertas condiciones de los distintos recursos monitoreados.
Antes de seguir, un pequeño repaso del segmento “Alert” disponible en el menú de edición del panel.
Alert Config:
- Nombre de la alerta.
- Tiempo de evaluación.
Condiciones:
- La primera condición
WHEN
, ademas de ser el comienzo de la regla, define de cierta forma el que no puedes agregar múltiples queries a un panel. Claro, puedes agregar condiciones a la regla medianteAND
yOR
. Pero eso sigue siendo muy distinto a agregar 5 tipos de alertas no relacionadas entre si. - El siguiente atributo puede ser
avg()
,min()
ymax()
. Define el valor que usará de las métricas recolectadas para comparar. OF query(A, 5m, now)
A corresponde a la letra correspondiente a la query, de esta forma puedes alternar y agregar múltiples condiciones. 5m define el rango de tiempo para evaluar el avg() con el valor actual (now).- El estado, lo defines tú en este caso:
IS ABOVE
algún número.
Para más información sobre cómo funciona las alertas:
Notificaciones ☎️
Ahora que ya sabes un poco más sobre Grafana y la composición de una alerta, el siguiente paso es que esta notifique a alguna parte es tener algún lado donde hacer. Mediante sus integraciones permite enviar alertas a servicios como:
- VictorOps y OpsGenie: plataformas de manejo de incidentes, populares por sus servicios ‘On-Call’, los cuales te llamarán hasta que les des acknowledgement a las alertas que se generen y/o solucionarlas.
- Slack: herramienta de comunicación para equipos sustentada por party parrots.
- Mail y otros servicios.
Ya con eso listo, una pequeña pregunta:
Caso hipotético 📑
Tienes 20 servidores para monitorear en base a los siguientes paneles:
- Queries
- Threads
- Load
- Delay
- Network
¿Cuántos paneles necesitas? 📖
Dos respuestas probables. La segunda te sorprenderá.
R1: Si pensaste en 5 paneles, tal vez.
Pese a que puedes agrupar multiples servidores dentro de un solo panel, gracias al uso de variables del dashboard y que para alertar solo tienes que asociar la query especifica de cada panel como regla para monitorear, técnicamente debería ser así. Esta solución tiene bastantes detalles de los cuales estar al tanto.
R2: Si pensaste que en el peor de los casos serían 100, tu respuesta es semi-realista.
Esta cobra 🐍 sentido cuando aplicas la lógica de los 5 paneles e intentas guardar, Grafana te mostrará una linda notificación diciendo que no soporta el uso de variables del template (dashboard). Es en este punto, cuando 100 paneles es casi una realidad.
Justifique la respuesta 📝
Antes de explicar cada respuesta y como trabajar para sacar lo mejor de ambas, se debe tener en consideración, que en la documentación dice explícitamente que no soporta el uso de variables del dashboard, como lo sería $host
, la cual agrupa los servidores monitoreados. Esta usualmente aparece por defecto en la mayoría de ejemplos y templates.
No es posible usar variables del dashboard siguiendo la lógica que las reglas para alertar surgen a partir de las queries utilizadas por cada backén, por lo cual, las variables utilizadas por la interfaz de Grafana son otra cosa.
Una forma de solucionar esto, es mediante expresiones regulares dentro de las queries utilizadas. Ejemplo:
Hacer un match con REGEX a los siguientes hosts:
partyparrot.energon.cloud
partyparrot5.energon.cloud
partyparrot10.energon.cloud
partyparrot19.energon.cloud
Debido a que las queries utilizadas son distintas según el backén, dejo él link a la documentación del REGEX los dos ejemplos de query.
Prometheus (Con Percona)
node_load1{instance=~"partypa.*"}
InfluxDB
SELECT mean(load1) as short FROM "system" WHERE host =~ /partypa/ AND $timeFilter GROUP BY time($interval), * ORDER BY asc
Bien, ahora vuelve a ser posible agrupar multiples hosts en esos 5 paneles y mandar las alertas correspondientes. Aquí es cuando cito la frase que me hace mucho mas sentido conforme pasa el tiempo:
Some people, when confronted with a problem, think “I know, I’ll use regular expressions.” Now they have two problems.
— Jamie Zawinski
Justificación para 5️⃣ paneles
Mas que un problema con las expresiones regulares utilizadas en la query, es que al agrupar todos los hosts dentro un solo panel, limitas el poder generar multiples alertas.
Cuando se generá una alerta, el estado del panel cambia de 💚 a 💔. Esto se mantiene hasta que ocurre la recuperación en base a la regla utilizada.
¿En qué afecta?
Si se encuentra en 💔, por mas que se generen nuevos eventos dentro del mismo panel, no avisará, ya que el estado no varía.
Tomando como referencia imagen del “💔 Load Example”. Si existe un servidor que se encuentre de forma constante sobre el limite general en este caso, la linea rosa, no llegarán alertas del resto de servidores, por mas que estos estén sobrepasando el limite.
Hay un límite que rompe el deseo, una query nueva que va más allá.
Si buscas buscas diferenciar las alertas, debido a que todas estan usando el mismo nombre, usando el mismo REGEX de la query.
Dependiendo bastante de lo que debas monitorear, puede que agruparlas no te sirva mucho, mas aún si quieres tener un registro individual de las alertas generadas para análisis.
Justificación para 1️⃣0️⃣0️⃣ paneles
Mi nueva catergoría favorita “métodos cuestionables pero efectivos”, puedes crear alertas individuales para cada host en un panel individual, evitando el problema de no poder recibir alertas por culpa de un servidor “especial” que se sale de los rangos comunes.
Aquí es cuando piensas, en “Uh ya sé, duplicaré el panel y solo cambiaré el hostname”.
Lamentablemente la copia del panel, no incluye la alerta, teniendo que agregarla a mano junto con el nombre del dashboard. Una forma de realizar esto, es en base a un template, el cual puedes obtener de cualquier panel en formato JSON.
La posición también es almacenada dentro del JSON que exportas desde el panel. Por lo tanto, considera redimensionar a un tamaño apropiado para uno de cien paneles.
Para hacer el template, edita en los siguientes atributos de uno de los paneles a utilizar con una palabra común como “VAR” u “holi”.
Template:
- Metrics: Reemplazar dentro de la query la (/variable|regex/) por “VAR”.
- General/Title: “VAR”.
- Alert/Alert Config: Nombre de alerta + “VAR”.
- Alert/Notifications: La integración que corresponda.
Eso lo exportas como un JSON, ¿ahora qué?
Improvisas un script con unfor
que lea una lista con todos los hosts que debes agregar y que en base al template, haga un reemplazo de la “VAR” con cada host. Creando nuevos archivos con el formato.json en un directorio especifico. Algo así, pero mas lindo:
#!/usr/bin/env bash
cat host.txt | while read line; do
sed "s/VAR/$line/g" example.json > EXAMPLE/${line}.json
done
Ahora simplemente duplicas los paneles necesarios y modificas con los .json generados, dejando lista la alerta. Ya en este caso si tienes que editar algo, vendría siendo el limite de cada alerta.
Hay un limite que cruza el panel común
Conclusión 5️⃣ 🆚 1️⃣0️⃣0️⃣
En el día a día, dependerá de lo que tengas que monitorear y hacer con las alertas, ademas de alertar. Al verte en la situación del caso de ejemplo, teniendo toda la información sobre los beneficios de los métodos presentados, una combinación de ambas soluciones sería lo más eficiente.
Sí tuvieses que generar reportes de frecuencia de incidentes y desempeño de cosas que se rompen cada cierto tiempo. No sería posible al agrupar un conjunto de servicios en un solo panel, perdiendo la visibilidad. En cambio, sacrificando la belleza estética de tu dashboard con múltiples paneles, lo lograrías.
La próxima vez que consideres usar una herramienta de visualización para alertar, ten en cuenta todo lo anterior.
La respuesta final a la cantidad de paneles necesarios para resolver el caso hipotético es:
“*️⃣”