Технологии 173 просмотров

Мониторинг и алертинг Ubuntu-сервера: как ловить проблемы до звонка от клиента

Практический контур мониторинга после приёмки сервера: uptime, метрики, логи, Telegram-алерты, пороги и runbook без зоопарка инструментов.

Мониторинг и алертинг Ubuntu-сервера: как ловить проблемы до звонка от клиента

В статье про приёмку dedicated-сервера мы зафиксировали железо, сеть и безопасность в момент выдачи root. Это точка «ноль». Дальше начинается настоящая жизнь сервера: диск заполняется логами, PHP-FPM упирается в пул, сертификат истекает в выходные, а клиент узнаёт об этом раньше вас.

За 17 лет работы с сервисами я видел один и тот же сценарий десятки раз: всё «вроде работало», пока не упал аптайм, не выросли таймауты и не просели позиции или конверсия. Мониторинг — это не красивые графики ради графиков. Это способ узнавать о проблеме до звонка от клиента и до того, как поисковик зафиксирует серию ошибок обхода.

Эта статья — практическое руководство по мониторингу и алертингу для Ubuntu (VPS и dedicated): что именно смотреть, какие пороги ставить, какой минимальный стек собрать без корпоративного зоопарка, как слать алерты в Telegram и как не утонуть в ложных срабатываниях.


1. Зачем мониторинг бизнесу и SEO

Акцент: мониторинг окупается не «галочкой DevOps», а сохранённой выручкой и нервами. Минута простоя интернет-магазина или SEO-сервиса дороже часа настройки алертов.

Связка простая:

  • Аптайм — доступность страниц, API, личных кабинетов, вебхуков оплаты.
  • Скорость — медленный TTFB и таймауты бьют по Core Web Vitals и по отказу пользователя.
  • Ошибки 5xx — поисковик и рекламные системы видят деградацию раньше, чем вы откроете логи.
  • SSL / DNS / диск 100% — классика «сайт лежит, а в панели всё зелёное», потому что смотрели не туда.

Приёмка сервера отвечает на вопрос «железо живое сейчас?». Мониторинг отвечает на вопрос «оно останется живым завтра в 03:14, когда упадёт cron бэкапа и забьёт диск?».

СигналЧто теряет бизнесКак ловить раньше клиента
HTTP 5xx / timeoutЗаявки, оплаты, довериеВнешний HTTP-check + алерт в Telegram
Диск > 90%Падение БД, логи, деплойПорог на filesystem + inode
SSL < 14 днейБраузерный warning, обрыв APIПроверка срока сертификата
Очередь растётПисьма/вебхуки «зависли»Метрика depth очереди
Load / PHP-FPM fullМедленный сайт, SEO-просадкаLatency + pool utilization

2. Четыре слоя контроля

Если ставить «всё сразу», получите шум. Если поставить только uptime-пинг — пропустите заполненный диск и умирающий PHP-FPM. Рабочая модель — четыре слоя.

СлойВопросПримерыКак часто
Синтетика снаружиСайт открывается у пользователя?HTTP 200, SSL, DNS, keyword на странице1–5 мин
ХостСерверу хватает ресурсов?CPU, RAM, disk, inode, temperature, SMART15–60 сек / агент
СервисыСтек приложения жив?nginx, php-fpm, mysql, redis, queue worker30–60 сек
Бизнес-сигналыПродукт делает работу?Очередь писем, cron бэкапа, webhook delivery1–15 мин

Практика: для одного-двух серверов не нужен сразу кластер Prometheus. Нужен внешний uptime + локальные метрики + 5–10 понятных алертов. Сложность добавляйте, когда появляется парк машин или команда дежурств.


3. Метрики и пороги: что считать нормой

Пороги без контекста бесполезны. Ниже — стартовые значения для типичного веб-сервера на Ubuntu. Подстройте под свой трафик, но не начинайте с «алертить всё».

МетрикаWarningCriticalКомментарий
Disk used> 80%> 90%Отдельно следите за / и разделом БД/бэкапов
Inode used> 80%> 90%Частая причина «диск есть, писать нельзя»
Load average (на 1 CPU)> 1.0> 2.0 долгоСмотрите устойчивый рост, не один пик деплоя
RAM available< 15%< 8% + swap thrashВажнее available, чем «free»
HTTP latency (главная/API)> 1–2 с> 5 с или timeoutСинтетика снаружи важнее локального curl
5xx rate> 1%> 5% / любые 5xx пачкойСчитайте окно 5–15 минут
SSL expiry< 21 день< 7 днейАлерт в рабочее время + повтор за 3 дня
Backup age> 26 ч> 48 чБэкап без проверки восстановления — самообман
Queue depthрост 15+ минрост + worker downЗависит от продукта — зафиксируйте базовую линию
# Быстрый снимок «живости» хоста
df -hT
df -i
free -h
uptime
nproc
systemctl is-active nginx php*-fpm mysql redis-server 2>/dev/null

4. Выбор стека без перегруза

Инструментов много. Для блога, лендинга, Laravel/Bitrix-проекта и пары VPS обычно хватает компактной связки.

ЗадачаПростой стекКогда усложнять
Внешний uptime / SSLUptime Kuma (self-hosted) или внешний ping-сервисНужны мультирегион и SLA-отчёты клиентам
Метрики хоста в реальном времениNetdata или node_exporterЕдиный Grafana на десятки серверов
Алерты человекуTelegram-ботPagersDuty/Opsgenie при круглосуточном дежурстве
Логи приложенияjournalctl + ротация + grep-алертыLoki/ELK, когда логов гигабайты в день
Бизнес-healthСвой /health endpointОтдельные SLO-дашборды

Рекомендуемый минимум для одного Ubuntu-сервера:

  1. Uptime Kuma (на отдельном маленьком VPS или у провайдера) — смотрит сайт снаружи.
  2. Netdata на самом сервере — CPU/RAM/disk/сервисы.
  3. Telegram — канал алертов.
  4. /health у приложения — «стек поднялся и БД отвечает».
  5. Cron-проверка бэкапа и срока SSL.

Prometheus + Grafana берите, когда уже понимаете, какие 10 графиков смотрите каждую неделю. Иначе получите красивую пустоту и ноль реакции на инциденты.


5. Внешний uptime и синтетические проверки

Локальный мониторинг не заменит взгляд «как у пользователя». Сервер может быть жив, а сайт снаружи — нет: упал балансировщик, протух DNS, провайдер режет маршрут, Let's Encrypt не обновился.

Что проверять снаружи

  • Главная: HTTP 200, время ответа, наличие ключевой строки в HTML.
  • Критичный API/форма: POST/GET health, не только «картинка открылась».
  • HTTPS: валидный сертификат, корректная цепочка.
  • DNS: A/AAAA резолвятся в ожидаемые адреса.
  • Редиректы: http → https, www → apex (если так задумано).
# Ручная синтетика — удобно для отладки порогов
curl -sS -o /dev/null -w '%{http_code} time=%{time_total}\n' https://abramov.top/ru
curl -sSI https://abramov.top/ru | head -n 20
echo | openssl s_client -servername abramov.top -connect abramov.top:443 2>/dev/null \
  | openssl x509 -noout -dates -subject

Важно: монитор должен жить не на том же сервере, который проверяете. Иначе при падении машины вы не получите алерт «сайт лежит» — упадёт и сторож.

Антифлап для uptime

  • Алерт после 2–3 неудач подряд, не с первой ошибки.
  • Интервал 60–180 секунд для критичных URL.
  • Отдельные мониторы: «сайт», «админка», «API оплаты» — разная критичность.
  • Recovery-уведомление «уже живо» обязательно: иначе непонятно, закрыт инцидент или нет.

6. Хост: CPU, RAM, диск, inode, SMART

После приёмки SMART и температуры нельзя «забыть навсегда». Мониторинг превращает разовый чек-лист в постоянный контроль износа.

Диск и inode

df -hT
df -i
du -xh /var/log 2>/dev/null | sort -h | tail -n 20
du -xh /var/lib/mysql 2>/dev/null | sort -h | tail -n 10

Типичные убийцы места: логи Nginx/PHP без ротации, бэкапы в /var, старые Docker-слои, storage/logs Laravel, journald без лимита.

# Лимит журнала systemd — базовая гигиена
sudo journalctl --disk-usage
sudo nano /etc/systemd/journald.conf
# SystemMaxUse=500M
sudo systemctl restart systemd-journald

Память и swap

free -h
vmstat 1 5
ps aux --sort=-%mem | head -n 15

Если swap постоянно «молотится», сайт может формально отвечать, но для SEO и пользователей это уже деградация. Алерт полезнее на высокий si/so в vmstat и низкий available RAM, чем на «swap > 0».

SMART в динамике

sudo smartctl -H /dev/sda
sudo smartctl -A /dev/sda | grep -iE 'Reallocated|Pending|Uncorrect|Temperature|Media'
# NVMe
sudo smartctl -A /dev/nvme0n1 | grep -iE 'percentage|temperature|media|unsafe'

Имеет смысл раз в сутки писать краткий SMART-снимок в файл и алертить на рост Reallocated / Pending. Это прямое продолжение логики из статьи про приёмку сервера.


7. Сервисы: Nginx, PHP-FPM, БД, очереди

«Сервер пингуется» ≠ «сайт работает». Нужны проверки процессов и прикладного health.

systemd как первый контур

systemctl is-active nginx
systemctl is-failed --quiet nginx && echo 'nginx failed'
systemctl status php8.3-fpm --no-pager -l | head
systemctl status mysql --no-pager -l | head

В Netdata/Prometheus обычно есть unit-state. Минимум — алерт, если critical unit не active.

Nginx: ошибки и latency

sudo tail -n 100 /var/log/nginx/error.log
sudo awk '$9 ~ /^5/ {c++} END {print c+0}' /var/log/nginx/access.log
# если есть отдельный access лог за день — считайте 5xx за окно

PHP-FPM: пул и медленные запросы

# пример статуса пула (если включён pm.status_path)
curl -s http://127.0.0.1/fpm-status
# медленные скрипты
sudo find /var/log -name '*slow*.log' 2>/dev/null
sudo journalctl -u php*-fpm -p err --since '15 min ago' --no-pager

Красный флаг: max children reached, очередь listen растёт, average latency скачет. Для бизнеса это выглядит как «сайт тупит», даже при зелёном uptime-пинге.

База данных

sudo mysqladmin ping
sudo mysql -e "SHOW GLOBAL STATUS LIKE 'Threads_connected'; SHOW GLOBAL STATUS LIKE 'Slow_queries';"
  • Алерт: MySQL/MariaDB не отвечает.
  • Warning: рост connected к потолку max_connections.
  • Warning: резко вырос slow_queries после релиза.

Очереди и cron

Для Laravel-подобных приложений критично знать: worker жив и очередь не растёт бесконечно.

# пример идеи health-команды приложения
php /var/www/app/artisan queue:monitor
php /var/www/app/artisan schedule:list
# возраст последнего успешного бэкапа
find /backups -type f -printf '%T@ %p\n' | sort -n | tail -n 5

Свой endpoint /health

# Концепт ответа health (приложение должно реализовать логику)
curl -sS https://example.com/health
# ожидаем JSON вроде:
# {"status":"ok","db":true,"cache":true,"queue":"ok"}

Совет: /health не кэшируйте на CDN агрессивно и не открывайте публично без необходимости. Лучше ограничить по IP монитора или закрыть basic-auth/секретом в заголовке.


8. Логи, journald и безопасность

Метрики говорят «что-то плохо». Логи говорят «почему». Но алертить на каждую строку error — путь к игнору уведомлений.

Что алертить из логов

  • Всплеск 5xx в Nginx за 5 минут.
  • PHP Fatal / OOM killer.
  • Disk I/O errors / MCE в dmesg (наследник чек-листа приёмки).
  • Массовые failed SSH login — не «каждый бот», а аномальный скачок или успешный вход с нового IP.
  • fail2ban: бан критичных jail — infормативно, но не critical.
sudo dmesg -T | grep -iE 'error|fail|mce|oom|out of memory' | tail
sudo journalctl -p err..alert --since '30 min ago' --no-pager
sudo tail -n 50 /var/log/auth.log
sudo fail2ban-client status sshd 2>/dev/null

Базовый hardening (SSH-ключи, UFW, fail2ban) разобран в Linux Survival Guide. Мониторинг не заменяет hardening — он сообщает, что защита сработала или что её обошли.


9. Алертинг: приоритеты и борьба с шумом

Плохой алертинг хуже отсутствия мониторинга: через неделю все уведомления в mute.

ПриоритетКогдаКудаПримеры
P1 CriticalСейчас ломает клиентовTelegram + звукСайт 5xx, диск 95%, MySQL down, SSL expired
P2 HighСкоро станет P1TelegramДиск 85%, SSL < 7 дней, worker down
P3 MediumНужно в рабочее времяDigest / тихий каналРост latency, warning SMART, необычный CPU
P4 InfoКонтекстЛог-каналДеплой завершён, бэкап ok, recovery

Правила антишума

  1. Подтверждение: 2–3 failed checks подряд.
  2. Окно: считайте rate за 5–15 минут, не мгновенный spike.
  3. Дедупликация: не слать один и тот же critical каждые 60 секунд — reminder раз в 10–15 минут, пока не recovery.
  4. Тихие часы: P3 не будит ночью; P1 будит всегда.
  5. Один канал ответственности: лучше один Telegram-чат on-call, чем 12 размытых групп.
  6. Алерт = действие: если непонятно, что делать — это не алерт, а график.

Тест на зрелость: раз в квартал устройте game day — остановите PHP-FPM на staging/копии и проверьте, что алерт пришёл, runbook понятен, эскалация сработала.


10. Telegram-бот для критичных событий

Telegram — нормальный канал для соло-разработчика и небольшой команды. Главное — не слать туда всё подряд.

# Отправка сообщения в Telegram (токен и chat_id храните вне git)
TOKEN="123456:ABC"
CHAT_ID="123456789"
TEXT="P1: https://example.com возвращает 502 уже 3 минуты"
curl -sS -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
  -d chat_id="${CHAT_ID}" \
  --data-urlencode text="${TEXT}"
#!/usr/bin/env bash
# /usr/local/bin/check-disk-alert.sh
set -euo pipefail
THRESH=90
USED=$(df -P / | awk 'NR==2 {gsub(/%/,"",$5); print $5}')
STATE_FILE=/tmp/disk_alert_root.state
TOKEN_FILE=/root/.secrets/tg_token
CHAT_FILE=/root/.secrets/tg_chat

if [ "$USED" -ge "$THRESH" ]; then
  if [ ! -f "$STATE_FILE" ]; then
    TOKEN=$(cat "$TOKEN_FILE")
    CHAT=$(cat "$CHAT_FILE")
    MSG="P1: диск / заполнен на ${USED}% на $(hostname)"
    curl -sS -X POST "https://api.telegram.org/bot${TOKEN}/sendMessage" \
      -d chat_id="${CHAT}" --data-urlencode text="${MSG}" >/dev/null
    touch "$STATE_FILE"
  fi
else
  rm -f "$STATE_FILE"
fi
# cron каждые 5 минут
*/5 * * * * root /usr/local/bin/check-disk-alert.sh

Аналогично собираются проверки SSL, возраста бэкапа, systemctl is-active. Uptime Kuma и Netdata умеют Telegram из коробки — скрипты нужны для тонких бизнес-проверок, которых нет в UI.


11. Runbook: короткий план реакции

Алерт без инструкции превращается в панику. Держите рядом с каналом уведомлений одностраничный runbook.

АлертПервые 5 минутЕсли не ожило
HTTP 5xxsystemctl status nginx php-fpm, tail error.log, место на дискеОткат релиза / включить maintenance / эскалация хостеру
Disk > 90%df -h, du по /var/log, ротация, чистка старых бэкаповРасширение диска, перенос логов
DB downmysqladmin ping, journal БД, диск, памятьRestore из последнего проверенного бэкапа
SSL < 7 днейРучной renew, проверка cron certbot/acmeВыпуск временно на другом клиенте, правка nginx
SMART pendingСнизить нагрузку на запись, полный smartctl-отчётТикет хостеру, миграция данных

После инцидента запишите: симптом → причина → дыра в мониторинге → новый алерт или новый порог. Иначе история повторится через месяц.


12. Чек-лист: поднять мониторинг за один вечер

  1. Выписать 5 пользовательских сценариев, которые нельзя ломать (главная, форма, API, оплата, админка).
  2. Поднять внешний uptime (Uptime Kuma или аналог) не на том же сервере.
  3. Добавить проверки HTTP + SSL + DNS на эти сценарии, антифлап 2–3 ошибки.
  4. Установить Netdata (или node_exporter) на боевой Ubuntu.
  5. Включить алерты: disk 80/90, inode 80/90, RAM available, unit down для nginx/php/db.
  6. Сделать /health приложения (БД + кэш минимум).
  7. Проверка возраста бэкапа раз в час + алерт, если старше суток.
  8. Telegram-канал: P1/P2 отдельно от информационного шума.
  9. Написать runbook на 5 главных алертов.
  10. Устроить тестовый инцидент на staging и убедиться, что сообщение дошло.
  11. Раз в неделю 15 минут: посмотреть графики, ложные алерты, подкрутить пороги.
  12. Связать с приёмкой: раз в месяц SMART/температуры/RAID — как профилактика железа.
# Мини-комплект утилит на сервере
sudo apt update
sudo apt install -y curl jq smartmontools lm-sensors sysstat
# sysstat даёт sar — история CPU/IO, удобно разбирать «что было вчера в 19:40»
sudo systemctl enable --now sysstat

13. Мониторинг глазами SEO

Для сайта с трафиком из поиска мониторинг — часть технического SEO, не только админки.

  • Доступность — долгий даунтайм = выпадение страниц и потеря доверия к краулингу.
  • Скорость под нагрузкой — «в Lighthouse было 95» не спасает, если ночью PHP-FPM лежит в очереди.
  • Корректные ответы — внезапные 500 на категориях хуже, чем медленный 200.
  • SSL и редиректы — ошибки цепочки и циклы редиректов ломают обход.
  • Целостность витрины — синтетика может проверять наличие title/H1/ключевого блока, не только код 200.

Микроразметка и чистый HTML помогают роботам понимать страницу — об этом руководство по Schema.org. Но если сервер нестабилен, идеальная JSON-LD не спасёт поведенческие и краулинговые метрики.


Приёмка сервера даёт вам честную точку старта. Мониторинг и алертинг сохраняют эту честность каждый день: вы узнаёте о диске, 5xx, SSL и мёртвом worker раньше клиента.

Не начинайте с «большой observability-платформы». Начните с четырёх слоёв, десяти понятных алертов, Telegram и runbook. Когда шум побеждён и реакции отработаны — наращивайте глубину метрик.

Связанные материалы:

Нужна помощь с контуром мониторинга под ваш проект — напишите в Telegram или через страницу контактов.

Комментарии

Комментарии появляются после модерации.

Опубликованных комментариев пока нет. Будьте первым.

Написать в Telegram
Cookies Этот сайт использует файлы cookie для улучшения работы сервиса и аналитики. Продолжая использование сайта, вы соглашаетесь с обработкой данных.