Gestione semplice di avvisi complessi. O la storia della creazione di Balerter

Gestione semplice di avvisi complessi. O la storia della creazione di Balerter

Tutti amano le notifiche.

Certo, è molto meglio ricevere un avviso quando qualcosa è accaduto (o si è sistemato) piuttosto che stare a guardare grafici e cercare anomalie.

E ci sono diversi strumenti creati per questo. Alertmanager dall'ecosistema Prometheus e vmalert dal gruppo di prodotti VictoriaMetrics. Notifiche Zabbix e avvisi in Grafana. Script personalizzati in bash e bot di Telegram che controllano periodicamente un certo URL e segnalano se c'è qualcosa che non va. Ce n'è di tutto.

Anche nella nostra azienda abbiamo usato diverse soluzioni, fino a quando non ci siamo scontrati con la complessità, o meglio, l'impossibilità di creare avvisi complessi e compositi. Cosa desideravamo e cosa abbiamo fatto alla fine — nel seguito. TLDR: Così è nato il progetto open source Balerter

Per un periodo, siamo andati bene con gli avvisi configurati in Grafana. Sì, non è la strada migliore. Si consiglia sempre di utilizzare soluzioni specializzate, come Alertmanager. E abbiamo anche considerato più di una volta di migrare. Poi, piano piano, abbiamo iniziato a desiderare di più.

Dire quando un certo grafico è calato/aumentato del XX% e ci si trova lì già da N minuti rispetto al periodo precedente di M ore? Sembrerebbe possibile realizzarlo con Grafana o Alertmanager, ma non è affatto semplice. (E forse nemmeno possibile, in questo momento non lo so).

Tutto diventa ancora più complicato quando la decisione su un avviso deve essere presa basandosi su dati provenienti da fonti diverse. Un esempio pratico:

Controlliamo i dati da due database Clickhouse, confrontiamo poi con alcuni dati da Postgres e prendiamo la decisione sull'avviso. Segnalare oppure annullare.

Abbiamo accumulato abbastanza richieste simili da farci pensare a una nostra soluzione. Così abbiamo provato a redigere la prima lista di requisiti/possibilità di questo servizio, ancora da creare.

  • interrogare diverse fonti di dati. Ad esempio, Prometheus, Clickhouse, Postgres.

  • inviare avvisi a diversi canali — telegram, slack, ecc.

  • nel processo di riflessione è diventato chiaro che desideravamo non una descrizione dichiarativa, ma la possibilità di scrivere script.

  • eseguire script in base a un programma.

  • facile aggiornamento degli script senza riavviare il servizio.

  • possibilità di ampliare le funzionalità senza ricompilare il servizio dai codici sorgente.

Questa è una lista indicativa e, molto probabilmente, non molto precisa. Alcuni punti sono stati modificati, altri sono stati abbandonati. Tutto come al solito.

Infatti, è così che è iniziata la storia di Balerter.

Gestione semplice di avvisi complessi. O la storia della creazione di Balerter

Cercherò di descrivere brevemente cosa è stato ottenuto e come funziona. (Sì, certo, non è la fine. Ci sono molti piani per lo sviluppo del prodotto. Mi fermerò solo al giorno di oggi)

Come funziona?

Scrivi uno script in Lua, dove invii chiaramente richieste (a Prometheus, Clickhouse, ecc.). Ricevi risposte e in qualche modo le elabori e le confronti. Dopodiché attivi/disattivi un qualche alert. Balerter invierà automaticamente una notifica nei canali che hai configurato (Email, telegram, slack, ecc.). Lo script viene eseguito con periodicità definita. E... in sostanza è tutto)

È meglio mostrare con un esempio:

-- @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("errore di query 'ch1' in clickhouse: " .. err)
    return
end

local resultRPS = res[1].rps

if resultRPS < minResultRPS then
    alert.error("rps-min-limit", "Le richieste RPS sono molto basse: " .. tostring(resultRPS))
else
    alert.success("rps-min-limit", "Richieste RPS ok")
end 

Cosa sta succedendo qui:

  • indichiamo che questo script deve essere eseguito ogni 10 secondi

  • indichiamo il nome dello script (per l'API, per visualizzarlo nei log, per utilizzarlo nei test)

  • collegiamo il modulo per la registrazione dei log

  • collegiamo il modulo per accedere al clickhouse con nome ch1 (la connessione stessa è configurata nel file di configurazione)

  • inviamo una richiesta al clickhouse

  • in caso di errore - scriviamo un messaggio nel log e usciamo

  • confrontiamo il risultato della richiesta con la costante (in un esempio reale potremmo ottenere questo valore, ad esempio, dal database Postgres)

  • attiviamo o disattiviamo l'alert con ID rps-min-limit

  • riceverai una notifica se lo stato dell'alert cambia

L'esempio è abbastanza semplice e chiaro. Tuttavia, naturalmente, nella vita reale gli script possono diventare piuttosto complessi e intricati. È facile confondersi e commettere errori.

Pertanto, è nato il desiderio logico di avere la possibilità di scrivere test per i propri script. E con la versione v0.4.0, questo è arrivato.

Testing degli script

Ecco un esempio di test per il nostro script dall'esempio precedente:

-- @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', 'Le richieste RPS sono molto basse: 10')
test.alert().assertNotCalled('success', 'rps-min-limit', 'Richieste RPS ok')

Passo dopo passo:

  • indichiamo il nome dello script per il quale è stato scritto il test

  • il nome del test (per i log)

  • colleghiamo il modulo di test

  • parliamo di quale risultato deve essere restituito per una determinata richiesta a ClickHouse ch1

  • controlliamo che sia stato chiamato l'alert (errore) rps-min-limit con il messaggio specificato

  • controlliamo che l'alert rps-min-limit non sia stato disattivato (successo)

Cosa può fare ancora Balerter?

Cercherò di toccare le abilità più importanti, secondo me, di Balerter. Puoi vedere tutto in dettaglio sul sito ufficiale https://balerter.com

  • ricevere dati da

    • clickhouse

    • postgres

    • mysql

    • prometheus

    • loki

  • inviare notifiche ai canali

    • slack

    • telegram

    • syslog

    • notiify (notifiche UI sul tuo computer)

    • email

    • discord

  • costruire grafici dai tuoi dati, caricare immagini in un deposito compatibile con S3 e allegarle alle notifiche (Esempio con immagini)

  • permette di scambiare dati tra gli script — un'archiviazione Key/Value globale

  • scrivere le proprie librerie in Lua e usarle negli script (per impostazione predefinita sono fornite librerie lua per lavorare con json, csv)

  • inviare richieste HTTP dai tuoi script (e ricevere risposte, ovviamente)

  • fornisce API (ancora non funzionale come vorremmo)

  • esporta metriche nel formato Prometheus

E cosa ci piacerebbe ancora sapere?

È già chiaro che gli utenti e noi vogliamo poter gestire l'esecuzione degli script utilizzando la sintassi cron. Questo sarà fatto prima della versione v1.0.0

Desideriamo supportare più fonti di dati e canali di consegna delle notifiche. Ad esempio, ad alcuni mancherà sicuramente MongoDB. Ad altri Elastic Search. Inviare SMS e/o fare chiamate sui cellulari. Vogliamo poter ricevere script non solo da file, ma anche, ad esempio, da database. Infine, vogliamo un sito più comodo e una documentazione migliore per il progetto.

A qualcuno manca sempre qualcosa) Qui speriamo nella richiesta della comunità, per stabilire correttamente le priorità. E nell'aiuto della comunità per realizzare tutto

In conclusione

Lo usiamo Balerter da un bel po' di tempo. Decine di script proteggono la nostra tranquillità. Spero che questo lavoro sia utile anche a qualcun altro.

E benvenuto con i tuoi issue e PR.

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster