
Wszyscy lubią alerty.
Oczywiście, znacznie lepiej otrzymać powiadomienie, gdy coś się wydarzyło (lub naprawiło), niż siedzieć, patrzeć na wykresy i szukać anomalii.
I stworzono wiele narzędzi do tego celu. Alertmanager z ekosystemu Prometheus i vmalert z grupy produktów VictoriaMetrics. Powiadomienia zabbix i alerty w Grafanie. Skrypty napisane w bash i boty Telegram, które okresowo sprawdzają jakiś URL i informują, jeśli coś jest nie tak. Naprawdę dużo tego.
My, w naszej firmie, również korzystaliśmy z różnych rozwiązań, aż napotkaliśmy na trudności, a właściwie niemożność stworzenia skomplikowanych, złożonych alertów. To, czego chcieliśmy, i co w końcu zrobiliśmy — poniżej. TLDR: Tak powstał projekt open source
Dość długo dobrze żyliśmy z alertami skonfigurowanymi w Grafanie. Tak, to nie jest najlepsza droga. Zawsze zaleca się używanie jakichś wyspecjalizowanych rozwiązań, takich jak Alertmanager. I my również wielokrotnie rozważaliśmy migrację. A potem, powoli, zapragnęliśmy więcej.
Powiedzieć, kiedy wykres spadł/wzrosł o XX% i znajduje się tam już N minut w porównaniu do poprzedniego okresu w M godzin? To wydaje się możliwe do zrealizowania w Grafanie lub Alertmanagerze, ale raczej nie jest to łatwe. (A może nawet nie jest możliwe, w tej chwili nie jestem pewien)
Wszytko staje się jeszcze bardziej skomplikowane, gdy decyzję o alercie należy podjąć na podstawie danych z różnych źródeł. Żywy przykład:
Sprawdzamy dane z dwóch baz Clickhouse, a następnie porównujemy je z niektórymi danymi z Postgresa i podejmujemy decyzję o alercie. Sygnalizować lub anulować.
Mieliśmy już sporo podobnych wymagań, byśmy zaczęli myśleć o naszym rozwiązaniu. I wtedy spróbowaliśmy stworzyć pierwszą listę wymagań/możliwości tego, jeszcze nie stworzonego, serwisu.
odnosić się do różnych źródeł danych. Na przykład, Prometheus, Clickhouse, Postgres.
wysyłać alerty do różnych kanałów — telegram, slack itp.
W trakcie rozmyślania stało się jasne, że chcemy nie deklaratywnego opisu, a możliwości pisania skryptów.
uruchamianie skryptów według harmonogramu.
łatwe aktualizowanie skryptów bez ponownego uruchamiania usługi.
możliwość rozszerzania funkcjonalności bez ponownego kompilowania usługi z kodu źródłowego.
To przykładowa lista, która prawdopodobnie nie jest bardzo dokładna. Niektóre punkty zmieniały się, inne umierały. Wszystko jak zwykle.
Właściwie tak właśnie rozpoczęła się historia Balerter.

Postaram się krótko opisać, co ostatecznie udało się osiągnąć i jak to działa. (Tak, oczywiście, to nie jest koniec. Mamy wiele planów na rozwój produktu. Po prostu skupię się na dniu dzisiejszym)
Jak to działa?
Piszesz skrypt w Lua, w którym wyraźnie wysyłasz zapytania (do Prometheus, Clickhouse itd.). Otrzymujesz odpowiedzi i jakoś je przetwarzasz i porównujesz. Następnie włączasz/wyłączasz jakiś alert. Balerter sam wyśle powiadomienie do kanałów, które skonfigurowałeś (Email, telegram, slack itd.). Skrypt wykonuje się w ustalonych odstępach czasu. I… to właściwie wszystko)
Najlepiej pokazać na przykładzie:
-- @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("błąd zapytania 'ch1' w clickhouse: " .. err)
return
end
local resultRPS = res[1].rps
if resultRPS < minResultRPS then
alert.error("rps-min-limit", "Requests RPS są bardzo małe: " .. tostring(resultRPS))
else
alert.success("rps-min-limit", "Requests RPS w porządku")
end Co tu się dzieje:
określamy, że ten skrypt powinien być wykonywany co 10 sekund
określamy nazwę skryptu (dla API, do wyświetlania w logach, do użycia w testach)
łączymy moduł do wyprowadzania logów
łączymy moduł do dostępu do clickhouse o nazwie
ch1(samo połączenie konfiguruje się w pliku konfiguracyjnym)wysyłamy zapytanie do clickhouse
w przypadku błędu — wyprowadzamy komunikat do logu i wychodzimy
porównujemy wynik zapytania z stałą (w rzeczywistym przykładzie moglibyśmy tę wartość uzyskiwać, na przykład, z bazy Postgres)
włączamy lub wyłączamy alert o ID
rps-min-limitotrzymasz powiadomienie, jeśli status alertu się zmieni
Przykład jest dość prosty i zrozumiały. Jednak w rzeczywistości skrypty mogą być dosyć rozwlekłe i skomplikowane. Łatwo w nich się pogubić i popełnić błędy.
Dlatego pojawiła się logiczna chęć — możliwość napisania testów dla swoich skryptów. I w wersji v0.4.0 to się pojawiło.
Testowanie skryptów
Przykład testu dla naszego skryptu z powyższego przykładu:
-- @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 są bardzo małe: 10')
test.alert().assertNotCalled('success', 'rps-min-limit', 'Requests RPS w porządku')Kroki:
określamy nazwę skryptu, dla którego napisano test
nazwa testu (do logów)
łączymy moduł do testowania
mówimy, jaki wynik należy zwrócić przy określonym zapytaniu do ClickHouse
ch1sprawdzamy, czy został wywołany alert (error) rps-min-limit z podanym komunikatem
sprawdzamy, czy alert rps-min-limit nie został wyłączony (success)
Co jeszcze potrafi Balerter?
Spróbuję poruszyć najważniejsze umiejętności Balerter, według mojej opinii. Szczegóły można zobaczyć na oficjalnej stronie
pobierać dane z
clickhouse
postgres
mysql
prometheus
loki
wysyłać powiadomienia do kanałów
slack
telegram
syslog
notiify (powiadomienia UI na twoim komputerze)
email
discord
budować wykresy na podstawie twoich danych, przesyłać obrazy do kompatybilnego z S3 magazynu i dołączać je do powiadomień ()
umożliwia wymianę danych między skryptami — globalna pamięć Key/Value
pisanie własnych bibliotek w Lua i używanie ich w skryptach (domyślnie dostarczane są biblioteki lua do pracy z json, csv)
wysyłać zapytania HTTP z twoich skryptów (no i oczywiście odbierać odpowiedzi)
oferuje API (jeszcze nie tak funkcjonalne, jak byśmy chcieli)
eksportuje metryki w formacie Prometheus
A czego jeszcze chcielibyśmy się nauczyć?
Już widać, że użytkownicy i my chcemy mieć możliwość zarządzania uruchamianiem skryptów za pomocą składni cron. To będzie zrealizowane przed wersją v1.0.0
Chcielibyśmy wspierać więcej źródeł danych i kanałów dostarczania powiadomień. Na przykład komuś może zabraknąć MongoDB. Ktoś inny może potrzebować Elastic Search. Wysyłać SMS i/lub wykonywać połączenia telefoniczne na komórkę. Chcemy również móc pobierać skrypty nie tylko z plików, ale i na przykład z bazy danych. Ostatecznie chcielibyśmy, aby projekt miał bardziej przyjazną stronę oraz lepszą dokumentację.
Zawsze komuś czegoś brakuje) Tutaj liczymy na zapotrzebowanie społeczności, aby prawidłowo ustalić priorytety. I na pomoc społeczności, aby wszystko zrealizować.
Na zakończenie
Używamy mamy go już od jakiegoś czasu. Dziesiątki skryptów strzegą naszego spokoju. Mam nadzieję, że ta praca będzie przydatna także dla innych.
I zapraszamy do zgłaszania swoich Issue i PR.
Źródło: habr.com
