Bash-скрипт для мониторинга сервисов и уведомлений в Telegram

Bash-скрипт для проверки сервисов

Для небольших проектов и dev-серверов полноценный мониторинг в стиле Zabbix или Prometheus часто оказывается избыточным. В таких случаях достаточно простого скрипта, который пройдётся по списку сервисов и покажет, что именно не отвечает.

Ниже — готовый вариант со проверкой через systemctl и отправкой уведомлений в Telegram.

Базовый вариант

Создаём файл:

nano check_services.sh

Содержимое:

#!/bin/bash
SERVICES=("nginx" "postgresql" "redis" "ssh")

echo "===== СТАТУС СЕРВИСОВ ====="
echo ""

for SERVICE in "${SERVICES[@]}"; do
    STATUS=$(systemctl is-active "$SERVICE" 2>/dev/null)
    if [ "$STATUS" = "active" ]; then
        echo "[OK]     $SERVICE"
    else
        echo "[УПАЛ]   $SERVICE"
    fi
done

Выдаём права и запускаем:

chmod +x check_services.sh
./check_services.sh

Массив SERVICES подстройте под свой стек. Результат будет примерно таким:

===== СТАТУС СЕРВИСОВ =====

[OK]     nginx
[OK]     postgresql
[УПАЛ]   redis
[OK]     ssh

Вариант с уведомлением в Telegram

Базовый вариант выводит результат прямо в консоль. Но если скрипт запускается по cron, этот вывод вы не увидите. Поэтому добавим отправку сообщения в Telegram, когда будет найден упавший сервис.

Для этого нужны бот и chat_id. Бота создаёте через @BotFather, а chat_id получаете через @userinfobot или из API бота после того, как отправите ему любое сообщение.

#!/bin/bash
SERVICES=("nginx" "postgresql" "redis" "ssh")

BOT_TOKEN="123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
CHAT_ID="987654321"

FAILED=""

for SERVICE in "${SERVICES[@]}"; do
    STATUS=$(systemctl is-active "$SERVICE" 2>/dev/null)
    if [ "$STATUS" != "active" ]; then
        FAILED="${FAILED} ${SERVICE}\n"
    fi
done

if [ -n "$FAILED" ]; then
    HOSTNAME=$(hostname)
    MESSAGE=" Проблема на ${HOSTNAME}\n\nУпавшие сервисы:\n${FAILED}"
    curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
        -d chat_id="$CHAT_ID" \
        -d text="$(echo -e "$MESSAGE")" \
        -d parse_mode="HTML" > /dev/null
fi

Скрипт отправляет сообщение только в том случае, если что-то перестало работать. Если все сервисы в порядке, он ничего не пишет и не засоряет чат.

Добавляем в cron

Открываем crontab:

crontab -e

Добавляем строку для проверки каждые 5 минут:

*/5 * * * * /path/to/check_services.sh

Что можно улучшить

Скрипт специально сделан максимально простым, но его легко доработать. Например, можно добавить автоматический перезапуск упавшего сервиса через systemctl restart "$SERVICE" прямо в блоке проверки. Или сохранять результаты в лог-файл для истории. Если серверов несколько, скрипт можно запускать удалённо через ssh в цикле по списку хостов.

Для продакшена с десятками сервисов и серверов лучше смотреть в сторону полноценных решений. Но для пары серверов этот скрипт закрывает задачу за пять минут настройки.