Bot do monitorowania usług internetowych w pół godziny: telegram + bash + cron

Bot do monitorowania usług internetowych w pół godziny: telegram + bash + cron

Czasami trzeba szybko przeprowadzić monitoring nowej usługi, a gotowej infrastruktury/ekspertyzy nie ma pod ręką. W tym przewodniku w pół godziny stworzymy narzędzie do monitorowania dowolnych usług internetowych, używając tylko wbudowanych narzędzi ubuntu: bash, cron i curl. Do dostarczania powiadomień użyjemy telegramu.

„Wisienką na torcie” będzie emocjonalne zaangażowanie użytkowników. Sprawdzone na ludziach – działa.

Kiedy w telemedycznym serwisie Doktor Rząd stworzyliśmy chatbota do określania poziomu stresu użytkowników, potrzebowaliśmy monitoringu. W ciągu kilku godzin stworzono mini-projekt, który nie tylko świetnie działa, ale także wnosi pozytywne emocje swoimi wiadomościami.

Na początek, pobierzmy repozytorium ze skryptami:

git clone https://github.com/rshekhovtsov/msms.git

Przechodzimy do folderu msms i dalej pracujemy w nim.

Jeśli telegram jest zablokowany, użyj proxy. Najprostszy i najpewniejszy sposób to torsocks:

sudo apt install tor
sudo apt install torsocks

Jako przykład skonfigurujemy monitoring startowej strony google.com w trzech krokach.

KROK 1. Tworzymy bota w telegramie i uzyskujemy id użytkownika.

  • W pasku wyszukiwania kontaktów w telegramie szukamy @botfather:

    Bot do monitorowania usług internetowych w pół godziny: telegram + bash + cron

  • Uruchamiamy go przyciskiem Start, wpisujemy polecenie /newbot i odpowiadamy na pytania. Należy pamiętać, że name to imię bota, które będzie wyświetlane użytkownikom, a username jest unikalny i musi kończyć się na „bot”:

    Bot do monitorowania usług internetowych w pół godziny: telegram + bash + cron

    Między innymi, bot wyda tajny token dla HTTP API, który należy skopiować i zapisać w pliku telegram-api-key.txt w folderze msms.

  • Wpisujemy w pasku wyszukiwania telegramu nazwę naszego bota i uruchamiamy go.
  • Na koniec, dodamy siebie do listy odbiorców powiadomień monitoringu:
    sudo chmod +x ./recipients-setup.sh
    torsocks ./recipients-setup.sh

    Skrypt wyświetli listę ostatnich nieobecności bota, powinna tam być jedna linia z naszymi id i nazwą w telegramie. Bierzemy to id i zapisujemy je w pliku services/google-recipients.txt. Format pliku: każda linia – jeden id. Przykład:

    123456789
    987654321

Aby dodać nowego odbiorcę, należy poprosić go, aby uruchomił bota w telegramie, uruchomił recipients-setup.sh i dodał id do pliku.

KROK 2. Konfigurujemy monitoring.

Opis usługi odbywa się poprzez stworzenie pliku ini w folderze services. Należy określić pięć parametrów:

  1. MSMS_SERVICE_NAME: nazwa usługi – będzie używana w powiadomieniach i dzienniku monitoringu.
  2. MSMS_SERVICE_ENDPOINT: endpoint usługi, do którego będziemy się odnosić za pomocą curl’a.
  3. MSMS_CURL_PARAMS: dodatkowe parametry curl, patrz przykład poniżej.
  4. MSMS_OCZEKIWANY: oczekiwana odpowiedź serwisu. Używane, gdy odpowiedź jest krótka.
  5. MSMS_OCZEKIWANY_PLIK: nazwa pliku z oczekiwaną odpowiedzią serwisu. Jeśli podano, nadpisuje MSMS_OCZEKIWANY.
  6. MSMS_ODBIORCY: plik z listą odbiorców powiadomień.

Zapytanie do google.com zwraca stały html z przekierowaniem, użyjemy go jako oczekiwaną odpowiedź serwera:

curl google.com > services/google-response.html

Utworzymy plik services/google.ini:

MSMS_NAZWA_USŁUGI='strona główna google'

# punkt końcowy usługi
MSMS_PUNKT_KOŃCOWY='google.com'

# parametry curl
MSMS_CURL_PARAMETRY='-s --connect-timeout 3 -m 7'

# oczekiwana odpowiedź usługi
MSMS_OCZEKIWANY_PLIK='google-response.html'

# plik z listą odbiorców
MSMS_ODBIORCY='google-recipients.txt'

W MSMS_CURL_PARAMS można podać wszystko, co potrafi curl, w tym:

  1. Wyłącz komunikaty curl, aby nie zagracać konsoli i logu: -s
  2. Ustaw czas oczekiwania na połączenie z testowaną usługą (w sekundach): --connect-timeout 3
  3. Ustaw czas oczekiwania na odpowiedź: -m 7
  4. Wyłącz weryfikację certyfikatu dla SSL (na przykład, gdy używany jest samopodpisany certyfikat): --insecure
  5. Podaj typ zapytania http: -X POST
  6. Podaj nagłówki: -H "Content-Type: application/json"
  7. Podaj treść zapytania w postaci ciągu lub pliku. Przykład dla pliku: -d @request.json

Wyłączyliśmy powiadomienia i ustawiliśmy czasy oczekiwania na 3 sekundy na połączenie i 7 sekund na uzyskanie odpowiedzi serwisu.

Uwaga: podawaj wartości parametrów w pojedynczych cudzysłowach, jak w przykładzie. Niestety, bash w tym względzie jest dość kruchy, a przypadkowo wpadła mucha lub źle umieszczony cudzysłów mogą prowadzić do złożonych błędów.

Skonfigurowaliśmy monitoring. Sprawdźmy, czy wszystko jest w porządku:

sudo chmod +x ./monitoring.sh
torsocks ./monitoring.sh

Skrypt powinien zwrócić komunikat w formacie:

2020-01-10 12:14:31
health-check "strona główna google": OK

KROK 3. Ustawiamy harmonogram

Skonfigurujmy harmonogram monitoringu w cron:

sudo crontab -e

Dodajemy linię do sprawdzania google.com co minutę:

*/1 * * * * torsocks /monitoring.sh >> /monitoring.log 2>&1

Dodamy codzienne powiadomienie o 11:00, potwierdzające działanie monitoringu. W tym celu przekażemy skryptowi parametr DAILY:

0 11 * * * torsocks /monitoring.sh DAILY >> /monitoring.log 2>&1

2>&1 — standardowa metoda, przekierowująca błędy do głównego strumienia wyjściowego. W rezultacie, również trafią one do dziennika monitoringu.

Zapisz zmiany i załaduj je poleceniem:

 sudo service cron reload

Więcej informacji na temat konfiguracji cron można znaleźć na przykład, tutaj.

W ten sposób każdą minutę uruchamiany będzie skrypt monitorowania, który przez curl zwróci się do google.com. Jeśli otrzymana odpowiedź różni się od oczekiwanej, skrypt wyśle powiadomienie do listy odbiorców w telegramie. Dziennik kontroli jest prowadzony w pliku monitoring.log

Jeśli potrzebujemy dodać kolejny serwis, wystarczy, że stworzymy nowy plik ini w folderze services i, w razie potrzeby, utworzymy osobną listę odbiorców. Wszystko inne zadziała automatycznie.

Jeśli monitorowany serwis stanie się niedostępny, powiadomienia będą przychodzić co minutę. Jeśli nie uda się szybko przywrócić serwisu, można tymczasowo wyłączyć powiadomienia w ustawieniach bota w telegramie.

Teraz omówmy szczegółowo dodatkowe możliwości i realizację skryptów.

Szablony wiadomości i emocjonalne zaangażowanie

Aby uczynić komunikację z botem bardziej żywą, nazwaliśmy go Maneczką, dodaliśmy odpowiedni obrazek awatar i zatrudniliśmy profesjonalnych PR-owców do stworzenia tekstów wiadomości. Możesz wykorzystać nasze rozwiązania lub zmienić je według własnego uznania.

Na przykład tak:

Bot do monitorowania usług internetowych w pół godziny: telegram + bash + cron
albo nawet tak:

Bot do monitorowania usług internetowych w pół godziny: telegram + bash + cron
Czemu nie?

Imię bota i awatar są ustawiane przez @botfather.
Szablony wiadomości znajdują się w folderze templates:

  • curl-fail.txt: wiadomość wysyłana w przypadku, gdy curl zwraca niezerowy kod błędu. Zazwyczaj informuje o niemożności połączenia się z serwisem.
  • daily.txt: codzienna wiadomość, potwierdzająca, że monitorowanie serwisu działa.
  • service-fail.txt: wiadomość wysyłana w przypadku, gdy odpowiedź serwisu różni się od oczekiwanej.

Omówimy możliwości dostosowania na przykładzie wbudowanych szablonów wiadomości.
W szablonach używane są emotikony. Niestety, habr ich nie wyświetla.
Do wyszukiwania emotikonów wygodnie używać wyszukiwania na emojipedia.org:

Bot do monitorowania usług internetowych w pół godziny: telegram + bash + cron

Odpowiedni symbol po prostu kopiujesz i wklejasz do tekstu szablonu (to zwykły unicode).

  1. curl-fail.txt:
    Kotek, pomóż mi... 
    Nie mogę połączyć się z serwisem "$MSMS_SERVICE_NAME" 
    `CURL EXIT CODE: $EXIT_CODE`

    Użyliśmy podanej przez nas nazwy serwisu (zmienna MSMS_SERVICE_NAME) oraz wewnętrznej zmiennej skryptu z kodem zakończenia curl (EXIT_CODE). Sformatowaliśmy również wiadomość, stosując formatowanie telegram markdown: znaki "`" owijają tekst o stałej szerokości. Ponieważ cudzysłowy i apostrofy są symbolami specjalnymi bash, dodatkowo je zabezpieczamy znakiem "". Nazwy zmiennych poprzedzamy znakiem "$".

    Wynik:

    Bot do monitorowania usług internetowych w pół godziny: telegram + bash + cron

  2. service-fail.txt:
    Kociaku, pomóż mi... 
    Serwis "$MSMS_SERVICE_NAME" mnie zawiódł.
    Nie działa poprawnie, oto co mi odpowiada:
    `$RESPONSE`

    Wynik:

    Bot do monitorowania usług internetowych w pół godziny: telegram + bash + cron

    Tutaj używamy jeszcze jednej zmiennej skryptu: RESPONSE. Zawiera odpowiedź serwisu.

  3. daily.txt:
    Cześć maluchu!
    U mnie wszystko w porządku, obserwuję serwis:
    "$MSMS_SERVICE_NAME" co minutę...
    A co u ciebie słychać?
    

    Wynik:

    Bot do monitorowania usług internetowych w pół godziny: telegram + bash + cron

Przejdźmy do realizacji skryptów.

Skrypt monitorowania

monitoring.sh wykonuje prostą auto-odkrywanie — bierze wszystkie pliki ini z folderu services i dla każdego wykonuje główny skrypt z logiką sprawdzania i wysyłania powiadomień:

#!/bin/bash
cd $(dirname "$0")/services

for service_ini  in $(ls *.ini); do
    bash ../msms.sh "$1" "$service_ini"
done

Aby utworzyć codzienną wiadomość o statusie monitorowania, można przekazać parametr DAILY.

Zwróć uwagę, że przy uruchamianiu skryptu bieżący folder zmienia się na services. Pozwala to na określenie ścieżek do plików w plikach ini w odniesieniu do services.

Skrypt sprawdzający i wysyłający powiadomienia

msms.sh zawiera główną logikę sprawdzania serwisu i wysyłania powiadomień.

Praca z telegramem:

# telegram endpoint
TG_API_URL="https://api.telegram.org/bot$(cat ../telegram-api-key.txt)/sendMessage"

#################################################################
# send message to telegram
# parameter: message text
#################################################################
function send_message {
    for chat_id  in $(cat ../$MSMS_RECIPIENTS); do
	curl -s -X POST --connect-timeout 10 $TG_API_URL -d chat_id=$chat_id -d parse_mode="Markdown" -d text="$1"
	echo
    done
}

Tworzymy URL do dostępu do REST API telegramu, korzystając z zapisanego w pliku klucza sekretnego.

Funkcja send_message używa curl do wysyłania wiadomości na to REST API, pobierając id odbiorców z pliku, który wskazaliśmy w ini. W wysyłanych danych wskazujemy, że używamy formatowania wiadomości: parse_mode="Markdown".

Wyświetlimy bieżącą datę i czas oraz załadujemy plik ini.

echo $(date '+%Y-%m-%d %H:%M:%S')

# załaduj zmienne z pliku .ini:
. $2

Magiczny ciąg . $2 wykonuje przekazany jako drugi parametr plik ini jako zwykły skrypt, umieszczając określone w nim wartości w zmiennych środowiskowych.

Załadujemy oczekiwaną odpowiedź z pliku, jeśli podany jest parametr MSMS_OCZEKIWANY_PLIK:

if [ -n "$MSMS_EXPECTED_FILE" ]; then
 MSMS_EXPECTED="$(cat "$MSMS_EXPECTED_FILE")"
fi

Wykonajmy sprawdzenie serwisu z wysyłką powiadomień, jeśli to konieczne:

RESPONSE="$(eval curl $MSMS_CURL_PARAMS "$MSMS_SERVICE_ENDPOINT")"
EXIT_CODE=$?
if [[ $EXIT_CODE != 0 ]]; then
    echo health-check "$MSMS_SERVICE_NAME" NIE POWIODŁO SIĘ: CURL EXIT WITH $EXIT_CODE
    MESSAGE="$(cat ..\/templates\/curl-fail.txt)"
    MESSAGE=$(eval echo $MESSAGE)
    send_message "$MESSAGE"
elif [[ "$RESPONSE" != "$MSMS_EXPECTED" ]]; then
    echo health-check "$MSMS_SERVICE_NAME" NIE POWIODŁO SIĘ: "$RESPONSE"
    MESSAGE="$(cat ..\/templates\/service-fail.txt)"
    MESSAGE=$(eval echo $MESSAGE)
    send_message "$MESSAGE"
else
    echo health-check "$MSMS_SERVICE_NAME": OK
fi

Najpierw przypisujemy zmiennej RESPONSE wynik wykonania polecenia curl dla tego serwisu.

Wyrażenie EXIT_CODE=$? przechowuje w zmiennej wynik ostatniego polecenia, tj. curl. W razie potrzeby wysyłane jest powiadomienie, wczytywany jest szablon z odpowiedniego pliku i realizowana jest wysyłka do odbiorców za pomocą send_message.

Ostatni blok przetwarza parametr DAILY:

if test "$1" = "DAILY"; then
    echo health-check "$MSMS_SERVICE_NAME" DAILY
    MESSAGE="$(cat ..\/templates\/daily.txt)"
    MESSAGE=$(eval echo $MESSAGE)
    send_message "$MESSAGE"
fi

Wysłał wiadomość potwierdzającą działanie samego monitoringu.

Pobieranie listy id użytkowników

recipients-setup.sh odnosi się do API telegramu w celu uzyskania ostatnich wiadomości skierowanych do bota:

curl -s https:\/\/api.telegram.org\/bot$(cat telegram-api-key.txt)\/getUpdates 
| python recipients-setup.py

Tutaj używana jest magia Pythona do ładnego wyświetlania listy. To nie jest konieczne, można po prostu wziąć potrzebne id z jsona, które wyświetli komenda:

torsocks curl -s https:\/\/api.telegram.org\/bot$(cat telegram-api-key.txt)\/getUpdates

Podsumowanie

Dzięki temu możesz używać gotowych skryptów i szablonów wiadomości, konfigurując tylko obserwowane usługi i listy powiadomień; możesz stworzyć nową «tożsamość» dla bota; lub możesz stworzyć własne rozwiązanie na podstawie przedstawionego.

Jako opcje dalszego rozwoju nasuwa się skonfigurowanie i zarządzanie monitoringiem bezpośrednio w bocie, ale tutaj już nie obędzie się bez Pythona. Jeśli ktoś zdąży to zrobić wcześniej niż ja — wiecie, gdzie wrzucić pull request 🙂

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster