
Alle lieben Alerts.
Natürlich ist es viel besser, eine Benachrichtigung zu erhalten, wenn etwas passiert ist (oder repariert wurde), als dazusitzen, auf Grafiken zu schauen und nach Anomalien zu suchen.
Und dafür gibt es viele Tools. Alertmanager aus dem Prometheus-Ökosystem und vmalert aus der VictoriaMetrics-Produktgruppe. Zabbix-Benachrichtigungen und Alerts in Grafana. Selbstgeschriebene Skripte in Bash und Telegram-Bots, die periodisch eine bestimmte URL abfragen und mitteilen, wenn etwas nicht stimmt. Eine Menge Möglichkeiten.
Auch wir in unserem Unternehmen haben verschiedene Lösungen verwendet, bis wir auf die Komplexität, oder eher, die Unmöglichkeit gestoßen sind, komplexe, zusammengesetzte Alerts zu erstellen. Was wir uns gewünscht haben und was wir letztendlich erreicht haben – im Folgenden. TLDR: So entstand das Open-Source-Projekt
Lange Zeit lebten wir gut mit den in Grafana eingerichteten Alerts. Ja, das ist nicht der beste Weg. Es wird immer empfohlen, spezielle Lösungen wie Alertmanager zu verwenden. Und auch wir haben mehrere Male in Richtung eines Umzugs geschaut. Doch dann, nach und nach, wuchs unser Wunsch nach mehr.
Benachrichtigen, wenn ein Diagramm um XX % gefallen oder gestiegen ist und seit N Minuten im Vergleich zum vorherigen Zeitraum von M Stunden dort bleibt? Das scheint man vielleicht mit Grafana oder Alertmanager umsetzen zu können, ist aber ziemlich kompliziert. (Oder vielleicht auch nicht, das kann ich jetzt nicht sagen.)
Es wird noch komplizierter, wenn die Entscheidung über den Alert auf Basis von Daten aus verschiedenen Quellen getroffen werden muss. Ein praktisches Beispiel:
Wir überprüfen die Daten aus zwei Clickhouse-Datenbanken, vergleichen dann einige Daten aus Postgres und treffen die Entscheidung über den Alert. Signalisieren oder abbrechen.
Wir haben so viele ähnliche Anforderungen gesammelt, dass wir über eine eigene Lösung nachgedacht haben. Deshalb haben wir versucht, die erste Liste an Anforderungen/Möglichkeiten für diesen noch nicht geschaffenen Dienst zu erstellen.
Zugriff auf verschiedene Datenquellen. Zum Beispiel Prometheus, Clickhouse, Postgres.
Alerts an verschiedene Kanäle senden — Telegram, Slack usw.
Während der Überlegungen wurde klar, dass wir keine deklarative Beschreibung wollen, sondern die Möglichkeit, Skripte zu schreiben.
Skripte nach einem Zeitplan ausführen.
Einfache Aktualisierung von Skripten ohne Neustart des Dienstes.
Die Möglichkeit, die Funktionalität ohne Neubau des Dienstes aus dem Quellcode zu erweitern.
Dies ist eine ungefähre Liste und wahrscheinlich nicht sehr genau. Einige Punkte haben sich verändert, andere sind weggefallen. Alles wie gewohnt.
So begann die Geschichte von Balerter.

Ich werde versuchen, kurz zu beschreiben, was dabei herausgekommen ist und wie es funktioniert. (Ja, das ist natürlich nicht das Ende. Es gibt viele Pläne zur Weiterentwicklung des Produkts. Ich beschränke mich einfach auf den heutigen Stand.)
Wie funktioniert das?
Sie schreiben ein Skript in Lua, in dem Sie explizit Anfragen senden (an Prometheus, Clickhouse usw.). Sie erhalten Antworten und verarbeiten und vergleichen diese auf verschiedene Weise. Danach schalten Sie einen Alert ein oder aus. Balerter sendet selbst Benachrichtigungen an die Kanäle, die Sie eingerichtet haben (E-Mail, Telegram, Slack usw.). Das Skript wird in einem festgelegten Intervall 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' query error: " .. err)
return
end
local resultRPS = res[1].rps
if resultRPS < minResultRPS 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 Skriptnamen an (für die API, zur Anzeige in Logs, für Tests)
wir binden das Modul für die Log-Ausgabe ein
wir binden das Modul für den Zugriff auf ClickHouse mit dem Namen
ch1(die eigentliche Verbindung wird in der Konfiguration eingestellt)wir senden die Anfrage an ClickHouse
im Falle eines Fehlers — wir geben eine Meldung im Log aus und brechen ab
wir vergleichen das Ergebnis der Anfrage mit einer Konstante (im Live-Beispiel könnten wir diesen Wert beispielsweise aus einer Postgres-Datenbank erhalten)
wir aktivieren oder deaktivieren den Alert mit der ID
rps-min-limitSie erhalten eine Benachrichtigung, wenn sich der Status des Alerts ändert
Das Beispiel ist recht einfach und verständlich. In der Realität können Skripte jedoch durchaus umfangreich und komplex sein. Es ist leicht, sich darin zu verirren und Fehler zu machen.
Daher entstand der Wunsch — die Möglichkeit zu haben, Tests für seine Skripte zu schreiben. Und in der Version v0.4.0 wurde dies möglich.
Testing von Skripten
Ein Beispieltest für unser Skript aus dem obigen Beispiel:
-- @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')Schritt für Schritt:
wir geben den Namen des Skripts an, für das der Test geschrieben wurde
Name des Tests (für Logs)
Wir binden das Testmodul ein
Wir geben an, welches Ergebnis bei einer bestimmten Anfrage an ClickHouse zurückgegeben werden soll
ch1Wir prüfen, ob der Alert (Fehler) rps-min-limit mit der angegebenen Nachricht aufgerufen wurde
Wir prüfen, ob der Alert rps-min-limit nicht deaktiviert wurde (Erfolg)
Was kann Balerter noch?
Ich werde versuchen, die wichtigsten Fähigkeiten von Balerter zu beleuchten. Eine detaillierte Übersicht finden Sie auf der offiziellen Website.
Daten abrufen aus
clickhouse
postgres
mysql
prometheus
loki
Benachrichtigungen an Kanäle senden
slack
telegram
syslog
notiify (UI-Benachrichtigungen auf Ihrem Computer)
von
discord
Grafiken basierend auf Ihren Daten erstellen, Bilder in einem S3-kompatiblen Speicher hochladen und an Benachrichtigungen anhängen ()
ermöglicht den Austausch von Daten zwischen Skripten — globaler Key/Value-Speicher
Schreiben Sie Ihre Bibliotheken in Lua und verwenden Sie sie in Skripten (standardmäßig werden Lua-Bibliotheken zum Arbeiten mit JSON und CSV mitgeliefert)
HTTP-Anfragen aus Ihren Skripten senden (und natürlich auch Antworten erhalten)
stellt eine API zur Verfügung (noch nicht so funktional, wie ich es mir wünschen würde)
exportiert Metriken im Prometheus-Format
Was möchten Sie noch können?
Es ist bereits klar, dass die Benutzer und wir die Möglichkeit wünschen, die Ausführung von Skripten mithilfe von Syntax zu steuern cron. Dies wird bis zur Version v1.0.0 umgesetzt werden
Wir möchten mehr Datenquellen und Benachrichtigungskanäle unterstützen. Zum Beispiel wird es jemanden geben, der MongoDB benötigt. Jemand anderem wird Elastic Search fehlen. SMS senden und/oder Anrufe auf Mobiltelefone tätigen. Wir möchten Skripte nicht nur aus Dateien, sondern auch beispielsweise aus einer Datenbank erhalten. Schließlich streben wir eine benutzerfreundlichere Website und bessere Dokumentation für das Projekt an.
Irgendjemandem fehlt immer etwas) Hier hoffen wir auf die Anfragen der Gemeinschaft, um Prioritäten richtig zu setzen. Und auf die Unterstützung der Gemeinschaft, um alles zu realisieren
Zusammenfassung
Wir nutzen schon seit einiger Zeit. Dutzende Skripte wachen über unsere Ruhe. Ich hoffe, diese Arbeit wird auch jemand anderem nützlich sein.
Und herzlich willkommen mit Ihren Issues und PRs.
Quelle: habr.com
