Зачем нужен лёгкий мониторинг и какие задачи он решает
Минимальный мониторинг сервера собирается из двух слоёв. Первый: ручные проверки штатными командами uptime, free, df, du и htop, когда состояние нужно оценить прямо сейчас. Второй: автоматические уведомления о падении сервиса через лёгкий контейнер Uptime Kuma, а графики нагрузки закрывает Netdata, который ставится одной командой. Оба слоя помещаются на один недорогой VPS и не требуют отдельного стека с базой метрик.
Правило, которое нарушают чаще всего: мониторинг ставят на тот же сервер, который он проверяет. При падении хоста упадут и проверки, и уведомления, поэтому о проблеме вы узнаете от пользователей. Держите мониторинг на отдельной машине или во внешнем сервисе. Практический разбор такого подхода с командами и конфигами есть в материале про мониторинг VPS: нагрузка и доступность.
Две задачи мониторинга: доступность и ресурсы
Мониторинг закрывает две разные задачи, и путать их не стоит: понять, работает ли сайт прямо сейчас и кто об этом узнает, а также увидеть, сколько ресурсов тратится и когда кончится запас.
Пример, который объясняет разницу. Сервер отвечает на пинг, load average в норме, а приложение отдаёт 500, потому что база данных перестала принимать подключения. uptime про такое не расскажет: команда показывает нагрузку, а не доступность сервиса. Такой случай ловит HTTP-проверка страницы, которая обращается к базе.
Вторая половина задачи - запас ресурсов. Диск, заполненный на 96%, или 150 МБ свободной памяти требуют внимания сегодня, а не к концу недели.
Когда хватит скриптов, а когда нужны Prometheus или Zabbix
Prometheus и Zabbix дают глубокую аналитику, централизацию и хранение истории, но требуют отдельного сервера под хранилище метрик, экспортёров и времени на настройку дашбордов и правил алертинга. Лёгкий набор закрывает большую часть задач небольшой инфраструктуры за один вечер.
| Критерий | Скрипты, Uptime Kuma, Netdata | Prometheus или Zabbix |
|---|---|---|
| Парк серверов | 1-20 машин | Кластеры, autoscaling, десятки сервисов |
| История метрик | Секунды и часы, для быстрой диагностики | Месяцы и годы, ретеншн настраивается |
| Порог входа | Один контейнер и cron | Дни на настройку агентов и хранилища |
| Расход ресурсов | Десятки мегабайт памяти | Отдельный сервер под базу метрик |
| Кто эксплуатирует | Один инженер без дежурств | Дежурная смена, эскалация, регламенты |
Ориентируйтесь на масштаб и на то, кто дежурит. Для 1-20 серверов, где за инфраструктуру отвечает один инженер, скриптов, Uptime Kuma и Netdata достаточно. Prometheus нужен, когда появляются кластеры и запросы вида «покажи p95 задержки за прошлый квартал». Zabbix выбирают, когда требуется алертинг с эскалацией и дежурствами: триггеры, media type и Actions разобраны в руководстве по настройке оповещений в Zabbix.
Лёгкий набор можно держать рядом с тяжёлой системой: Uptime Kuma проверяет доступность снаружи, Prometheus собирает графики и хранит историю, а скрипты закрывают специфичные проверки, под которые не написан экспортёр.
Быстрая проверка состояния сервера: 5 команд для ручной диагностики
Когда нужно посмотреть состояние сервера прямо сейчас, хватает пяти команд. Каждая занимает секунды, ничего не устанавливает и не требует агентов.
| Команда | Что показывает | На что смотреть |
|---|---|---|
| uptime | load average за 1, 5 и 15 минут | 15-минутное значение против числа ядер |
| free -h | Память: used, free, available, кэш | Колонка available, а не free |
| df -h | Заполнение разделов | Больше 90% на любом разделе |
| du -sh /var/* | sort -h | tail -10 | Топ каталогов по объёму | Логи, старые бэкапы, образы Docker |
| htop | Процессы по CPU и памяти | Кто именно грузит сервер |
Как читать load average и не путать его с загрузкой CPU
uptime
14:32:05 up 23 days, 4:11, 1 user, load average: 0.42, 0.51, 0.48
Три числа в конце - средняя нагрузка за 1, 5 и 15 минут. Сравнивать их нужно с числом ядер: на одноядерном сервере 1.0 означает полную загрузку, на четырёхъядерном это четверть. Число ядер подскажет команда nproc.
Тревожно, когда пятнадцатиминутное значение стабильно выше числа ядер: нагрузка не пиковая, а постоянная. На четырёх ядрах load average 8.0 означает, что очередь задач вдвое длиннее, чем сервер успевает разбирать. Разовое значение 8.0 после ночного бэкапа - повод посмотреть графики, а не будить дежурного.
Память: почему маленькое значение free нормально
free -h
Смотрите колонку available: это реально доступная память с учётом кэша. Колонка free почти всегда маленькая, и пугаться её не нужно: Linux намеренно занимает свободную память под кэш файлов, а при нехватке отдаёт её процессам.
Рабочий пример: free показывает 200 МБ, available 3.5 ГБ. Серверу хватает памяти. Если available в гигабайтах опускается к сотням мегабайт и при этом работает swap, разбирайтесь, какой процесс съел память, через ту же htop с сортировкой по столбцу MEM%.
Диски: когда заполнение 90% становится тревогой
df -h
Заполнение выше 90% - повод разбираться в тот же день. При 100% сервер перестаёт работать: базы не пишут, логи не пишутся, сайт отдаёт ошибки. Отдельно проверьте inode командой df -i: место может быть свободно, а файловых дескрипторов уже нет.
Найти, что занимает место:
du -sh /var/* | sort -h | tail -10
Чаще всего виноваты логи в /var/log, старые бэкапы или образы Docker. Если du показывает десятки гигабайт в /var/lib/docker, чистите неиспользуемые образы и тома, а не только контейнеры. Скрипты, которые создают бэкапы, стоит сразу учить удалять копии старше N дней: готовые примеры есть в статье про автоматизацию резервного копирования и восстановления.
Пятая команда показывает, кто грузит сервер:
apt install htop -y
htop даёт интерактивную таблицу процессов: сортировка по CPU и памяти, видно, кто именно нагружает сервер. На минимальных образах, где htop ставить нечем, эквивалент руками - ps aux --sort=-%cpu | head.
Скрипт проверки доступности портов и HTTP-статусов
Ручных проверок хватает для дежурного взгляда. Повторяющиеся сценарии лучше оформить скриптом: он вернёт понятный код возврата и не забудет проверить порт в три часа ночи.
Проверка TCP-портов через nc и timeout
nc -zv example.com 443
Ключ -z переводит nc в режим сканирования без передачи данных, -v печатает результат. Команда возвращает 0, если порт открыт, и 1, если порт закрыт или недоступен. Чтобы проверка не зависла на фильтрующем файрволе, оборачивайте её в timeout:
timeout 5 nc -zv 10.0.0.5 5432
Для базового набора достаточно портов 80, 443 и порта базы данных. Если nc нет в минимальном образе, используйте curl или редирект bash на /dev/tcp.
Проверка HTTP-статуса и содержимого ответа через curl
curl -s -o /dev/null -w '%{http_code}' https://example.com
200 - норма, 500 - ошибка приложения, 503 - сервис недоступен, 301 и 302 - редирект, который тоже стоит заметить. Для API добавьте проверку содержимого, чтобы поймать случай «страница отдаёт 200, а внутри заглушка»:
curl -s https://example.com/health | grep -q 'ok'
grep -q возвращает 0 при совпадении и 1, если строки в ответе нет. Так проверяется и доступность, и работоспособность прикладной логики.
Скрипт объединяет оба типа проверок и отдаёт код возврата для планировщика:
#!/usr/bin/env bash
set -uo pipefail
TARGETS=("example.com:443" "example.com:80" "10.0.0.5:5432")
FAIL=0
for target in "${TARGETS[@]}"; do
host="${target%%:*}"; port="${target##*:}"
if timeout 5 nc -z "$host" "$port" 2>/dev/null; then
echo "OK ${host}:${port}"
else
echo "FAIL ${host}:${port}"; FAIL=1
fi
done
code=$(curl -s -o /dev/null -w '%{http_code}' https://example.com/health)
if [ "$code" != "200" ]; then echo "FAIL health: HTTP $code"; FAIL=1; fi
exit $FAIL
Запуск скрипта по расписанию: cron и systemd timer
*/5 * * * * /opt/scripts/check_ports.sh >/dev/null 2>&1
При ненулевом коде возврата cron отправит письмо локальному пользователю. На практике такие письма никто не читает, поэтому явное уведомление в Telegram или Slack надёжнее; как это сделать, разберём ниже.
Альтернатива крону - systemd timer. Создайте check-ports.service с Type=oneshot и check-ports.timer с OnCalendar=*:0/5 и Unit=check-ports.service. Плюсы: логи в journalctl, запуск только после network-online.target, внятный статус через systemctl list-timers.
Автоматические уведомления о падении: Uptime Kuma в контейнере
Скрипт, запущенный на самом сервере, не расскажет о том, что сервер целиком недоступен. Внешний наблюдатель нужен именно для этого: Uptime Kuma ставится контейнером, интерфейс понятен без чтения документации, а уведомления уходят в Telegram, почту и десяток других каналов. Проверки поддерживают HTTP(s)-адреса, срок действия SSL-сертификата и API-эндпоинты. Детали работы с этим инструментом описаны в материале про мониторинг нагрузки и доступности.
Установка Uptime Kuma через Docker Compose
mkdir -p /opt/uptime-kuma && cd /opt/uptime-kuma
Создайте в этом каталоге файл docker-compose.yml:
services:
uptime-kuma:
image: louislam/uptime-kuma:1
restart: unless-stopped
ports:
- "3001:3001"
volumes:
- ./data:/app/data
docker compose up -d
Откройте http://server:3001, создайте администратора и добавьте первую проверку. Порт 3001 не выставляйте в интернет напрямую: спрячьте панель за обратный прокси с авторизацией или ограничьте доступ по IP через ufw.
Настройка проверок: главная, база, SSL, API
- Главная страница: тип HTTP(s), адрес сайта, интервал 60 секунд, ожидаемый код 200.
- Страница, которая обращается к базе: проверка ловит случай «сайт открывается, но база лежит».
- Срок действия SSL-сертификата: Kuma предупредит заранее, до того как браузеры начнут ругаться.
- Отдельные API-эндпоинты, если они есть: проверяйте и код ответа, и ключевое поле в теле.
Интервал 60 секунд - разумный компромисс: падение замечается почти сразу, а сервер не получает тысячи запросов в сутки. Для внутренних сервисов добавьте проверку типа TCP на конкретный порт.
Подключение Telegram-уведомлений через @BotFather
- Откройте @BotFather в Telegram, выполните /newbot и получите токен бота.
- Узнайте chat id: отправьте боту сообщение и посмотрите ответ метода getUpdates либо используйте бота, который показывает ваш chat id.
- В Uptime Kuma откройте Settings, затем Notifications, добавьте уведомление типа Telegram, вставьте токен и chat id.
- Нажмите Test, чтобы проверить доставку, и привяжите уведомление к нужным проверкам.
Мониторинг не должен жить на том же сервере, который он проверяет: при падении хоста упадут и проверки, и уведомления, и о проблеме вы узнаете от пользователей. Если второй машины нет, берите внешний сервис проверки доступности: у большинства есть бесплатный тариф на несколько адресов, а настройка требует только адреса сайта.
Мониторинг SSL-сертификатов: ручная проверка и автоматическое предупреждение
Ручная проверка сертификата через openssl s_client
openssl s_client -connect example.com:443 -showcerts
Команда покажет цепочку сертификатов, которую отдаёт сервер. Чтобы получить только отпечаток SHA-256 и сравнить его с ожидаемым:
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -fingerprint -sha256 -noout
Сравнение отпечатка с тем, что вы ожидаете увидеть от своего провайдера или из документации сервиса, помогает убедиться, что сервер отдаёт нужный сертификат, а не подменённый на стороне прокси или балансировщика.
Даты действия:
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
Для внутренних доменов и самоподписанных сертификатов удобно держать такой однострочник в wiki и запускать после каждой смены сертификата или переезда балансировщика.
Автоматическое предупреждение об истечении в Uptime Kuma
Ручная проверка спасает, когда о ней помнят. Автоматика надёжнее: при создании HTTP(s)-проверки включите мониторинг SSL-сертификата, и Kuma сама предупредит заранее, например за 14 дней до истечения. Уведомление приходит тем же каналом, что настроен для проверки, то есть в Telegram или на почту, и не требует отдельного скрипта. Для сертификатов из Let's Encrypt этого достаточно, чтобы успеть разобраться с автопродлением до аварии.
Лёгкий сбор метрик и графиков: Netdata одной командой
Установка Netdata и первые шаги
Netdata ставится одной командой через официальный kickstart-скрипт и сразу показывает сотни метрик в реальном времени с секундной детализацией. Скачайте скрипт на официальном сайте Netdata в файл /tmp/netdata-kickstart.sh и запустите его с флагами:
sh /tmp/netdata-kickstart.sh --stable-channel --disable-telemetry
Флаг --disable-telemetry отключает отправку статистики вендору. После установки веб-интерфейс поднимается на порту 19999; фактический порт и доступ проверьте в конфиге netdata.conf, а наружу панель лучше не открывать без авторизации.
Что смотреть в Netdata в первую очередь
Набор графиков зависит от версии и включённых плагинов, но при разборе инцидента смотрят одно и то же:
- CPU: доли system, user и iowait. Высокий iowait означает, что процессы ждут диск, а не считают.
- Память: used, cached, available. Рост used при падении cached - признак утечки или нехватки RAM.
- Диски: загрузка устройства и задержка операций. Рост задержки при небольшом IOPS говорит о проблемах с накопителем или очередью.
- Сеть: пропускная способность и ошибки на интерфейсе. Растущие errors и drops указывают на проблемы линка или перегрузку.
Пример: iowait держится на 30%, а CPU user низкий. Приложение не страдает от вычислений, оно ждёт диск, и дальше смотрим задержки и очередь. Netdata не заменяет Prometheus с его историей на месяцы, но для быстрой диагностики на живом сервере хватает.
Интеграция скриптов с оповещениями и форматы вывода
Exit code и stdout: как скрипт сообщает о результате
Договоритесь о простом контракте: код возврата 0 - успех, 1 - проблема. Данные пишутся в stdout, ошибки и отладочные сообщения в stderr. Тогда скрипт одинаково хорошо работает и в кроне, и в CI, и в systemd timer. cron отправит письмо при ненулевом коде возврата, а systemd пометит юнит как failed и покажет это в systemctl status.
Отправка уведомлений в Telegram через Bot API
curl -s -X POST "https://api.telegram.org/botBOT_TOKEN/sendMessage" -d chat_id=CHAT_ID --data-urlencode "text=Сервер web-01 недоступен"
Подставьте токен от @BotFather и свой chat id. Флаг --data-urlencode нужен для текста с пробелами и кириллицей. Пример скрипта, который следит за диском и шлёт алерт при превышении порога:
#!/usr/bin/env bash
THRESHOLD=90
TOKEN="ВАШ_ТОКЕН"
CHAT_ID="ВАШ_CHAT_ID"
usage=$(df --output=pcent / | tail -1 | tr -dc '0-9')
if [ "$usage" -gt "$THRESHOLD" ]; then
curl -s -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" -d chat_id="${CHAT_ID}" --data-urlencode "text=Диск на web-01 заполнен на ${usage}%"
exit 1
fi
exit 0
Параметр df --output=pcent есть в GNU coreutils, то есть на Linux. На других системах разбор вывода делайте через awk. Уведомление с текстом «Сервер web-01 недоступен» полезнее безликого «exit code 1»: дежурный сразу понимает, что произошло.
Форматы вывода: текст, JSON и лог-файлы
Формат выбирают по потребителю. Для человека достаточно строки вида OK example.com:443 или FAIL db.internal:5432. Для машинной обработки удобнее JSON: его разбирает jq, его принимают системы аналитики и тикетницы, из него собираются сводки.
{"host": "web-01", "disk": "/dev/sda1", "usage": 92, "status": "warning"}
Третий формат - лог-файл или journald. Он нужен для истории: когда через неделю выясняется, что сайт падал трижды, записи с временными метками дают точную картину. Если нужны не только уведомления, но и автоматическая реакция, например блокировка IP по audit.log или разбор подозрительной активности, смотрите подборку скриптов автоматического реагирования на угрозы.
Чек-лист: что настроить в первую очередь
- Прогоните uptime, free -h, df -h и du -sh /var/* | sort -h | tail -10 вручную и запишите текущие значения как точку отсчёта.
- Поставьте htop через apt install htop -y, чтобы за секунды находить процесс, который грузит сервер.
- Разверните Uptime Kuma через Docker Compose в /opt/uptime-kuma на отдельном сервере или во внешнем сервисе проверки.
- Создайте проверки главной страницы, страницы с обращением к базе, API-эндпоинта и срока действия SSL, интервал 60 секунд.
- Подключите Telegram-уведомления через @BotFather и нажмите Test для каждой проверки.
- Напишите скрипт проверки портов и HTTP-статусов, повесьте его на cron каждые 5 минут или на systemd timer.
- Добавьте алерт на заполнение диска выше 90% через df и curl в Telegram Bot API.
- Проверьте сертификат вручную через openssl s_client и сравните отпечаток SHA-256 с ожидаемым.
- Установите Netdata с флагом --disable-telemetry для графиков нагрузки в реальном времени.
- Запишите в wiki, где живёт мониторинг, кто получает алерты и какой канал связи используется, если он упал вместе с сервером.
Если в парке есть Windows-серверы, часть задач закрывают утилиты из подборки программ для системного администратора Windows 2026. Начните с пунктов 1-5: они дают дежурному понимание состояния сервера и уведомление в Telegram в тот же вечер, без развёртывания Prometheus или Zabbix.