Trabajo sencillo con alertas complejas. O la historia detrás de Balerter

Trabajo sencillo con alertas complejas. O la historia detrás de Balerter

A todos les gustan las alertas.

Por supuesto, es mucho mejor recibir una notificación cuando algo sucede (o se repara) que quedarse mirando gráficos buscando anomalías.

Hay muchas herramientas creadas para esto. Alertmanager del ecosistema Prometheus y vmalert del grupo de productos VictoriaMetrics. Notificaciones de zabbix y alertas en Grafana. Scripts propios en bash y bots de Telegram que periódicamente consultan alguna URL y avisan si algo no está bien. Hay mucho disponible.

Nosotros, en nuestra empresa, también utilizamos diferentes soluciones hasta que nos encontramos con la complejidad, o más bien, la imposibilidad de crear alertas complejas y compuestas. Lo que queríamos y lo que finalmente hicimos — debajo del enlace. TLDR: Así nació el proyecto de código abierto Balerter

Durante bastante tiempo, vivimos razonablemente bien con las alertas configuradas en Grafana. Sí, no es el mejor camino. Siempre se recomienda utilizar soluciones especializadas, como Alertmanager. Y también, en varias ocasiones, consideramos mudarnos. Luego, poco a poco, empezamos a desear más.

¿Decir cuándo un gráfico ha caído/aumentado un XX% y ha estado ahí durante N minutos en comparación con el período anterior de M horas? Esto, parece, se podría intentar implementar con Grafana o Alertmanager, pero no es nada sencillo. (O tal vez no se pueda, no lo sé ahora)

Todo se vuelve aún más complicado cuando la decisión sobre la alerta debe tomarse basándose en datos de diferentes fuentes. Un ejemplo en vivo:

Verificamos datos de dos bases de datos de Clickhouse, luego comparamos con algunos datos de Postgres y tomamos una decisión sobre la alerta. Señalizar o cancelar.

Hemos acumulado suficientes deseos similares como para pensar en nuestra propia solución. Entonces intentamos elaborar la primera lista de requisitos/posibilidades de este servicio que aún no se ha creado.

  • acceder a diferentes fuentes de datos. Por ejemplo, Prometheus, Clickhouse, Postgres.

  • enviar alertas a varios canales — telegram, slack, etc.

  • en el proceso de reflexión, se hizo evidente que queríamos no solo una descripción declarativa, sino la capacidad de escribir scripts.

  • ejecutar scripts programados.

  • actualización fácil de scripts sin reiniciar el servicio.

  • posibilidad de ampliar funciones sin recompilar el servicio desde el código fuente.

Esta es una lista aproximada y, probablemente, no muy precisa. Algunos puntos cambiaron, otros se eliminaron. Todo como de costumbre.

En realidad, así comenzó la historia de Balerter.

Trabajo sencillo con alertas complejas. O la historia detrás de Balerter

Intentaré describir brevemente lo que ha resultado y cómo funciona. (Sí, por supuesto, esto no es el final. Hay muchos planes para el desarrollo del producto. Simplemente me detendré en el día de hoy)

¿Cómo funciona?

Escribís un script en Lua, donde envías claramente solicitudes (a Prometheus, Clickhouse, etc.). Recibes respuestas y las procesas y comparas de alguna manera. Después, enciendes/apagas alguna alerta. Balerter enviará notificaciones a los canales que hayas configurado (Email, telegram, slack, etc.). El script se ejecuta con una periodicidad determinada. Y… eso es todo)

Lo mejor es mostrarlo con un ejemplo:

-- @interval 10s
-- @name script1

local minRequestsRPS = 100

local log = require("log")
local ch1 = require("datasource.clickhouse.ch1")

local res, err = ch1.query("SELECT sum(requests) AS rps FROM some_table WHERE date = now()")
if err ~= nil then
    log.error("error de consulta de clickhouse 'ch1': " .. err)
    return
end

local resultRPS = res[1].rps

if resultRPS < minRequestsRPS then
    alert.error("rps-min-limit", "Las solicitudes RPS son muy bajas: " .. tostring(resultRPS))
else
    alert.success("rps-min-limit", "Las solicitudes RPS están bien")
end 

Lo que sucede aquí:

  • indicamos que este script debe ejecutarse cada 10 segundos

  • indicamos el nombre del script (para la API, para mostrarse en los logs, para usar en pruebas)

  • conectamos el módulo para la salida de logs

  • conectamos el módulo para acceder a Clickhouse con el nombre ch1 (la conexión en sí se configura en el archivo de configuración)

  • enviamos una solicitud a Clickhouse

  • en caso de error, mostramos un mensaje en el log y salimos

  • comparamos el resultado de la consulta con la constante (en un ejemplo real, podríamos obtener este valor, por ejemplo, de una base de datos Postgres)

  • encendemos o apagamos la alerta con ID rps-min-limit

  • recibirás una notificación si el estado de la alerta cambia

El ejemplo es bastante simple y fácil de entender. Sin embargo, por supuesto, en la vida real, los scripts pueden ser bastante extensos y complejos. Es fácil confundirse y cometer errores.

Por lo tanto, surgió el deseo lógico de poder escribir pruebas para tus scripts. Y en la versión v0.4.0 esto se hizo realidad.

Pruebas de scripts

Ejemplo de prueba para nuestro script del ejemplo anterior:

-- @test script1
-- @name script1-test

test = require('test')

local resp = {
    {
        rps = 10
    }
} 

test.datasource('clickhouse.ch1').on('query', 'SELECT sum(requests) AS rps FROM some_table WHERE date = now()').response(resp)

test.alert().assertCalled('error', 'rps-min-limit', 'Las solicitudes RPS son muy bajas: 10')
test.alert().assertNotCalled('success', 'rps-min-limit', 'Las solicitudes RPS están bien')

Pasos:

  • indicamos el nombre del script para el cual se ha escrito la prueba

  • nombre de la prueba (para los logs)

  • conectamos el módulo de pruebas

  • decimos qué resultado se debe devolver ante una determinada solicitud a ClickHouse ch1

  • verificamos que se haya activado la alerta (error) rps-min-limit con el mensaje indicado

  • comprobamos que la alerta rps-min-limit no haya sido desactivada (éxito)

¿Qué más puede hacer Balerter?

Intentaré tocar las habilidades más importantes de Balerter, en mi opinión. Se puede ver todo detalladamente en el sitio oficial https://balerter.com

  • obtener datos de

    • clickhouse

    • postgres

    • mysql

    • prometheus

    • loki

  • enviar notificaciones a canales

    • slack

    • telegram

    • syslog

    • notiify (notificaciones en la interfaz de su computadora)

    • correo electrónico

    • discord

  • crear gráficos a partir de sus datos, cargar imágenes en un almacenamiento compatible con S3 y adjuntarlas a las notificaciones (Ejemplo con imágenes)

  • permite intercambiar datos entre scripts - un almacenamiento global de clave/valor

  • escribir sus propias bibliotecas en Lua y usarlas en scripts (por defecto se incluyen bibliotecas de lua para trabajar con json, csv)

  • enviar solicitudes HTTP desde sus scripts (y recibir respuestas, por supuesto)

  • proporciona API (aún no tan funcional como nos gustaría)

  • exporta métricas en formato Prometheus

¿Y qué más nos gustaría poder hacer?

Ya está claro que tanto los usuarios como nosotros deseamos la capacidad de gestionar la ejecución de scripts mediante la sintaxis cron. Esto se hará antes de la versión v1.0.0

Nos gustaría soportar más fuentes de datos y canales de entrega de notificaciones. Por ejemplo, a alguien seguramente le faltará MongoDB. A alguien más, Elastic Search. Enviar SMS o hacer llamadas a móviles. Queremos poder obtener scripts no solo de archivos, sino, por ejemplo, de bases de datos. Al final, queremos para el proyecto un sitio más accesible y documentación de mejor calidad.

Siempre hay algo que a alguien le falta) Aquí esperamos la solicitud de la comunidad para establecer correctamente las prioridades. Y la ayuda de la comunidad para hacer realidad todo.

En conclusión

Utilizamos Balerter ya desde hace un tiempo. Decenas de scripts protegen nuestra tranquilidad. Espero que este trabajo sea útil para alguien más.

Y bienvenidos con sus Issue y PR.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster