Бот за наблюдение на уеб услуги за половин час: 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: крайна точка на услугата, към която ще се обръщаме с 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'

# крайна точка на услугата
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 може да зададете всичко, което умеe 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": ОК

СТЪПКА 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.

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

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

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

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

Бот за наблюдение на уеб услуги за половин час: 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" НЕУСПЕШЕН: CURL EXIT С $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" НЕУСПЕШЕН: "$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