Trabajo fácil con alertas complejas. O la historia de la creación de Balerter

Trabajo fácil con alertas complejas. O la historia de la creación de Balerter

A todo el mundo le encantan las alertas.

Por supuesto, es mucho mejor recibir una notificación cuando algo sucede (o se soluciona) que sentarse y mirar gráficos y buscar anomalías.

Y se han creado muchas herramientas para ello. Alertmanager del ecosistema Prometheus y vmalert del grupo de productos VictoriaMetrics. Notificaciones y alertas de Zabbix en Grafana. Scripts autoescritos en bash y bots de Telegram que periódicamente obtienen alguna URL y le indican si algo anda mal. Mucho de todo.

Nosotros, en nuestra empresa, también utilizamos diferentes soluciones hasta que nos topamos con la complejidad, o más bien la imposibilidad, de crear alertas complejas y compuestas. Lo que queríamos y lo que terminamos haciendo está por debajo del corte. TLDR: así apareció el proyecto de código abierto Balerter

Durante bastante tiempo vivimos bien con las alertas configuradas en Grafana. Sí, esta no es la mejor manera. Siempre se recomienda utilizar algunas soluciones especializadas, como Alertmanager. Y también miramos hacia la mudanza más de una vez. Y luego, poco a poco, quisimos más.

Digamos, ¿cuándo un determinado gráfico ha caído/aumentado en un XX% y ha estado allí durante N minutos en comparación con el período anterior de M horas? Parece que puedes intentar implementar esto con Grafana o Alertmanager, pero no es del todo fácil. (O tal vez no sea posible, no lo diré ahora)

Las cosas se complican aún más cuando la decisión de alerta debe tomarse en base a datos de diferentes fuentes. Ejemplo en vivo:

Verificamos los datos de dos bases de datos de Clickhouse, luego los comparamos con algunos datos de Postgres y decidimos sobre una alerta. Señalar o cancelar

Hemos acumulado bastantes deseos similares para que pensemos en nuestra decisión. Y luego intentamos compilar la primera lista de requisitos/capacidades 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 pensar, quedó claro que no quería una descripción declarativa, sino la capacidad de escribir guiones.

  • ejecutar scripts según un cronograma

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

  • la capacidad de expandir de alguna manera la funcionalidad sin reconstruir el servicio a partir de códigos fuente

Esta lista es aproximada y probablemente no muy precisa. Algunos puntos cambiaron, otros murieron. Todo es como siempre.

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

Trabajo fácil con alertas complejas. O la historia de la creación de Balerter

Intentaré describir brevemente lo que sucedió al final y cómo funciona. (Sí, por supuesto, este no es el final. Hay muchos planes para el desarrollo de productos. Me detendré en hoy)

Como funciona?

Escribe un script en Lua donde envía solicitudes explícitamente (a Prometheus, Clickhouse, etc.). Recibes respuestas y de alguna manera las procesas y comparas. Luego activa/desactiva algún tipo de alerta. El propio Balerter enviará una notificación a los canales que tengas configurados (Email, telegram, slack, etc.). El script se ejecuta a intervalos específicos. Y... en general, 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("clickhouse 'ch1' query error: " .. err)
    return
end

local resultRPS = res[1].rps

if resultRPS < minResultRPS then
    alert.error("rps-min-limit", "Requests RPS are very small: " .. tostring(resultRPS))
else
    alert.success("rps-min-limit", "Requests RPS ok")
end 

Que está pasando aqui:

  • indicamos que este script debe ejecutarse cada 10 segundos

  • indique el nombre del script (para la API, para mostrar en registros, para usar en pruebas)

  • conecte el módulo para generar registros

  • conecta un módulo para acceder al clickhouse con el nombre ch1 (la conexión en sí está configurada en la configuración)

  • enviar una solicitud a clickhouse

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

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

  • habilitar o deshabilitar alerta con ID rps-min-limit

  • Recibirás una notificación si el estado de la alerta ha cambiado.

El ejemplo es bastante simple y comprensible. Sin embargo, por supuesto, en la vida real los guiones pueden ser bastante largos y complejos. Es fácil confundirse y cometer errores.

Por lo tanto, ha madurado un deseo lógico: poder escribir pruebas para sus scripts. Y en la versión v0.4.0 apareció esto.

Guiones de prueba

Prueba de ejemplo 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', 'Requests RPS are very small: 10')
test.alert().assertNotCalled('success', 'rps-min-limit', 'Requests RPS ok')

En pasos:

  • indicar el nombre del script para el cual está escrita la prueba

  • nombre de la prueba (para registros)

  • conectar el módulo de prueba

  • decimos qué resultado se debe devolver para una solicitud específica al clickhouse ch1

  • comprobamos que se llamó la alerta (error) rps-min-limit con el mensaje especificado

  • comprobar que la alerta rps-min-limit no estaba deshabilitada (éxito)

¿Qué más puede hacer Balerter?

Intentaré abordar las habilidades más importantes, en mi opinión, de Balerter. Puedes ver todo en detalle en la web oficial https://balerter.com

  • recibir datos de

    • casa de clics

    • Postgres

    • mysql

    • Prometeo

    • loki

  • enviar notificaciones a canales

    • flojo

    • Telegram.

    • syslog

    • notificar (notificaciones de UI en su computadora)

    • email

    • discord

  • cree gráficos basados ​​en sus datos, cargue la imagen en un almacenamiento compatible con S3 y adjúntela a las notificaciones (Ejemplo con fotos)

  • le permite intercambiar datos entre scripts: almacenamiento global de clave/valor

  • escriba sus propias bibliotecas en Lua y úselas en scripts (de forma predeterminada, las bibliotecas lua se proporcionan para trabajar con json, csv)

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

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

  • exporta métricas en formato Prometheus

¿Qué más te gustaría poder hacer?

Ya está claro que los usuarios y nosotros queremos tener la capacidad de controlar el lanzamiento de scripts utilizando la sintaxis. cron. Esto se hará antes de la versión v1.0.0.

Me gustaría admitir más fuentes de datos y canales de entrega de notificaciones. Por ejemplo, alguien definitivamente extrañará MongoDB. Búsqueda elástica para algunos. Envía SMS y/o realiza llamadas a tu teléfono móvil. Queremos poder recibir scripts no sólo de archivos, sino también, por ejemplo, de una base de datos. Al final, queremos un sitio web más fácil de usar y mejor documentación para el proyecto.

Siempre a alguien le falta algo) Aquí nos basamos en la solicitud de la comunidad para establecer las prioridades correctamente. Y a la ayuda de la comunidad para realizar todo.

en conclusión

Usamos Balerter Lo tengo desde hace bastante tiempo. Decenas de guiones guardan nuestra tranquilidad. Espero que este trabajo sea útil para alguien más.

Y bienvenido con su problema y relaciones públicas.

Fuente: habr.com

Añadir un comentario