Логи и диагностика проблем в Linux
Как читать journald и текстовые логи, фильтровать сообщения, следить за событиями в реальном времени и системно искать причины сбоев Linux.
Содержание статьи
- Зачем нужны логи
- Где искать сообщения
- journalctl и фильтрация
- Поиск в текстовых логах
- Просмотр в реальном времени
- Диагностика сервиса
- Логи ядра и аутентификации
- Ротация и размер логов
- Проверка связанных ресурсов
- Частые ошибки
- Читать только последние строки
- Путать старый и новый запуск
- Сразу применять `kill -9`
- Менять конфигурацию до фиксации симптомов
- Практическая задача
- Шпаргалка
- Итог
Зачем нужны логи
Логи — записи о событиях системы и приложений: запуске сервисов, ошибках, подключениях и отказах в доступе. При проблеме они помогают понять, что произошло, когда это началось и какой компонент сообщил об ошибке.
Диагностику лучше начинать с фиксации симптома и чтения журнала, а не с бесконечных перезапусков. Иначе важные сообщения смешаются с новым запуском.
Где искать сообщения
В системах с systemd основной источник — journald:
sudo journalctl
sudo journalctl -b
sudo journalctl -n 100 --no-pager
Традиционные текстовые логи обычно находятся в /var/log:
ls -lah /var/log
Частые файлы — /var/log/syslog или /var/log/messages, /var/log/auth.log или /var/log/secure, а также журналы конкретных приложений. Набор зависит от дистрибутива.
journalctl и фильтрация
Сообщения сервиса:
sudo journalctl -u nginx.service -b -n 100 --no-pager
sudo journalctl -u nginx.service -f
Журнал за период:
sudo journalctl --since '30 minutes ago'
sudo journalctl --since '2026-08-23 17:00' --until '2026-08-23 18:00'
Предыдущая загрузка:
sudo journalctl -b -1
Только ошибки:
sudo journalctl -p err..alert -b --no-pager
Сообщения ядра:
sudo journalctl -k -b -p warning..alert
Фильтровать можно по PID, пользователю и процессу:
sudo journalctl _PID=1234
sudo journalctl _UID=1000
sudo journalctl _COMM=sshd -b
Формат ISO удобен при сравнении времени:
sudo journalctl -u nginx -o short-iso --no-pager
Слово error не всегда означает остановку сервиса, а его отсутствие не гарантирует исправность. Смотрите время, PID и соседние сообщения.
Поиск в текстовых логах
Для обычных файлов используйте grep:
grep -nEi 'error|failed|timeout' /var/log/app.log
grep -Rni --include='*.log' 'connection refused' /var/log/app/
Последние совпадения и контекст:
grep -iE 'error|failed|panic' /var/log/app.log | tail -n 50
grep -n -B 2 -A 2 'ERROR' /var/log/app.log
Если временно скрываете отказы в доступе:
grep -Rni 'failed' /var/log 2>/dev/null
2>/dev/null только убирает сообщения об ошибках из вывода — он не исправляет проблему и может скрыть важную информацию.
Просмотр в реальном времени
Для текстового файла:
tail -F /var/log/app.log
-F лучше переживает ротацию файла. Для systemd:
sudo journalctl -u app.service -f
В отдельном терминале воспроизведите проблему и сопоставьте время действия с новыми строками. Это надёжнее, чем читать старый журнал без временного диапазона.
Диагностика сервиса
Базовая последовательность:
sudo systemctl status app.service --no-pager
sudo journalctl -u app.service -b -n 100 --no-pager
systemctl is-active app.service
Затем проверьте процесс и порт:
ps aux | grep '[a]pp'
sudo ss -ltnp
Частые причины сбоя:
- ошибка конфигурации;
- занятый порт;
- отсутствующий файл или каталог;
- неверный пользователь или права;
- недоступная база данных;
- неправильный путь в
ExecStart; - незаданная переменная окружения.
Проверку конфигурации выполняйте штатной командой приложения. После исправления перезапустите сервис и снова проверьте статус и журнал:
sudo systemctl restart app.service
sudo systemctl status app.service --no-pager
Если unit попал в failed state:
sudo systemctl reset-failed app.service
Эта команда только очищает зафиксированное состояние и не исправляет причину.
Логи ядра и аутентификации
dmesg -T | tail -n 50
sudo journalctl -k -b | grep -iE 'error|fail|warn|reset|timeout'
Доступ к dmesg может быть ограничен. Для SSH и sudo используйте источник конкретного дистрибутива:
sudo grep -iE 'failed|invalid|sudo' /var/log/auth.log
sudo journalctl _COMM=sshd -b
Не удаляйте журнал во время расследования. Сначала сохраните временной диапазон и исходные строки.
Ротация и размер логов
Проверить размер файлов:
sudo du -sh /var/log/* 2>/dev/null | sort -h
sudo journalctl --disk-usage
Традиционные логи часто обслуживает logrotate. Безопасная проверка без изменений:
sudo logrotate -d /etc/logrotate.conf
Принудительный запуск logrotate -f используйте только после проверки политики. Для journald временное ограничение возможно так:
sudo journalctl --vacuum-time=14d
Перед очисткой убедитесь, что требования к хранению и расследованию это позволяют.
Проверка связанных ресурсов
Если в логе недостаточно информации, проверьте окружение:
df -h
df -i
namei -l /path/to/file
df -h показывает место, а df -i — inode. Система может перестать создавать файлы при исчерпании inode даже при наличии свободных гигабайтов. namei -l показывает права всех каталогов в пути.
Для сетевой проблемы дополнительно проверьте порт через ss, HTTP через curl и процесс через ps.
Частые ошибки
Читать только последние строки
Причина может находиться раньше сообщения о завершении. Ограничивайте журнал по времени и увеличивайте число строк.
Путать старый и новый запуск
Используйте -b, PID и точное время события.
Сразу применять kill -9
Сначала изучите журнал и используйте штатное управление сервисом. Принудительная остановка может прервать запись данных.
Менять конфигурацию до фиксации симптомов
Сначала сохраните исходный журнал и копию конфигурации, затем внесите одно изменение и проверьте результат.
Практическая задача
Создайте учебный лог:
mkdir -p ~/logs-lab
printf 'INFO started\nWARN slow request\nERROR database timeout\nINFO retry\n' > ~/logs-lab/app.log
Найдите проблемы:
grep -nEi 'error|warn' ~/logs-lab/app.log
tail -F ~/logs-lab/app.log
В другом терминале добавьте событие:
printf '%s ERROR permission denied\n' "$(date -Is)" >> ~/logs-lab/app.log
Затем посчитайте уровни:
grep -oE 'INFO|WARN|ERROR' ~/logs-lab/app.log | sort | uniq -c | sort -nr
Остановите tail через Ctrl-c. Для системного сервиса применяйте ту же схему: зафиксировать время, открыть журнал, воспроизвести действие, найти новую запись и проверить результат.
Шпаргалка
| Задача | Команда |
|---|---|
| Журнал текущей загрузки | journalctl -b |
| Журнал сервиса | journalctl -u service |
| Последние строки | journalctl -u service -n 100 |
| Следить за журналом | journalctl -u service -f |
| Только ошибки | journalctl -p err..alert |
| Сообщения ядра | journalctl -k -b |
| Журнал за период | journalctl --since ... --until ... |
| Размер journald | journalctl --disk-usage |
| Искать в файле | `grep -nEi 'error |
| Следить за файлом | tail -F file |
| Размер логов | du -sh /var/log/* |
| Место на диске | df -h |
| Свободные inode | df -i |
| Права пути | namei -l /path |
| Проверить logrotate | logrotate -d /etc/logrotate.conf |
Итог
Логи полезны в контексте: учитывайте время, unit, PID, загрузку системы и последующие события. Для systemd начинайте с systemctl status и journalctl -u, для обычных файлов — с grep, tail -F и проверки ротации.
Безопасный порядок такой: зафиксировать симптом, определить временной диапазон, собрать журнал, проверить связанные ресурсы, внести одно изменение и снова проверить результат.
Следующая статья — «Сетевые команды Linux: ip, ss, curl и диагностика соединений».