Бот за мониторинг на уеб услуги за половин час: telegram + bash + cron

Бот за мониторинг на уеб услуги за половин час: telegram + bash + cron

Понякога е необходимо бързо да се направи мониторинг за нова услуга, а готова инфраструктура/експертиза не е налична. В това ръководство за половин час ще реализираме инструмент за мониторинг на всякакви уеб услуги, използвайки само вградените инструменти на ubuntu: bash, cron и curl. За доставка на известия ще използваме telegram.

«Вишенката на тортата» ще бъде емоционалното ангажиране на потребителите. Проверено на хора — работи.

Когато в телемедицинската услуга Доктор Рядом създадохме чат-бот за определяне на нивото на стреса на потребителите, ни беше необходим мониторинг. За няколко часа беше направен мини проект, който не само работи отлично, но и добавя позитивност със своите съобщения.

За начало, ще получим репозитория със скриптове:

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

Преминаваме в папката msms и продължаваме да работим там.

Ако telegram е блокиран, използвайте прокси. Най-лесният и надежден вариант е torsocks:

sudo apt install tor
sudo apt install torsocks

Като пример настроим в три стъпки мониторинг на началната страница google.com.

СТЪПКА 1. Създаваме бот в telegram и получаваме id на потребителя.

  • В полето за търсене на контакти в telegram търсим @botfather:

    Бот за мониторинг на уеб услуги за половин час: telegram + bash + cron

  • Стартираме го с бутона Start, въвеждаме командата /newbot и отговаряме на въпросите. Трябва да имате предвид, че name е името на бота, което ще се показва на потребителите, а username е уникален и трябва да завършва на «bot»:

    Бот за мониторинг на уеб услуги за половин час: telegram + bash + cron

    Между другото, ботът ще издаде секретен токен за HTTP API, който трябва да копирате и запазите в файл telegram-api-key.txt в папката msms.

  • Търсим в полето за търсене в telegram името на нашия бот и го стартираме.
  • Като финален щрих, ще добавим себе си в списъка на получателите на известия за мониторинга:
    sudo chmod +x ./recipients-setup.sh
    torsocks ./recipients-setup.sh

    Скриптът ще изведе списък на последните запитвания към бота, там трябва да има един ред с нашите id и име в telegram. Вземаме това id и го запазваме в файла services/google-recipients.txt. Формат на файла: всеки ред — един id. Пример:

    123456789
    987654321

За да добавите нов получател, трябва да го помолите да стартира бота в telegram, да стартира recipients-setup.sh и да добави id в файла.

СТЪПКА 2. Настройваме мониторинга.

Описание на услугата става чрез създаване на ini файл в папката services. Трябва да зададете пет параметъра:

  1. MSMS_SERVICE_NAME: име на услугата — ще се използва в известията и в журнала на мониторинга.
  2. MSMS_SERVICE_ENDPOINT: endpoint на услугата, към която ще се обръщаме с curl.
  3. MSMS_CURL_PARAMS: допълнителни параметри curl, вижте примера по-долу.
  4. MSMS_EXPECTED: очакван отговор на услугата. Използва се, ако отговорът е кратък.
  5. MSMS_EXPECTED_FILE: името на файла с очаквания отговор на услугата. Ако е посочено, замества MSMS_EXPECTED.
  6. MSMS_RECIPIENTS: файл със списък на получателите на известия.

Заявка към google.com връща фиксиран html с пренасочване, ще го използваме като очакван отговор от сървъра:

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

Ще създадем файл services/google.ini:

MSMS_SERVICE_NAME='google front page'

# крайна точка на услугата
MSMS_SERVICE_ENDPOINT='google.com'

# параметри на curl
MSMS_CURL_PARAMS='-s --connect-timeout 3 -m 7'

# очакван отговор на услугата
MSMS_EXPECTED_FILE='google-response.html'

# файл със списък на получателите
MSMS_RECIPIENTS='google-recipients.txt'

В MSMS_CURL_PARAMS можете да зададете всичко, което умеете с curl, включително:

  1. Изключете съобщенията на curl, за да не замърсяват конзолата и логовете: -s
  2. Установете таймаут за свързване с проверяваната услуга (в секунди): --connect-timeout 3
  3. Задайте таймаут за получаване на отговор: -m 7
  4. Изключете проверката на сертификата за SSL (например, ако се използва самоподписан сертификат): --insecure
  5. Посочете типа http-заявка: -X POST
  6. Посочете заглавията: -H "Content-Type: application/json"
  7. Посочете тялото на заявката като низ или файл. Пример за файл: -d @request.json

Изключихме известията и зададохме таймаути 3 секунди за свързване и 7 секунди за получаване на отговор от услугата.

Внимание: посочвайте стойностите на параметрите в единични кавички, както в примера. За съжаление, bash в този смисъл е доста крехък и случайно попадналата пеперуда там, където не трябва, може да доведе до трудно диагностируеми грешки.

Настроихме мониторинга. Нека проверим дали всичко е ОК:

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

Скриптът трябва да изведе съобщение от вида:

2020-01-10 12:14:31
health-check "google front page": OK

СТЪПКА 3. Настройваме график

Нека настроим графика на мониторинга в cron:

sudo crontab -e

Ще добавим ред за проверка на google.com всяка минута:

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

Ще добавим всеки ден в 11:00 известие, което потвърдява работоспособността на самия мониторинг. За това ще предадем параметъра DAILY на скрипта:

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

2>&1 — стандартна техника, пренасочваща грешките в основния поток на изхода. В резултат на това, те също ще попаднат в логовете за мониторинг.

Ще запазим промените и ще ги приложим с командата:

 sudo service cron reload

Повече информация за настройката на cron можете да намерите, например, тук.

По този начин, всяка минута ще се стартира скрипт за мониторинг, който чрез curl ще се свързва с google.com. Ако полученото отговорът се различава от очакваното, скриптът ще изпрати уведомление на списъка с получатели в telegram. Журналът на проверките се води в файла monitoring.log.

Ако трябва да добавим още един сервис, просто създаваме нов ini файл за него в папката services и, при необходимост, изграждаме отделен списък на получателите. Всичко останало ще работи автоматично.

Ако проверяваният сервис стане недостъпен, уведомление ще идва всяка минута. Ако не успеем бързо да възстановим сервиса, можем временно да изключим уведомленията в свойствата на бота в telegram.

Сега нека подробно разгледаме допълнителните възможности и реализацията на скриптовете.

Шаблони на съобщения и емоционално ангажиране

За да направим комуникацията с бота по-жива, го нарекохме Манечка, добавихме съответната картинка-аватар и привлечехме професионални PR специалисти за създаване на текстове на съобщения. Можете да използвате нашите разработки или да ги промените по свой вкус.

Например така:

Бот за мониторинг на уеб услуги за половин час: telegram + bash + cron
или даже така:

Бот за мониторинг на уеб услуги за половин час: telegram + bash + cron
Защо не?

Името на бота и аватарът се задават чрез @botfather.
Шаблоните на съобщенията се намират в папката templates:

  • curl-fail.txt: съобщение, изпращано в случай, че curl е върнал ненулев код на грешка. Обикновено показва, че не може да се достигне до сервиса.
  • daily.txt: ежедневно съобщение, потвърждаващо, че мониторингът на сервиса работи.
  • service-fail.txt: съобщение, изпращано в случай, че отговорът на сервиса се различава от очакваното.

Нека разгледаме възможностите за персонализиране на примера с вградените шаблони на съобщения.
В шаблоните се използват емодзи. За съжаление, habr не ги показва.
За подбора на емодзи е удобно да се ползва търсене на emojipedia.org:

Бот за мониторинг на уеб услуги за половин час: telegram + bash + cron

Подходящият символ просто копирате и поставяте в текста на шаблона (това е обикновен unicode).

  1. curl-fail.txt:
    Котенце, помогни ми... 
    Не мога да достигна до сервиса "$MSMS_SERVICE_NAME" 
    `CURL EXIT CODE: $EXIT_CODE`

    Използвахме зададеното от нас име на услугата (променливата MSMS_SERVICE_NAME) и вътрешната променлива на скрипта с код на завършване на curl (EXIT_CODE). Също така форматирахме съобщението, използвайки маркировка telegram markdown: символите "`" обграждат текста с фиксирана ширина. Тъй като кавичките и апострофите са служебни символи в bash, ние ги екранираме с символа "". Имената на променливите се предхождат от знака "$".

    Резултат:

    Бот за мониторинг на уеб услуги за половин час: telegram + bash + cron

  2. service-fail.txt:
    Коте, помогни ми... 
    Сервисът "$MSMS_SERVICE_NAME" ме разстрои
    Той не работи правилно, ето какво ми отговаря:
    `$RESPONSE`

    Резултат:

    Бот за мониторинг на уеб услуги за половин час: telegram + bash + cron

    Тук използваме още една променлива на скрипта: RESPONSE. Тя съдържа отговора на сервиса.

  3. daily.txt:
    Малък, здравей!
    Всичко е наред при мен, следя сервиза:
    "$MSMS_SERVICE_NAME" на всяка минута...
    А как си ти?
    

    Резултат:

    Бот за мониторинг на уеб услуги за половин час: telegram + bash + cron

Да преминем към реализация на скриптовете.

Скрипт за мониторинг

monitoring.sh прави прост auto-discovery — взима всички ini файлове от папка services и за всеки изпълнява основния скрипт с логиката на проверка и разпращане на уведомления:

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

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

За формиране на ежедневно съобщение за статус на мониторинга, на скрипта може да се предаде параметър DAILY.

Обърнете внимание, че при стартиране на скрипта текущата папка се променя на services. Това позволява в ini файловете да се указват пътища към файловете относително на services.

Скрипт за проверка и разпращане на уведомления

msms.sh съдържа основната логика за проверка на сервиза и разпращане на уведомления.

Работа с Telegram:

# 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
}

Формираме URL за достъп до REST API на Telegram, използвайки запазения в файла секретен ключ.

Функцията send_message използва curl за изпращане на съобщения до този REST API, взимайки id на получателите от файла, указания от нас в ini. В изпратените данни посочваме, че използваме разметка за съобщения: parse_mode="Markdown".

Ще изведем текущата дата-време и ще заредим ini файла.

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

# зареждане на променливи от .ini файла:
. $2

Магическата строка . $2 изпълнява предадения втори параметър ini файл като обикновен скрипт, записвайки определените в него стойности в променливите на средата.

Ще заредим очаквания отговор от файла, ако е зададен параметър MSMS_EXPECTED_FILE:

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

Ще извършим проверка на сервиза с изпращане на уведомления, ако е необходимо:

RESPONSE="$(eval curl $MSMS_CURL_PARAMS "$MSMS_SERVICE_ENDPOINT")"
EXIT_CODE=$?
if [[ $EXIT_CODE != 0 ]]; then
    echo health-check "$MSMS_SERVICE_NAME" FAILED: 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" FAILED: "$RESPONSE"
    MESSAGE="$(cat ..\/templates\/service-fail.txt)"
    MESSAGE=$(eval echo $MESSAGE)
    send_message "$MESSAGE"
else
    echo health-check "$MSMS_SERVICE_NAME": OK
fi

Първо присвояваме на променливата RESPONSE резултата от изпълнението на командата curl за този сервиз.

Израз EXIT_CODE=$? записва резултата от последната команда, т.е. curl. При необходимост за изпращане на уведомление, шаблонът се прочита от съответния файл и се извършва разпращане на получателите с помощта на send_message.

Последният блок обработва параметъра 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

Той изпраща съобщение, потвърждаващо функционалността на самия мониторинг.

Получаване на списък с ID на потребители

recipients-setup.sh се свързва с API на telegram, за да получи последните съобщения, адресирани до бота:

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

Тук се използва магията на python за красив изход на списъка. Това не е задължително, можете просто да вземете нужния ID от json, който ще изведе командата:

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

Заключение

По този начин можете да използвате готови скриптове и шаблони за съобщения, настройвайки само наблюдаваните услуги и списъците за уведомления; можете да създадете нова "личност" за бота; или можете да направите свое решение на базата на предложеното.

Като възможности за последващо развитие се предлага конфигуриране и управление на мониторинга в самия бот, но тук без python не може да се мине. Ако някой успее да завърши по-рано от мен — знаете къде да качите pull request 🙂

Източник: habr.com

Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри 🔥 Купете надежден хостинг за сайтове с защита от DDoS, VPS VDS сървъри | ProHoster