Давайте честно, современные стеки мониторинга тяжеловаты. Пока вы настроите Prometheus, поднимете дашборды в Grafana и отладите Docker-exporters, проблему на сервере часто проще исправить руками.
Для огромного корпоративного кластера такие инструменты, безусловно, нужны. Но для личного VPS, небольшого клиентского проекта или staging-окружения это почти всегда перебор.
Ирония в том, что самый мощный инструмент мониторинга уже лежит у вас под рукой — это терминал Linux.
Пара строк Bash-скрипта плюс встроенная сила Cron и у вас получается мониторинг по типу “настроил и забыл”. Он не стоит ни копейки, почти не ест ресурсы системы и, что особенно приятно, помогает понять, как работает Linux и ваш сервер.
В этом гайде мы не собираемся продавать вам SaaS. Мы просто покажем, как собрать собственного сторожевого пса на стандартных инструментах терминала Linux.
Сложные системы мониторинга добавляют ещё одну точку отказа. Если агент мониторинга упал, кто будет мониторить мониторинг?
Когда вы держитесь за командную строку Linux, вы опираетесь на ядро и стандартные утилиты, которые десятилетиями остаются стабильными.
А если вы арендуете VPS, то логика простая: ресурсы должны работать на ваших пользователей, а не уходить на фоновые аналитические процессы.
Прежде чем писать код, убедимся, что условный стек готов. Ничего особенного ставить не нужно, большинство этих команд терминала Linux уже предустановлены в стандартных дистрибутивах вроде Ubuntu, Debian или Rocky Linux.
Вам нужен базовый доступ по SSH к серверу. Проверьте, что эти утилиты на месте:
Не запускайте мониторинговые скрипты от root без крайней необходимости. Лучше создать отдельного пользователя для обслуживания или использовать обычного non-root пользователя.
А когда скрипт будет готов, мы ограничим права стандартными командами оболочки Linux:
chmod 700 monitor.sh
Так вы гарантируете, что читать, менять и выполнять файл сможет только владелец.
Мы не будем пытаться замерить всё. Наша цель — SLIs (Signal Level Indicators). Если эти метрики становятся красными, пора разбираться.
Нужно понимать, возвращает ли веб-сервер 200 OK. Но если сервер отвечает 30 секунд, то для пользователя это почти то же самое, что и остаться без ответа.
Заканчивающееся место на диске потихоньку убьет ваш сервер. Логи копятся, кэши апдейтов разрастаются, и в какой-то момент MySQL падает просто потому, что не может записать данные в раздел. Мы зададим порог (обычно 80% или 90%), после которого будем поднимать тревогу.
Load average часто понимают неправильно. 1.0 на одноядерном CPU означает, что процессор забит под 100%. Мы будем смотреть 1-минутный load average — он лучше показывает, насколько страдает сервер под текущей нагрузкой.
Linux любит использовать свободную RAM под кеш, и это нормально. Но если доступной памяти становится слишком мало и система начинает свапать на диск, производительность резко падает. Поэтому нам нужны инструменты командной строки Linux, которые позволяют следить именно за доступной RAM.
Работает ли вообще Nginx? Не истекает ли SSL-сертификат через 48 часов так, что все пользователи увидят предупреждение безопасности в браузере? С этим тоже надо разбираться.
Это ядро всей схемы. Мы напишем один Bash-скрипт, который проверяет все перечисленные метрики.
Если вы как раз учитесь скриптингу в терминале Linux — это отличный практический заход. Структуру сделаем модульной, чтобы потом безболезненно добавлять новые проверки.
Создайте файл health.sh:
nano health.sh
Вставьте следующий код.
Замените WEBHOOK_URL на ваш реальный веб-хук из Slack, Discord или любого другого сервиса.
#!/bin/bash
# Конфигурация
THRESHOLD_DISK=90
THRESHOLD_CPU=2.0
THRESHOLD_MEM=500 # Минимум свободных MB
TARGET_URL="https://google.com" # Измените на ваш сайт
SSL_DOMAIN="google.com" # Измените на ваш домен
WEBHOOK_URL="https://your-webhook-url-here" # Slack, Discord или что-либо другое
HOSTNAME=$(hostname)
# Функция отправки оповещений
send_alert() {
MESSAGE="CRITICAL: $1 on $HOSTNAME"
# Отправить на веб-хук
curl -H "Content-Type: application/json" \
-d "{\"content\": \"$MESSAGE\"}" \
$WEBHOOK_URL
# Дополнительно: запись в syslog
logger "HEALTHCHECK_ALERT: $1"
}
# 1. Проверка диска
DISK_USAGE=$(df / | grep / | awk '{ print $5 }' | sed 's/%//g')
if [ "$DISK_USAGE" -gt "$THRESHOLD_DISK" ]; then
send_alert "Disk usage is at ${DISK_USAGE}%"
fi
# 2. Проверка CPU (среднее значение за 1 минуту)
CPU_LOAD=$(awk '{print $1}' < /proc/loadavg)
# Bash плохо обрабатывает числа с плавающей запятой, поэтому для сравнения используем awk
IS_HIGH_LOAD=$(echo "$CPU_LOAD $THRESHOLD_CPU" | awk '{if ($1 > $2) print 1; else print 0}')
if [ "$IS_HIGH_LOAD" -eq 1 ]; then
send_alert "High CPU Load: ${CPU_LOAD}"
fi
# 3. Проверка памяти (доступно в МБ)
MEM_AVAIL=$(free -m | grep "Mem:" | awk '{print $7}')
if [ "$MEM_AVAIL" -lt "$THRESHOLD_MEM" ]; then
send_alert "Low Memory: Only ${MEM_AVAIL}MB available"
fi
# 4. Проверка доступности сайта (HTTP 200)
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$TARGET_URL")
if [ "$HTTP_CODE" -ne 200 ]; then
send_alert "Website $TARGET_URL is down (Status: $HTTP_CODE)"
fi
# 5. Проверка срока SSL (оставшееся количество дней)
EXPIRY_DATE=$(echo | openssl s_client -servername "$SSL_DOMAIN" -connect "$SSL_DOMAIN":443 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
CURRENT_EPOCH=$(date +%s)
DAYS_REMAINING=$(( ($EXPIRY_EPOCH - $CURRENT_EPOCH) / 86400 ))
if [ "$DAYS_REMAINING" -lt 14 ]; then
send_alert "SSL Certificate for $SSL_DOMAIN expires in $DAYS_REMAINING days"
fi
echo "Health check complete."
Скрипт использует стандартные команды Linux и напрямую запрашивает данные у ядра и базовых системных источников:
Если хотите глубже прокачать базу по защите, пригодится наш гайд про основы безопасности Linux-сервера.
В примере выше оповещения отправляются через веб-хук. Почему не email?
mail или sendmail — классика командной строки Linux, но в реальности доставить письмо во Входящие, а не в Спам, сложно. Нужны корректные SPF, DKIM и DMARC.
Для простого мониторинга запрос в веб-хук Slack, Discord или Telegram обычно быстрее, проще и безопаснее:
Если email всё-таки нужен, можно заменить curl в функции send_alert на:
echo "$MESSAGE" | mail -s "Server Alert" your@email.com
Скрипт бесполезен, если его запускать вручную. Тут нужен cron.
Чтобы запланировать проверку здоровья сервера, откройте crontab:
crontab -e
Запускать слишком часто не надо, иначе поймаете поток ложных срабатываний. Для простых схем обычно достаточно 5-10 минут, дальше подстроите под себя.
Добавьте в конец файла:
*/5 * * * * /home/youruser/health.sh >> /var/log/myhealth.log 2>&1
Если вы только входите в тему планировщиков, cron превращает сервер в автоматизированного работника.
Мы пишем вывод в /var/log/myhealth.log. Со временем файл разрастётся. И если его не контролировать, ваши же логи мониторинга могут вызвать тот самый алерт “Disk Full”, от которого вы защищаетесь.
Для этого в Linux есть logrotate — утилита, которая тихо в фоне ротирует, сжимает и удаляет старые логи.
Создайте конфиг:
sudo nano /etc/logrotate.d/myhealth
Добавьте:
/var/log/myhealth.log {
weekly
rotate 4
compress
missingok
notifempty
}
То есть: «ротируем лог раз в неделю, храним 4 недели накопленных данных, старое сжимаем, не паникуем, если файла нет, и не трогаем пустые логи».
Никогда не доверяйте системе мониторинга, которая никогда не давала сбоев. Можно аккуратно симулировать аварию и убедиться, что алерт реально доходит.
Вот как безопасно сломать всё с помощью команд Linux:
Описанный подход идеально подходит для одиночных серверов. Тут и практика с терминалом Linux, и понимание, что происходит с сервером.
Но если у вас сотни серверов, обновление такого скрипта на каждом станет вашим ночным кошмаром. В этот момент логично смотреть в сторону Ansible для автоматизации развёртывания и обновлений или Zabbix для централизованного мониторинга.
И всё же для базовой инфраструктуры простота мониторинга в терминале — это must-have.
В итоге у вас есть рабочая кастомная система мониторинга. Она почти ничего не стоит, при этом надежна и позволяет переносить ту же логику на разные сценарии и разные серверы.