Введение / Зачем это нужно
journalctl — это основная утилита для просмотра и анализа журналов, собираемых systemd-journald. Она заменяет собой множественные текстовые файлы логов (/var/log/syslog, /var/log/messages, dmesg), предоставляя единый, структурированный, индексированный источник информации обо всех процессах в системе.
С помощью этого гайда вы научитесь:
- Быстро находить логи конкретной службы или процесса.
- Фильтровать записи по времени, уровню серьезности (ошибка/предупреждение/инфо) и другим полям.
- Отслеживать события в реальном времени.
- Сохранять и экспортировать логи для дальнейшего анализа.
Это незаменимый навык для любого сисадмина, devops-инженера или разработчика, отлаживающего приложение на Linux.
Требования / Подготовка
- Операционная система: Любой современный дистрибутив Linux, использующий
systemd(подавляющее большинство). - Права доступа: Для просмотра логов всех пользователей и служб обычно требуются права root (или членство в группе
systemd-journal). Команды, требующие повышенных привилегий, в этом гайде помеченыsudo. - Понимание структуры лога: Каждая запись в журнале имеет множество полей (
_SYSTEMD_UNIT,_PID,_COMM,PRIORITY,__REALTIME_TIMESTAMPи др.). Мы будем использовать их для фильтрации.
Шаг 1: Базовый просмотр и навигация
Простой вызов journalctl без аргументов отобразит весь доступный журнал, начиная с самой старой записи. Это может быть очень много данных.
Лучшие практики для начала:
# Показать последние 50 строк (аналог tail -n 50)
journalctl -n 50
# Показать последние 50 строк и следить за новыми (аналог tail -f)
journalctl -f -n 50
# Показать логи с самого начала (по умолчанию)
journalctl --no-pager
💡 Совет: Используйте флаг
--no-pager, если хотите, чтобы вывод сразу попал в конвейер (pipe) или файл, без постраничного просмотра черезless.
Шаг 2: Фильтрация по службе (UNIT)
Самый частый сценарий — посмотреть логи конкретного демона или службы.
# Логи службы Nginx (имя службы берется из systemd unit-файла)
journalctl -u nginx.service
# Логи службы Docker
journalctl -u docker.service -f
# Логи нескольких служб одновременно
journalctl -u ssh.service -u cron.service
⚠️ Важно: Имя службы должно быть точным. Узнать список всех активных юнитов можно командой
systemctl list-units --type=service.
Шаг 3: Фильтрация по уровню серьезности (PRIORITY)
Каждая запись имеет приоритет от 0 (emerg) до 7 (debug). Для отладки чаще всего нужны ошибки и предупреждения.
# Только ошибки (err) и критичные (crit, emerg)
journalctl -p err
# Только предупреждения и ошибки
journalctl -p warning
# Все, кроме отладочных сообщений (info и выше)
journalctl -p info
# Комбинация уровней: err, warn, notice
journalctl -p err -p warn -p notice
Шкала приоритетов (от самого серьезного):
0. emerg (система неработоспособна)
alert(требуется немедленное действие)crit(критическая ошибка)err(ошибка)warning(предупреждение)notice(уведомление, нормальное, но значимое событие)info(информационное сообщение)debug(отладочное сообщение)
Шаг 4: Фильтрация по времени
Точное указание временного интервала — ключ к быстрому поиску.
# Логи за последние 10 минут
journalctl --since "10 minutes ago"
# Логи за сегодня (с 00:00)
journalctl --since "today"
# Логи за конкретную дату
journalctl --since "2026-02-15" --until "2026-02-16"
# Логи с точностью до секунды (формат: "YYYY-MM-DD HH:MM:SS")
journalctl --since "2026-02-15 14:30:00" --until "2026-02-15 15:00:00"
# Логи за последний час (сравнение с `-p err`)
journalctl --since "1 hour ago" -p err
💡 Совет: Формат времени понимается довольно свободно. Можно писать
"5 min ago","yesterday","2026-02-15".
Шаг 5: Комбинирование фильтров и поиск по полям
Сила journalctl — в комбинировании фильтров и поиске по структурированным полям (префикс _). Это гораздо точнее, чем grep.
# Логи службы nginx с уровнем ошибка за последние 30 минут
journalctl -u nginx.service -p err --since "30 minutes ago"
# Логи конкретного процесса по PID
journalctl _PID=1234
# Логи конкретного исполняемого файла
journalctl _COMM=/usr/bin/ssh
# Логи от определенного пользователя (UID)
journalctl _UID=1000
# Логи, связанные с конкретным сеансом (session)
journalctl _SESSION=2
Популярные поля для фильтрации:
_SYSTEMD_UNIT— аналог-u._PID— ID процесса._UID— ID пользователя._GID— ID группы._COMM— команда (имя исполняемого файла)._EXE— полный путь к исполняемому файлу.SYSLOG_IDENTIFIER— идентификатор, часто совпадает с именем программы.
Поиск по тексту (если фильтры по полям не помогают)
Используйте стандартный grep для поиска по свободному тексту сообщения (MESSAGE).
# Поиск всех упоминаний 'Connection refused' (без учета регистра)
journalctl | grep -i "connection refused"
# Поиск с контекстом (2 строки до и после)
journalctl | grep -C 2 "timeout"
# Поиск и подсчет количества совпадений
journalctl | grep -c "Failed password"
Шаг 6: Управление выводом и экспорт
Изменение формата вывода
По умолчанию выводится много метаданных. Можно изменить формат.
# Краткий формат: только время и сообщение
journalctl -o short
# Подробный формат (с полями)
journalctl -o verbose
# JSON (удобно для скриптов и парсинга)
journalctl -u nginx.service -o json --since "1 hour ago" > nginx_logs.json
# JSON-pretty (читаемый JSON)
journalctl -o json-pretty
# Показать только поле сообщения (очень кратко)
journalctl -o cat
Ограничение размера вывода
# Показать последние N записей (самый частый вариант)
journalctl -n 100
# Ограничить вывод по времени (например, за последние 2 часа)
journalctl --since "2 hours ago"
Сохранение логов в файл
# Сохранить логи службы ssh за последний день в файл
journalctl -u ssh.service --since "yesterday" > ssh_logs.txt
# Сохранить в JSON для последующего анализа скриптом
journalctl -p err --since "2026-02-01" -o json > errors_feb.json
Шаг 7: Управление самим журналом (вакуумация, ротация)
Журнал systemd по умолчанию может занимать много места (до 10% диска). Управление:
# Показать текущую статистику по журналу (размер, количество записей)
journalctl --disk-usage
# Очистить (удалить) все старые записи, оставив только последние N мегабайт
sudo journalctl --vacuum-size=500M
# Очистить записи старше указанного времени
sudo journalctl --vacuum-time=3d # старше 3 дней
sudo journalctl --vacuum-time=1w # старше 1 недели
# Принудительно ротировать журнал (создать новый файл)
sudo journalctl --rotate
# Комбинация: ротация + очистка записей старше 1 дня
sudo journalctl --rotate && sudo journalctl --vacuum-time=1d
⚠️ Важно: Очистка (
--vacuum) работает только с файлами в/var/log/journal. Если журнал хранится только в памяти (/run/log/journal), он будет очищен при перезагрузке.
Проверка результата
- Базовый тест: Выполните
journalctl -n 5 -f. Вы должны увидеть последние 5 строк лога и новые записи при их появлении (например, при запуске службы). - Фильтрация: Выполните
journalctl -u ssh.service -p info. В выводе должны быть только записи уровняinfoи выше от службы SSH. - Экспорт: Выполните
journalctl --since "1 hour ago" -o json > test.json. Файлtest.jsonдолжен содержать валидный JSON-массив объектов-записей. - Управление: Выполните
sudo journalctl --disk-usageдля проверки текущего размера. Послеsudo journalctl --vacuum-size=100Mразмер должен уменьшиться.
Если все перечисленные команды выполняются без ошибок и вывод соответствует ожиданиям — вы успешно освоили основы работы с journalctl.
Возможные проблемы
1. "Failed to open directory /var/log/journal: Permission denied"
Причина: У текущего пользователя нет прав на чтение системных логов.
Решение: Используйте sudo перед командой или добавьте пользователя в группу systemd-journal: sudo usermod -aG systemd-journal $USER (требуется перелогин).
2. Нет логов для нужной службы (journalctl -u ... пустой)
Причина а: Служба не использовала stdout/stderr для логирования (использует отдельный файл).
Решение: Проверьте конфигурацию службы (/etc/systemd/system/<имя>.service), опция StandardOutput. Возможно, логи идут в отдельный файл, а не в journald.
Причина б: Служба не запускалась в рассматриваемом периоде.
Решение: Убедитесь, что служба активна (systemctl status <имя>). Проверьте временной интервал (--since).
3. "No journal files were found."
Причина: systemd-journald настроен на хранение логов только в памяти (/run/log/journal), и вы перезагрузили систему.
Решение: Для постоянного хранения создайте директорию: sudo mkdir -p /var/log/journal && sudo systemd-tmpfiles --create --prefix /var/log/journal. Логи начнут сохраняться после перезапуска службы systemd-journald или перезагрузки.
4. Слишком много данных, поиск работает медленно
Решение: Всегда сужайте временной интервал (--since) и уровень приоритета (-p). Используйте фильтрацию по полям (_PID, _SYSTEMD_UNIT) вместо grep, так как поиск по индексированным полям происходит в разы быстрее.
5. Нужно мониторить логи, но journalctl -f не показывает новые записи
Причина: Вы запустили journalctl с очень старым --since или без -f, и вывод "завис" в начале.
Решение: Нажмите Ctrl+C и запустите заново с -f и, возможно, с -n 0 (не показывать старые записи): journalctl -u service.name -f -n 0.
Продвинутые сценарии и примеры
Поиск последних перезагрузок и их причин
# Найти все записи о перезагрузке (сообщение от systemd)
journalctl -b -1 -u systemd-logind.service | grep -i "system reboot" -A5 -B5
-b -1 — логи предыдущей загрузки (boot). Это помогает найти, что происходило перед падением системы.
Анализ причин падения службы (Failed)
# Найти все неудачные запуски служб
journalctl -p err | grep -i "failed"
# Или точнее, по полю результата юнита
journalctl _SYSTEMD_UNIT=nginx.service _SYSTEMD_INVOCATION_ID=$(systemctl show nginx.service -p InvocationID --value)
Сравнение логов двух загрузок (boot)
# Сравнить разницу в логах между текущей и предыдущей загрузкой
journalctl -b -0 > current_boot.log
journalctl -b -1 > previous_boot.log
diff -u previous_boot.log current_boot.log | less
Мониторинг в реальном времени с цветовой подсветкой
journalctl не поддерживает цвета из коробки, но можно обернуть в grep --color:
journalctl -f | grep --color -E "error|failed|exception|WARNING"
Использование в скриптах (без постраничного просмотра)
Всегда используйте --no-pager в скриптах, чтобы команда не ждала нажатия клавиши.
#!/bin/bash
# Проверить, были ли ошибки nginx за последние 15 минут
if journalctl -u nginx.service --since "15 minutes ago" -p err --no-pager | grep -q .; then
echo "Обнаружены ошибки в nginx!"
# Можно отправить уведомление или перезапустить службу
systemctl restart nginx
fi