Анализ логов сервера — самый честный источник информации о том, что происходит с вашим проектом: мониторинг покажет, что CPU загружен, а логи Nginx ответят, кто и чем его грузит. В журналах видно всё: всплески ошибок 5xx перед падением, боты, выкачивающие сайт, попытки найти уязвимости перебором путей, медленные запросы и реальная посещаемость без прикрас счётчиков. В этой статье разберём практический анализ логов Linux-сервера тремя инструментами — GoAccess для наглядной картины, grep и awk для точечных расследований — и покажем готовые команды, которые находят ботов и проблемы за минуты. Все примеры — для Ubuntu 24.04 LTS и стандартного combined-формата логов Nginx.
Где лежат логи и что в них записано
Основные журналы, с которыми придётся работать:
- /var/log/nginx/access.log — каждый HTTP-запрос: IP, время, метод, URL, код ответа, размер, referer, User-Agent;
- /var/log/nginx/error.log — ошибки веб-сервера: недоступный бэкенд, превышение лимитов, проблемы с конфигом;
- journalctl — системный журнал systemd: события сервисов, SSH, ядра;
- /var/log/auth.log — аутентификация: входы, sudo, неудачные попытки;
- логи приложений — PHP-FPM (
/var/log/php8.3-fpm.log), MySQL, вашего кода.
Строка access.log в combined-формате выглядит так:
203.0.113.42 - - [17/Jul/2026:14:03:11 +0300] "GET /catalog/item-15 HTTP/1.1" 502 552 "-" "Mozilla/5.0 (compatible; SomeBot/1.0)"
Для работы с awk важно помнить номера полей: $1 — IP, $7 — URL, $9 — код ответа. Это стандарт, на нём построены все команды ниже.
GoAccess: вся картина по логам за одну команду
GoAccess — консольный анализатор логов, который превращает гигабайты access.log в интерактивный отчёт: топ посетителей, запрашиваемые URL, коды ответов, User-Agent, распределение по времени. Установка из репозитория Ubuntu 24.04:
sudo apt update && sudo apt install -y goaccess
Интерактивный отчёт прямо в терминале:
goaccess /var/log/nginx/access.log --log-format=COMBINED
HTML-отчёт, который можно открыть в браузере (в том числе обновляемый в реальном времени):
# разовый отчёт
goaccess /var/log/nginx/access.log --log-format=COMBINED -o /var/www/html/report.html
# live-режим: отчёт обновляется по WebSocket
goaccess /var/log/nginx/access.log --log-format=COMBINED -o /var/www/html/report.html --real-time-html
Чтобы проанализировать логи вместе с уже ротированными архивами:
zcat /var/log/nginx/access.log.*.gz | goaccess /var/log/nginx/access.log - --log-format=COMBINED
На что смотреть в отчёте в первую очередь:
- Панель «HTTP Status Codes» — доля 4xx и 5xx. Больше 1–2% ошибок 5xx — повод для расследования.
- «Hosts» — топ IP по числу запросов. Один адрес с десятками тысяч хитов — почти наверняка бот.
- «Requested Files» — что запрашивают. Всплески по несуществующим путям — сканеры уязвимостей.
- «Browsers» / «User-Agents» — сколько трафика приходится на заявленных ботов.
GoAccess парсит логи очень быстро, но на многогигабайтных файлах скорость упирается в диск — на NVMe-накопителях (у Cheap-Host они стоят во всех тарифах) гигабайтный лог разбирается за секунды.
grep и awk: точечные расследования
GoAccess отвечает на вопрос «что происходит вообще», а grep и awk — на вопрос «что случилось конкретно здесь и сейчас». Набор команд, который стоит сохранить в закладки.
Ошибки 5xx: считаем и находим виновных
# сколько всего ответов 5xx
awk '$9 ~ /^5/' /var/log/nginx/access.log | wc -l
# какие именно коды и сколько раз
awk '$9 ~ /^5/ {print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# на каких URL возникают ошибки
awk '$9 ~ /^5/ {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# в какие минуты был всплеск (группировка по времени до минут)
awk '$9 ~ /^5/ {print substr($4, 2, 17)}' /var/log/nginx/access.log | uniq -c | sort -rn | head
Дальше — за причиной в error.log. Например, ошибки 502 почти всегда означают, что бэкенд не ответил:
grep "connect() failed\|upstream timed out\|no live upstreams" /var/log/nginx/error.log | tail -20
Если в error.log видны таймауты PHP-FPM — проблема в нехватке воркеров или медленном коде; как правильно рассчитать пул, разобрано в статье об оптимизации PHP-FPM. А если 5xx появляются только под наплывом трафика — сервер упирается в лимиты, и стоит почитать про оптимизацию Nginx под высокую нагрузку.
Топ IP: кто создаёт нагрузку
# топ-20 адресов по числу запросов
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -20
# что именно делает подозрительный IP
grep "203.0.113.42" /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head
# сколько запросов в минуту делает этот IP
grep "203.0.113.42" /var/log/nginx/access.log | awk '{print substr($4, 2, 17)}' | uniq -c | sort -rn | head
Обычный посетитель делает десятки запросов за визит. Сотни запросов в минуту с одного IP часами — это парсер, сканер или качалка.
Вычисляем ботов
Боты бывают трёх типов: честные (поисковики), заявленные (парсеры с ботовским User-Agent) и маскирующиеся под браузер. Ищем каждый тип по-своему:
# заявленные боты по User-Agent
awk -F'"' '{print $6}' /var/log/nginx/access.log | grep -i "bot\|crawl\|spider\|scan" | sort | uniq -c | sort -rn | head -20
# сканеры уязвимостей: перебор типовых путей
grep -E "\.env|wp-login|phpmyadmin|\.git/|xmlrpc\.php" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head
# кто получает много 404 (перебор несуществующих страниц)
awk '$9 == 404 {print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
Честного поисковика проверяйте обратным DNS: у настоящего Googlebot PTR-запись указывает на googlebot.com или google.com:
host 66.249.66.1
Если IP представляется Googlebot, а резолвится в чужую сеть — это подделка, можно смело блокировать. Найденных вредителей отправляйте в файрвол или fail2ban — подробная настройка описана в статье о комплексной защите от брутфорса.
Системные журналы: journalctl и auth.log
Веб-логи — не единственный источник. Проблемы уровня системы ищите в journalctl:
# все ошибки системных служб за сегодня
journalctl -p err --since today
# журнал конкретного сервиса
journalctl -u nginx --since "1 hour ago"
# убийца процессов OOM: не прибивало ли ядро ваши сервисы из-за нехватки памяти
sudo dmesg -T | grep -i "out of memory\|oom"
Последняя команда — обязательная проверка при «беспричинных» падениях MySQL или PHP-FPM: если ядро прибило процесс из-за нехватки памяти, в dmesg останется запись. Частое срабатывание OOM-киллера — сигнал, что серверу пора добавить RAM (у Cheap-Host апгрейд тарифа проходит без потери данных) или настроить своп.
Попытки подбора пароля к SSH смотрите так:
# количество неудачных попыток входа за сегодня
journalctl -u ssh --since today | grep -c "Failed password"
# топ атакующих IP
journalctl -u ssh --since today | grep "Failed password" | grep -oE "from [0-9.]+" | sort | uniq -c | sort -rn | head
Регламент: как анализировать логи, чтобы не утонуть
Логи полезны только при регулярной работе с ними. Практичный минимум:
| Периодичность | Что делать | Инструмент |
|---|---|---|
| При инциденте | Всплеск 5xx по минутам, причина в error.log, виновные IP | awk, grep |
| Раз в день (автоматически) | HTML-отчёт GoAccess по вчерашнему логу | GoAccess + cron |
| Раз в неделю | Топ ботов, доля 4xx/5xx, новые сканеры, проверка dmesg на OOM | GoAccess, journalctl |
| Постоянно | Автоблокировка перебора, контроль места под логи (df -h) | fail2ban, logrotate |
Автоматический ежедневный отчёт делается одной строкой в cron (запуск в 00:05 по вчерашнему ротированному логу):
5 0 * * * zcat -f /var/log/nginx/access.log.1 | goaccess - --log-format=COMBINED -o /var/www/html/report-daily.html
Не забывайте про ротацию: на посещаемом сайте access.log растёт на сотни мегабайт в сутки. В Ubuntu logrotate уже настроен для Nginx (ежедневная ротация, 14 дней хранения, сжатие) — конфиг лежит в /etc/logrotate.d/nginx. Для полной картины здоровья сервера логи стоит дополнить метриками — как собрать связку графиков и алертов, описано в статье о мониторинге с Grafana и Prometheus.
FAQ
Какие логи смотреть в первую очередь при проблемах с сайтом?
Сначала error.log Nginx — там причины ошибок 5xx. Затем access.log для картины трафика, журнал приложения (PHP-FPM, Node.js) и journalctl -p err для системных ошибок. При внезапных падениях сервисов проверьте dmesg на OOM.
Как быстро посчитать ошибки 5xx в access.log?
awk '$9 ~ /^5/' /var/log/nginx/access.log | wc -l — посчитает все ответы 500–599. Девятое поле в combined-формате — код ответа.
Как отличить полезного бота от вредного?
Полезные (Googlebot, YandexBot) честно представляются в User-Agent и подтверждаются обратным DNS. Вредные маскируются под браузер, делают сотни запросов в минуту и перебирают типовые пути вроде /wp-admin, .env, .git.
GoAccess или grep/awk — что выбрать?
И то и другое: GoAccess — для общей картины (топ IP, URL, коды, боты), grep/awk — для точечных вопросов: кто вызвал всплеск 502 в 14:03, что перебирает конкретный IP.
Как логи не переполнят диск?
Ротацией занимается logrotate — для Nginx в Ubuntu она включена по умолчанию (ежедневно, 14 архивов, сжатие). Контролируйте место командой df -h; при активном трафике и долгом хранении логов выбирайте тариф с запасом по диску.
Вывод
Анализ логов сервера сводится к трём навыкам: GoAccess даёт общую картину трафика за минуту, awk по девятому полю мгновенно находит ошибки 5xx и их источники, а grep по User-Agent и типовым путям вычисляет ботов и сканеры. Добавьте еженедельный регламент и автоматический отчёт по cron — и большинство проблем вы будете замечать раньше, чем их заметят посетители.
Если нужен сервер, где и логам, и проектам хватит места и скорости — у Cheap-Host тариф Pro за 750 ₽/мес: 12 vCPU, 16 ГБ RAM и NVMe 128 ГБ, на котором GoAccess разбирает гигабайтные журналы за секунды. KVM, безлимитный трафик, выдача за 45–60 секунд — тарифы на cheap-host.onl.