Ой, ничего не найдено!

К сожалению, по вашему запросу пока ничего нет (но это только пока!), зато вы можете подписаться на нашу замечательную email-рассылку, чтобы не пропустить самое интересное в будущем.

  • 16

Логи, которые говорят: учимся читать journalctl, nginx и syslog

  • 4 минуты на чтение

Часть 2 из 14 · Серия «Сервер в бою»

В прошлой статье мы разбирали ночную аварию и договорились о главном правиле: сначала смотрим, потом трогаем. Но «смотреть» — это не медитировать на htop. Смотреть — это читать логи. Сервер вообще-то очень разговорчивый собеседник: он подробно записывает всё, что с ним происходит, — кто пришёл, что запросил, что сломалось и почему. Проблема в том, что говорит он на своём языке, в нескольких местах одновременно, и по большей части — о вещах, которые вам не интересны.

Эта статья — про то, как в этом потоке слышать главное. Где какие логи лежат, как их фильтровать, а не листать, и как применить всё это на практике: найдём причину ошибки 502 за пять минут, по секундомеру.

Карта местности: кто и куда пишет

В типичном VPS с Ubuntu/Debian и связкой nginx + PHP + MySQL логи живут в трёх мирах, и путаница между ними — причина половины мучений новичка.

Мир первый: systemd-journal. Всё, что запущено через systemd (а это почти всё: nginx, PHP-FPM, MySQL, sshd, cron), пишет свой стандартный вывод и сообщения о запуске/падении в единый бинарный журнал. Читается он только командой journalctl. Именно здесь лежат ответы на вопросы «почему сервис не стартует» и «кто его убил».

Мир второй: классические текстовые логи в /var/log. Наследие доброго старого syslog, живее всех живых:

1 месяц бесплатно
Сервер с нуля — без боли и гугления каждой команды
Понятная панель, готовые шаблоны и поддержка, которая объясняет по-человечески. Поднимите проект, даже если SSH видите впервые.
Попробовать бесплатно
Файл Что там
/var/log/syslog общесистемный поток: ядро, cron, всякая всячина
/var/log/auth.log входы по SSH, sudo, попытки брутфорса
/var/log/kern.log сообщения ядра (OOM killer живёт здесь)
/var/log/dpkg.log что и когда устанавливалось через apt

Мир третий: собственные логи приложений. Сервисы, которым журнала мало, ведут свои файлы:

Файл Что там
/var/log/nginx/access.log каждый HTTP-запрос: кто, что, каким кодом ответили
/var/log/nginx/error.log ошибки nginx: не достучался до бэкенда, кривой конфиг
/var/log/php8.3-fpm.log жизнь пулов PHP-FPM: перезапуски, нехватка воркеров
/var/log/mysql/error.log старт/стоп MySQL, крэши, проблемы InnoDB
storage/logs/laravel.log и т.п. ошибки уровня вашего кода — внутри проекта

Запоминать таблицы не нужно. Нужно запомнить принцип маршрутизации, он спасает всегда: ошибка HTTP-уровня → nginx, ошибка «сервис умер/не стартует» → journalctl, ошибка в логике сайта → лог приложения, безопасность → auth.log. Сначала выбираем мир, потом уже грепаем.

journalctl: журнал, который умеет фильтровать за вас

Первая ошибка новичка — запустить journalctl без аргументов и утонуть в тысячах строк с начала времён. Journalctl — это не файл, это база данных с языком запросов. Несколько запросов покрывают 95% задач.

Логи конкретного сервиса:

journalctl -u nginx

...за последний час и без листания:

journalctl -u nginx --since "1 hour ago" --no-pager

--since понимает человеческий язык: "today", "yesterday", "2026-07-04 02:00", "10 min ago". Это главный фильтр вообще: авария случилась в 3:12 — вот и смотрите --since "03:00" --until "03:20", а не весь журнал.

Перенос бесплатно
Перерос хостинг? Пора на свой VPS
Бесплатно поможем перенести проект без простоя и потери данных. Больше ресурсов, полный root-доступ и никаких тесных рамок.
Переехать на Siteko

Только ошибки, без информационного шума:

journalctl -p err -b

-p err — приоритет «ошибка и хуже», -b — только текущая загрузка. Это команда номер один для утреннего осмотра сервера: пусто — живём.

Живой хвост (как tail -f):

journalctl -u php8.3-fpm -f

Запустили в одном окне, в другом — воспроизвели проблему на сайте, и смотрите, что сервис скажет в прямом эфире. Простейший, но невероятно эффективный приём.

Прошлая загрузка — помните из первой статьи? Если сервер перезагрузился, разгадка в журнале до ребута:

journalctl -b -1 -e

И маленькая, но важная деталь: journald по умолчанию может жить в памяти и забывать всё после перезагрузки. Проверьте, что журнал персистентный:

mkdir -p /var/log/journal && systemctl restart systemd-journald
от 0 ₽ на старте
Свой сервер по цене чашки кофе в неделю
Прозрачные тарифы без сюрпризов в чеке. Платите за то, что реально используете, и масштабируйтесь, когда вырастете.
Смотреть тарифы

Одна команда — и улики больше не испаряются вместе с ребутом.

Логи nginx: детектив в две колонки

У nginx две книги: access.log — «кто приходил», error.log — «что пошло не так». Начинать почти всегда стоит со второй: она короче и честнее.

error.log. Типичная строка:

2026/07/04 03:12:41 [error] 812#812: *44 connect() to unix:/run/php/php8.3-fpm.sock failed
(111: Connection refused) while connecting to upstream, client: 203.0.113.7,
server: example.com, request: "GET /catalog HTTP/1.1"

Читается как предложение: в 03:12 nginx попытался передать запрос PHP-FPM через сокет — и получил отказ. Connection refused = за сокетом никто не слушает = PHP-FPM мёртв. Диагноз, время, виновник — всё в одной строке. Самые частые фразы этого лога и их перевод:

  • Connection refused — бэкенд не запущен или слушает не там;
  • Resource temporarily unavailable / upstream timed out — бэкенд жив, но захлебнулся: все воркеры заняты (привет pm.max_children, доберёмся в девятой части);
  • No space left on device — а вот и вчерашний забитый диск;
  • Too many open files — упёрлись в лимиты, частый спутник наплыва ботов.

access.log. Формат по умолчанию:

203.0.113.7 - - [04/Jul/2026:03:12:41 +0300] "GET /catalog HTTP/1.1" 502 552
"-" "Mozilla/5.0 ..."

IP, время, запрос, код ответа, размер, реферер, юзер-агент. Поодиночке строки скучные, интересна статистика. И тут начинается настоящая магия однострочников.

SSD/NVMe в комплекте
Скорость, которую видно в первом же отклике
NVMe-диски, свежее железо и честные ресурсы без «соседей», которые съедают всю мощность. Разница чувствуется с первого запроса.
Разогнать проект

Сколько каких кодов мы отдавали за сегодня:

awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
  48211 200
   1302 301
    977 404
    412 502

Кто долбит сервер сильнее всех:

awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10

Если в топе один IP с десятками тысяч запросов — вы нашли либо бота-парсера, либо брутфорсера (и это мостик к следующей статье про fail2ban).

Какие именно URL падают в 502:

awk '$9 == 502 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head

Связка sort | uniq -c | sort -rn — «сгруппируй и отсортируй по частоте» — это швейцарский нож анализа логов. Выучите её один раз, и любой access.log превращается из простыни в аналитический отчёт.

Грепать осмысленно: пять правил

Grep — инструмент простой, но есть разница между «грепать» и «грепать осмысленно».

SSD/NVMe в комплекте
Пока вы это читаете, чей-то сайт уже летает
NVMe-диски, свежее железо и честные ресурсы без «соседей», которые съедают всю мощность. Разница чувствуется с первого запроса.
Разогнать проект

1. Сужайте по времени, а не по слову. Не ищите error по всему логу за месяц — сначала отрежьте нужный интервал (--since в journalctl, или грепните по дате-часу: grep "04/Jul/2026:03:1" access.log), и только внутри него ищите причину. Ошибка недельной давности вас сейчас только запутает.

2. Ищите первую ошибку, а не последнюю. Аварии каскадны: упал MySQL → посыпался PHP → nginx завалил лог пятисотками. Тысячи строк про 502 — это следствия. Мотайте вверх, к моменту, когда всё ещё было хорошо: первая ошибка в цепочке и есть причина.

3. Добавляйте контекст. grep -B 5 -A 5 "Fatal" покажет по пять строк до и после совпадения — часто причина написана строкой выше самой ошибки.

4. Исключайте шум. grep -v — «всё, кроме»: отфильтруйте свои IP, health-чеки мониторинга, знакомый безвредный warning — и в остатке останется настоящее.

5. Не игнорируйте warning'и хронически. Сегодняшний warning — это завтрашний error, который вы уже приучили себя не замечать. Разберитесь один раз или осознанно подавите — но не тренируйте «баннерную слепоту» на собственных логах.

Практикум: находим причину 502 за пять минут

Сведём всё вместе. Ночь, сайт отдаёт 502 Bad Gateway. Секундомер пошёл.

1 месяц бесплатно
Первый сервер? Пусть будет нестрашным
Понятная панель, готовые шаблоны и поддержка, которая объясняет по-человечески. Поднимите проект, даже если SSH видите впервые.
Попробовать бесплатно

Минута 1. 502 = «nginx не дозвался бэкенда». Значит, наш мир — error.log nginx:

tail -50 /var/log/nginx/error.log

Видим: connect() to unix:/run/php/php8.3-fpm.sock failed (111: Connection refused). Подозреваемый назван — PHP-FPM.

Минута 2. Спрашиваем systemd, что с ним:

systemctl status php8.3-fpm

Active: failed (Result: oom-kill) — или просто failed. Мёртв. Но почему — статус говорит не всегда, поэтому...

Минута 3. ...идём в журнал за последними словами покойного:

journalctl -u php8.3-fpm --since "30 min ago" --no-pager

Вариант А: Out of memory: Killed process ... (php-fpm8.3) — OOM killer, знакомый по первой статье. Вариант Б: в логе паника после недавнего Reloading — кто-то (вы, три часа назад) поправил конфиг с опечаткой, и перезапуск его добил. Вариант В: лог обрывается на write: No space left on device — диск.

от 0 ₽ на старте
Свой сервер по цене чашки кофе в неделю
Прозрачные тарифы без сюрпризов в чеке. Платите за то, что реально используете, и масштабируйтесь, когда вырастете.
Смотреть тарифы

Минута 4. Подтверждаем гипотезу фактами: free -h и dmesg -T | grep -i oom для варианта А, php-fpm8.3 -t (проверка конфига) для Б, df -h для В.

Минута 5. И только теперь — лечим: systemctl restart php8.3-fpm, проверяем сайт, записываем причину в заметки. Перезапуск на пятой минуте — с диагнозом на руках — это совсем не то же самое, что перезагрузка на первой.

Заметьте маршрут: симптом → error.log nginx → systemctl status → journalctl → подтверждение → лечение. Он один и тот же почти для любой аварии, меняются только имена сервисов.

Пока логи не съели диск

Ложка дёгтя напоследок: логи — единственный источник правды, и они же — классический пожиратель диска. Access.log нагруженного сайта спокойно набирает гигабайты в неделю, а journald без лимитов расползается на всё свободное место. Быстрая проверка, кто сколько занял:

du -sh /var/log/* | sort -rh | head
journalctl --disk-usage

Журналу можно тут же выставить потолок (SystemMaxUse=500M в /etc/systemd/journald.conf), а текстовыми логами заведует logrotate — но это уже сюжет пятой статьи серии, про внезапно закончившийся диск. Пока просто знайте: за разговорчивость сервера кто-то платит гигабайтами.

Логи — это не наказание и не архив на случай суда. Это сервер, который всё время пытается вам что-то сказать. Научитесь задавать ему правильные вопросы — journalctl -u, --since, sort | uniq -c — и большинство «загадочных» аварий перестанут быть загадочными ещё до того, как вы откроете второй терминал. А в следующей статье почитаем самый тревожный лог сервера — auth.log — и посмотрим, сколько незваных гостей стучится в ваш SSH прямо сейчас. Спойлер: сотни. И поставим на дверь fail2ban.

1 месяц бесплатно
Сервер с нуля — без боли и гугления каждой команды
Понятная панель, готовые шаблоны и поддержка, которая объясняет по-человечески. Поднимите проект, даже если SSH видите впервые.
Попробовать бесплатно

VDS с первого дня

Свой сервер Siteko под полным контролем

NVMe-диски, root-доступ и честные ресурсы без «соседей». Поднимите VPN, бота или прод-проект и масштабируйтесь без тесных рамок.

  • Root-доступ полная свобода настройки под ваш стек.
  • NVMe и свежее железо скорость заметна с первого запроса.
  • Перенос бесплатно поможем переехать без простоя.
Выбрать VDS