
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
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.

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-limitrecibirá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
ch1verificamos 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
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 ()
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 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
