Einfache Arbeit mit komplexen Alerts. Oder die Geschichte hinter Balerter.

Einfache Arbeit mit komplexen Alerts. Oder die Geschichte hinter Balerter.

Alle lieben Alarme.

Natürlich ist es viel besser, eine Benachrichtigung zu erhalten, wenn etwas passiert ist (oder repariert wurde), als nur auf Grafiken zu starren und nach Anomalien zu suchen.

Und es gibt viele Werkzeuge dafür. Alertmanager aus dem Prometheus-Ökosystem und vmalert aus der VictoriaMetrics-Produktgruppe. Zabbix-Benachrichtigungen und Alarme in Grafana. Selbstgeschriebene Skripte in Bash und Telegram-Bots, die regelmäßig eine URL abfragen und melden, wenn etwas nicht stimmt. Eine Menge.

Auch wir in unserem Unternehmen haben verschiedene Lösungen verwendet, bis wir auf die Komplexität oder vielmehr auf die Unmöglichkeit gestoßen sind, komplexe, zusammengesetzte Alarme zu erstellen. Was wir wollten und was wir letztendlich gemacht haben, steht im Folgenden. TLDR: So entstand das Open-Source-Projekt Balerter

Ziemlich lange hatten wir keine Probleme mit Alarme, die in Grafana eingerichtet waren. Ja, das ist nicht der beste Weg. Es wird immer empfohlen, spezialisierte Lösungen wie Alertmanager zu verwenden. Auch wir haben mehrmals darüber nachgedacht, zu wechseln. Und dann wollten wir allmählich mehr.

Zu sagen, dass ein Diagramm um XX% gefallen/gestiegen ist und seit N Minuten dort ist im Vergleich zum vorherigen Zeitraum von M Stunden? Das scheint man mit Grafana oder Alertmanager versuchen zu können, aber ziemlich kompliziert. (Vielleicht geht es auch nicht, das kann ich jetzt nicht sagen)

Alles wird noch komplizierter, wenn die Entscheidung über einen Alarm auf der Grundlage von Daten aus verschiedenen Quellen getroffen werden muss. Ein lebendiges Beispiel:

Wir überprüfen Daten aus zwei Clickhouse-Datenbanken, vergleichen sie dann mit einigen Daten aus Postgres und treffen eine Entscheidung über den Alarm. Signalisiere oder storniere.

Solche Wünsche haben sich bei uns angesammelt, sodass wir über eine eigene Lösung nachgedacht haben. Und dann haben wir versucht, die erste Liste von Anforderungen/Möglichkeiten für diesen noch nicht geschaffenen Dienst zu erstellen.

  • auf verschiedene Datenquellen zugreifen. Zum Beispiel Prometheus, Clickhouse, Postgres.

  • Alarme in verschiedene Kanäle senden – Telegram, Slack usw.

  • Während des Nachdenkens wurde klar, dass wir nicht eine deklarative Beschreibung möchten, sondern die Möglichkeit, Skripte zu schreiben.

  • Skripte nach Zeitplan ausführen.

  • Einfache Aktualisierung von Skripten ohne Neustart des Dienstes.

  • Die Möglichkeit, die Funktionalität ohne Neukompilierung des Dienstes aus dem Quellcode zu erweitern.

Diese Liste ist beispielhaft und wahrscheinlich nicht sehr genau. Einige Punkte haben sich verändert, einige sind weggefallen. Alles wie üblich.

Tatächlich begann so die Geschichte von Balerter.

Einfache Arbeit mit komplexen Alerts. Oder die Geschichte hinter Balerter.

Ich werde versuchen, kurz zu beschreiben, was dabei herausgekommen ist und wie es funktioniert. (Ja, natürlich ist das nicht das Ende. Viele Pläne zur Weiterentwicklung des Produkts. Ich beschränke mich einfach auf den heutigen Tag)

Wie funktioniert das?

Sie schreiben ein Skript in Lua, in dem Sie eindeutig Anfragen senden (an Prometheus, Clickhouse usw.). Sie erhalten Antworten und verarbeiten und vergleichen sie auf eine bestimmte Weise. Danach aktivieren/deaktivieren Sie einen bestimmten Alarm. Balerter sendet die Benachrichtigung an die Kanäle, die Sie eingerichtet haben (E-Mail, Telegram, Slack usw.). Das Skript wird in festgelegten Intervallen ausgeführt. Und… das ist eigentlich alles)

Am besten zeigt man es anhand eines Beispiels:

-- @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' Abfragefehler: " .. err)
    return
end

local resultRPS = res[1].rps

if resultRPS < minRequestsRPS then
    alert.error("rps-min-limit", "Requests RPS sind sehr gering: " .. tostring(resultRPS))
else
    alert.success("rps-min-limit", "Requests RPS ok")
end 

Was hier passiert:

  • wir geben an, dass dieses Skript alle 10 Sekunden ausgeführt werden soll

  • wir geben den Namen des Skripts an (für die API, für die Anzeige in Logs, für die Verwendung in Tests)

  • wir binden das Modul für die Protokollausgabe ein

  • wir binden das Modul für den Zugriff auf Clickhouse mit dem Namen ch1 (die Verbindung wird in der Konfiguration eingerichtet)

  • wir senden eine Anfrage an Clickhouse

  • bei einem Fehler - geben wir eine Nachricht im Log aus und beenden

  • wir vergleichen das Ergebnis der Anfrage mit einer Konstante (im echten Beispiel könnten wir diesen Wert z.B. aus einer Postgres-Datenbank beziehen)

  • wir aktivieren oder deaktivieren den Alarm mit der ID rps-min-limit

  • Sie erhalten eine Benachrichtigung, wenn sich der Status des Alarms ändert

Das Beispiel ist ziemlich einfach und verständlich. In der realen Welt können Skripte jedoch sehr komplex und unübersichtlich sein. Es ist leicht, sich darin zu verirren und Fehler zu machen.

Deshalb entstand das logische Bedürfnis - die Möglichkeit zu haben, Tests für seine Skripte zu schreiben. Und in der Version v0.4.0 ist das nun möglich.

Tests von Skripten

Ein Beispieltest für unser oben genannten Skript:

-- @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 sind sehr gering: 10')
test.alert().assertNotCalled('success', 'rps-min-limit', 'Requests RPS ok')

Schritt für Schritt:

  • wir geben den Namen des Skripts an, für das der Test geschrieben wurde

  • Name des Tests (für die Logs)

  • wir binden das Testmodul ein

  • Wir sprechen darüber, welches Ergebnis bei einer bestimmten Abfrage an Clickhouse zurückgegeben werden soll. ch1

  • Wir überprüfen, ob der Alert (Fehler) rps-min-limit mit der angegebenen Nachricht ausgelöst wurde.

  • Wir überprüfen, dass der Alert rps-min-limit nicht deaktiviert wurde (Erfolg).

Was kann Balerter noch?

Ich werde versuchen, die wichtigsten Funktionen von Balerter zu berühren, meiner Meinung nach. Alles kann auf der offiziellen Website ausführlich angesehen werden. https://balerter.com

  • Daten aus

    • ClickHouse

    • in einer Umgebung, in der die Locale nicht UTF-8 ist, beispielsweise in einer leeren Umgebung (hier

    • mysql

    • Prometheus

    • Loki

  • Benachrichtigungen an Kanäle senden

    • Slack

    • Telegram

    • syslog

    • notify (UI-Benachrichtigungen auf Ihrem Computer)

    • email

    • Discord

  • Grafiken basierend auf Ihren Daten erstellen, Bilder in ein S3-kompatibles Speicher hochladen und an Benachrichtigungen anhängen (Beispiel mit Bildern)

  • ermöglicht den Datenaustausch zwischen Skripten – ein globaler Key/Value-Speicher.

  • Eigene Bibliotheken in Lua schreiben und sie in Skripten verwenden (standardmäßig werden Lua-Bibliotheken für die Arbeit mit JSON, CSV geliefert).

  • HTTP-Anfragen aus Ihren Skripten senden (und natürlich Antworten empfangen).

  • stellt eine API bereit (noch nicht so funktional, wie man es sich wünschen würde).

  • exportiert Metriken im Prometheus-Format.

Was möchten wir noch können?

Es ist bereits klar, dass Benutzer und wir die Möglichkeit wünschen, die Ausführung von Skripten mit Syntax zu steuern. Cron. Dies wird vor Version v1.0.0 umgesetzt.

Wir möchten mehr Datenquellen und Benachrichtigungskanäle unterstützen. Zum Beispiel wird jemand ganz sicher MongoDB nicht genug finden. Jemand anderem fehlt Elastic Search. SMS senden und/oder Anrufe auf Mobiltelefone durchführen. Wir wollen Skripte nicht nur aus Dateien, sondern auch beispielsweise aus einer Datenbank abrufen können. Schließlich streben wir eine benutzerfreundlichere Website und bessere Dokumentation für das Projekt an.

Es fehlt immer jemandem etwas) Hier hoffen wir auf die Nachfrage der Community, um die Prioritäten richtig zu setzen. Und auf die Hilfe der Community, um alles umzusetzen.

Abschließend

Wir verwenden Balerter seit geraumer Zeit. Dutzende Skripte wachen über unseren Frieden. Ich hoffe, diese Arbeit wird jemandem anderen nützlich sein.

Und willkommen mit Ihren Issues und PRs.

Quelle: habr.com

60GB SSD 8Gb DDR4