Логирование в systemd: работа с journalctl¶
В современных Linux-дистрибутивах (Ubuntu ≥ 16.04, Debian ≥ 8, RHEL/CentOS ≥ 7, Alma/Rocky ≥ 8) systemd не только управляет службами — он также обеспечивает централизованное логирование через journald и утилиту journalctl.
Журнал systemd собирает:
- сообщения ядра (
dmesg), - логи служб (
nginx,sshd,dockerи др.), - стандартные потоки
stdout/stderrот демонов, - аудит-события (если интегрировано с
auditd).
Примечание
journald может работать параллельно с syslog (например, rsyslog или syslog-ng) — тогда логи дублируются. Но часто journald полностью заменяет классический syslog.
Быстрый старт: основные команды¶
| Задача | Команда |
|---|---|
| Посмотреть все логи (с пейджером) | journalctl |
| Последние 10 записей | journalctl -n |
| Хвост логов в реальном времени | journalctl -f (аналог tail -f) |
| Логи с момента последней загрузки | journalctl -b |
| Логи конкретной службы | journalctl -u nginx |
| Логи ядра | journalctl -k |
| Объём диска, занятый журналом | journalctl --disk-usage |
Время и часовые пояса¶
По умолчанию journalctl отображает локальное время. Убедитесь, что оно настроено корректно:
Управление часовым поясом¶
# Список всех часовых поясов
timedatectl list-timezones
# Установка (например, для Москвы)
sudo timedatectl set-timezone Europe/Moscow
Просмотр логов в UTC¶
История загрузок¶
По умолчанию журналы предыдущих загрузок не сохраняются (хранятся только в /run/log/journal/, который очищается при перезагрузке). Чтобы сохранять их — включите persistent storage:
sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
Или вручную отредактируйте конфиг:
Раскомментируйте и измените:Работа с загрузками¶
# Список всех сохранённых загрузок
journalctl --list-boots
# Вывод:
# -2 abc123... Wed 2025-11-05 10:00:00 MSK—Wed 12:30:45 MSK
# -1 def456... Thu 2025-11-06 09:15:22 MSK—Thu 18:44:10 MSK
# 0 xyz789... Fri 2025-11-07 08:20:05 MSK—running
# Логи предыдущей загрузки
journalctl -b -1
# Логи по ID загрузки
journalctl -b xyz789...
Фильтрация логов¶
По времени¶
# С указанного момента до сейчас
journalctl --since "2025-11-07 14:00:00"
# За период
journalctl --since "2025-11-06" --until "2025-11-07 09:00:00"
# Удобные ключевые слова
journalctl --since today
journalctl --since yesterday
journalctl --since "2 hours ago"
journalctl --until now
Примечание
Поддерживаемые форматы: YYYY-MM-DD, YYYY-MM-DD HH:MM:SS, today, yesterday, 1 hour ago, 5min ago.
По службе (юниту)¶
# Логи nginx
journalctl -u nginx
# С расширением .service (необязательно, но корректно)
journalctl -u nginx.service
# Несколько служб сразу
journalctl -u nginx -u php-fpm --since today
# Только ошибки nginx за последние 2 часа
journalctl -u nginx -p err --since "2 hours ago"
По процессу, пользователю, группе¶
# По PID (например, PID nginx master-процесса)
journalctl _PID=12345
# По UID пользователя
journalctl _UID=33 # например, www-data
journalctl _UID=$(id -u nginx)
# Список всех UID, о которых есть записи
journalctl -F _UID
# Аналогично для GID
journalctl -F _GID
По уровню приоритета (severity)¶
| Уровень | Код | Описание |
|---|---|---|
emerg | 0 | Система неработоспособна |
alert | 1 | Требуется немедленное вмешательство |
crit | 2 | Критические ошибки |
err | 3 | Ошибки |
warning | 4 | Предупреждения |
notice | 5 | Значимые события |
info | 6 | Информационные сообщения |
debug | 7 | Отладка |
Примеры:
# Только ошибки и выше (err, crit, alert, emerg)
journalctl -p err
# То же самое через цифру
journalctl -p 3
# Ошибки nginx за текущую загрузку
journalctl -u nginx -p err -b
Форматирование вывода¶
Основные опции¶
--no-pager # вывод в stdout (для grep, tee, перенаправления)
--no-full # не обрезать длинные строки (по умолчанию — обрезаны)
-n 50 # последние 50 записей
-f # follow (live-просмотр новых записей)
Форматы (-o)¶
| Формат | Использование |
|---|---|
short (по умолчанию) | Классический syslog-стиль |
short-iso | С временем в ISO 8601: 2025-11-07T15:30:45+03:00 |
short-precise | Время с микросекундами |
cat | Только текст сообщения (без метаданных) — удобно для скриптов |
json | JSON, одна запись на строку (machine-readable) |
json-pretty | Человекочитаемый JSON (для отладки/анализа) |
verbose | Все поля, включая скрытые (_SOURCE_REALTIME_TIMESTAMP, _BOOT_ID и др.) |
Примеры:
# Читаемый JSON для nginx
journalctl -u nginx -o json-pretty --since today
# Только текст ошибок
journalctl -u nginx -p err -o cat
# Экспорт в файл для анализа
journalctl -b -u docker --no-pager > docker_boot.log
Управление размером журнала¶
Текущий объём¶
Очистка логов¶
По объёму¶
# Оставить не более 500 МБ
sudo journalctl --vacuum-size=500M
# Оставить не более 1 ГБ
sudo journalctl --vacuum-size=1G
По времени¶
# Удалить всё старше 3 дней
sudo journalctl --vacuum-time=3d
# Оставить только за последнюю неделю
sudo journalctl --vacuum-time=7days
# За последний месяц
sudo journalctl --vacuum-time=1month
Примечание
Поддерживаемые суффиксы: s, m, h, days, weeks, months, years.
Постоянные ограничения (в конфиге)¶
Отредактируйте /etc/systemd/journald.conf:
[Journal]
# Хранить на диске (в /var/log/journal/)
Storage=persistent
# Макс. общий объём
SystemMaxUse=1G
# Оставлять свободными минимум
SystemKeepFree=500M
# Макс. размер одного файла
SystemMaxFileSize=100M
# Для временных логов в /run (при Storage=volatile)
# RuntimeMaxUse=100M
После изменений:
Примечание
Изменения в journald.conf не влияют на уже накопленные логи — используйте --vacuum-* для очистки.
Продвинутые приёмы¶
Поиск по содержимому (в связке с grep)¶
Анализ частоты событий¶
# Сколько раз nginx выдавал 5xx за сегодня
journalctl -u nginx --since today -o cat | grep -c " 5[0-9][0-9] "
Экспорт и резервное копирование¶
# Сохранить в бинарном формате (можно восстановить!)
journalctl -b --output=export > boot_log_$(date +%F).journal
# Восстановить позже:
journalctl --file=boot_log_2025-11-07.journal
Частые вопросы¶
Q: Почему journalctl не показывает логи прошлых перезагрузок?
A: Проверьте, включено ли Storage=persistent и существует ли /var/log/journal/. Без этого логи хранятся только в оперативной памяти (/run).
Q: Как отключить journald и вернуться к rsyslog?
A: Нельзя полностью «отключить» journald (он часть systemd), но можно: - перенаправлять логи в rsyslog через /etc/rsyslog.d/ + imjournal, - или отключить journald как источник для rsyslog, оставив только его.
Q: Можно ли шифровать логи?
A: journald не поддерживает шифрование «из коробки». Для этого используйте: - logrotate + gpg, - или сторонние SIEM-системы (Graylog, ELK, Loki + Promtail).