[Сервер] Настройка telegram уведомлений o превышении порога CPU

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

Как работает скрипт:

  1. Точный замер: скрипт снимает показатели через утилиту top дважды с интервалом в 1 секунду, чтобы отсечь мгновенные погрешности и получить реальную загрузку процессора.
  2. Защита от ложных срабатываний: кратковременные скачки игнорируются. Оповещение уходит только тогда, когда нагрузка держится выше заданного порога (THRESHOLD_HIGH=90%) два замера подряд (то есть не менее двух минут).
  3. Определение виновника: в момент фиксации перегрузки скрипт автоматически находит топ-3 самых ресурсоёмких процесса и прикрепляет их названия вместе с процентом нагрузки к сообщению.
  4. Защита от спама: благодаря временному файлу-флагу (/tmp/cpu_alert_sent) бот не заваливает чат сообщениями каждую минуту, пока процессор загружен.
  5. Оповещение о нормализации: когда нагрузка опускается ниже безопасного порога (THRESHOLD_LOW=70%), скрипт отправляет уведомление о стабилизации системы и сбрасывает флаг.
  6. Два варианта отправки: для зарубежного сервера (DE) запросы к Telegram API идут напрямую, а для сервера в РФ – через локальный SOCKS5-прокси.

Создайте файл скрипта:

sudo nano /usr/local/bin/cpu_monitor.sh

Вставьте код (выберите версию для нужного сервера):

Для сервера DE (прямая отправка):

#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TOKEN="YOUR_BOT_TOKEN"
CHAT_ID="YOUR_CHAT_ID"
SERVER_TAG="DE"
FLAG_FILE="/tmp/cpu_alert_sent"
COUNT_FILE="/tmp/cpu_high_count"
THRESHOLD_HIGH=90
THRESHOLD_LOW=70

CPU_USAGE=$(LC_ALL=C top -bn2 -d 1 | grep "Cpu(s)" | tail -n 1 | sed 's/,/ /g' | awk '{for(i=1;i<=NF;i++) if($i=="id") {print int(100 - $(i-1)); exit}}')

if [ "${CPU_USAGE:-0}" -ge "$THRESHOLD_HIGH" ]; then
    COUNT=$(cat "$COUNT_FILE" 2>/dev/null || echo 0)
    COUNT=$((COUNT + 1))
    echo "$COUNT" > "$COUNT_FILE"

    if [ "$COUNT" -ge 2 ] && [ ! -f "$FLAG_FILE" ]; then
        touch "$FLAG_FILE"
        TOP_PROCS=$(LC_ALL=C COLUMNS=512 top -b -n 2 -d 1 | awk '/PID USER/{i++} i==2' | head -n 4 | awk 'NR==1 {printf "%-16s %s\n", $12, $9; next} {printf "%-16s %s%%\n", $12, $9}')
        MSG="🚨 <b>[${SERVER_TAG}] Высокая нагрузка CPU!</b>
Нагрузка держится более 90% уже 2 минуты.
Текущая загрузка: <code>${CPU_USAGE}%</code>

<b>Топ процессов:</b>
<pre>${TOP_PROCS}</pre>"

        curl -s -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
            -d "chat_id=${CHAT_ID}" -d "parse_mode=HTML" \
            --data-urlencode "text=${MSG}" > /dev/null 2>&1
    fi
else
    rm -f "$COUNT_FILE"
    if [ "${CPU_USAGE:-0}" -le "$THRESHOLD_LOW" ] && [ -f "$FLAG_FILE" ]; then
        rm -f "$FLAG_FILE"
        MSG="✅ <b>[${SERVER_TAG}] Нагрузка CPU нормализовалась</b>
Текущая загрузка: <code>${CPU_USAGE}%</code>"

        curl -s -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
            -d "chat_id=${CHAT_ID}" -d "parse_mode=HTML" \
            --data-urlencode "text=${MSG}" > /dev/null 2>&1
    fi
fi

Для сервера РФ (через SOCKS5-прокси):

(В вызовах curl добавляется -x socks5h://127.0.0.1:10808, а SERVER_TAG="РФ"):

#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
TOKEN="YOUR_BOT_TOKEN"
CHAT_ID="YOUR_CHAT_ID"
SERVER_TAG="РФ"
FLAG_FILE="/tmp/cpu_alert_sent"
COUNT_FILE="/tmp/cpu_high_count"
THRESHOLD_HIGH=90
THRESHOLD_LOW=70

CPU_USAGE=$(LC_ALL=C top -bn2 -d 1 | grep "Cpu(s)" | tail -n 1 | sed 's/,/ /g' | awk '{for(i=1;i<=NF;i++) if($i=="id") {print int(100 - $(i-1)); exit}}')

if [ "${CPU_USAGE:-0}" -ge "$THRESHOLD_HIGH" ]; then
    COUNT=$(cat "$COUNT_FILE" 2>/dev/null || echo 0)
    COUNT=$((COUNT + 1))
    echo "$COUNT" > "$COUNT_FILE"

    if [ "$COUNT" -ge 2 ] && [ ! -f "$FLAG_FILE" ]; then
        touch "$FLAG_FILE"
        TOP_PROCS=$(LC_ALL=C COLUMNS=512 top -b -n 2 -d 1 | awk '/PID USER/{i++} i==2' | head -n 4 | awk 'NR==1 {printf "%-16s %s\n", $12, $9; next} {printf "%-16s %s%%\n", $12, $9}')
        MSG="🚨 <b>[${SERVER_TAG}] Высокая нагрузка CPU!</b>
Нагрузка держится более 90% уже 2 минуты.
Текущая загрузка: <code>${CPU_USAGE}%</code>

<b>Топ процессов:</b>
<pre>${TOP_PROCS}</pre>"

        curl -s -x socks5h://127.0.0.1:10808 -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
            -d "chat_id=${CHAT_ID}" -d "parse_mode=HTML" \
            --data-urlencode "text=${MSG}" > /dev/null 2>&1
    fi
else
    rm -f "$COUNT_FILE"
    if [ "${CPU_USAGE:-0}" -le "$THRESHOLD_LOW" ] && [ -f "$FLAG_FILE" ]; then
        rm -f "$FLAG_FILE"
        MSG="✅ <b>[${SERVER_TAG}] Нагрузка CPU нормализовалась</b>
Текущая загрузка: <code>${CPU_USAGE}%</code>"

        curl -s -x socks5h://127.0.0.1:10808 -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
            -d "chat_id=${CHAT_ID}" -d "parse_mode=HTML" \
            --data-urlencode "text=${MSG}" > /dev/null 2>&1
    fi
fi

Делаем скрипт исполняемым:

sudo chmod +x /usr/local/bin/cpu_monitor.sh

Добавляем проверку в Cron

 Откройте crontab:

sudo crontab -e

Добавьте в самый конец запуск каждую минуту:

* * * * * /usr/local/bin/cpu_monitor.sh

Как быстро проверить работу, не нагружая процессор

Чтобы убедиться, что сообщения приходят:

  1. Временно измените THRESHOLD_HIGH=0 в скрипте и выполните его дважды вручную: bash /usr/local/bin/cpu_monitor.sh (на второй запуск придёт тревога 🚨 со списком процессов).
  2. Верните THRESHOLD_HIGH=90 и снова выполните скрипт один раз (придёт сообщение, что нагрузка нормализовалась ✅).