Введение / Зачем это нужно
Systemd-journald — централизованная система сбора логов в современных дистрибутивах Linux. Она заменяет классический syslog и хранит записи в бинарном формате, что обеспечивает структурированный поиск и индексирование. Однако без управления журналы могут занимать гигабайты дискового пространства, замедлять систему и затруднять анализ. Этот гайд покажет, как контролировать рост логов, быстро находить нужные события и настроить автоматическую ротацию.
Требования / Подготовка
Перед началом убедитесь, что:
- У вас есть права sudo или доступ к root-пользователю.
- На системе используется systemd (проверьте:
systemctl --version). - Журнал хранится в постоянном режиме (файлы в
/var/log/journal/). Если папки нет, создайте:sudo mkdir -p /var/log/journal && sudo systemctl restart systemd-journald. - Установлена утилита
journalctl(обычно входит в пакетsystemd).
Шаг 1: Просмотр логов и базовый поиск
Журнал systemd-journald хранит все системные события, включая вывод сервисов, ядра и init-системы. Для просмотра используйте:
# Вывод всех записей с последними в конце (по умолчанию)
journalctl
# Просмотр с пагинацией (клавиши ↑/↓, q для выхода)
journalctl | less
# Отображение в реальном времени (аналог tail -f)
journalctl -f
# Показать только сообщения ядра
journalctl -k
Примечание: Для выхода из less нажмите q. Чтобы прервать -f — Ctrl+C.
Шаг 2: Фильтрация по времени, сервису и приоритету
Самые полезные фильтры:
# Логи за сегодня
journalctl --since today
# За определённый период (формат: "YYYY-MM-DD HH:MM:SS")
journalctl --since "2024-02-15 09:00:00" --until "2024-02-15 18:00:00"
# Только ошибки (приоритет err, crit, alert, emerg)
journalctl -p err
# Логи конкретного сервиса (например, nginx)
journalctl -u nginx.service
# Комбинированный фильтр: ошибки nginx за последние 2 часа
journalctl -u nginx.service -p err --since "2 hours ago"
Дополнительные опции:
-n 50— показать последние 50 записей.--no-pager— выводить без паузы (удобно для скриптов).-o jsonили-o json-pretty— вывод в JSON для парсинга.
Шаг 3: Очистка устаревших логов
Журнал может расти бесконтрольно. Очистка возможна по времени или размеру:
# Удалить записи старше 7 дней
sudo journalctl --vacuum-time=7d
# Оставить не более 200 МБ самых свежих записей
sudo journalctl --vacuum-size=200M
# Сохранить только логи за последние 24 часа
sudo journalctl --vacuum-time=1d
⚠️ Важно: Операция
--vacuum-*удаляет все записи, удовлетворяющие критерию, даже если они относятся к разным сервисам. Для выборочной очистки используйте фильтры +--vacuum-time, но будьте осторожны.
Если стандартная очистка не освобождает место (например, из-за "заблокированных" файлов), примените:
sudo systemctl stop systemd-journald
sudo rm -rf /var/log/journal/* # полная очистка
sudo systemctl start systemd-journald
Шаг 4: Настройка автоматической ротации
Редактируйте конфигурационный файл /etc/systemd/journald.conf:
# Включить постоянное хранение (если ещё не активно)
Storage=persistent
# Максимальный общий размер журнала (можно указать K, M, G)
SystemMaxUse=500M
# Максимальный размер одного файла журнала
SystemMaxFileSize=50M
# Автоматически удалять записи старше N дней
MaxRetentionSec=30d
# Сжимать старые записи (экономит место)
Compress=yes
# Разделять логи по сервисам (удобно для диагностики)
SplitMode=uid
Применение изменений:
sudo systemctl restart systemd-journald
sudo systemctl status systemd-journald # проверьте статус
Проверка текущих лимитов:
journalctl --disk-usage # текущий размер
journalctl --list-boots # список загрузок (по умолчанию хранятся)
Шаг 5: Расширенный поиск и анализ
Для глубокого анализа используйте комбинации фильтров и утилиты grep:
# Найти все упоминания "timeout" в логах сервиса cron
journalctl -u cron.service | grep -i timeout
# Подсчитать количество ошибок по сервисам за последний день
journalctl --since yesterday -p err --no-pager | \
grep -oP '(?<=^.*?service: ).*?(?=\.)' | \
sort | uniq -c | sort -nr
# Экспорт логов в текстовый файл (для отправки в поддержку)
journalctl --since "1 hour ago" --no-pager > /tmp/journal_snapshot.txt
Совет: Для сложных запросов используйте поле __UID (идентификатор пользователя) или _PID (идентификатор процесса):
journalctl _PID=1234 # логи конкретного процесса
journalctl _UID=1000 # логи пользователя с UID 1000
Проверка результата
- Размер журнала — выполните
journalctl --disk-usage. Значение должно соответствоватьSystemMaxUse(если настроено) или быть в разумных пределах (< 1 ГБ для сервера). - Доступность логов — проверьте наличие файлов в
/var/log/journal/(еслиStorage=persistent). - Корректность ротации — после срабатывания лимитов старые файлы должны архивироваться (расширение
.journal~) или удаляться. - Поиск работает — выполните тестовый запрос, например
journalctl -u systemd-journald --since "1 hour ago".
Возможные проблемы
| Проблема | Решение |
|---|---|
journalctl --disk-usage показывает 0 B | Журнал отключён (Storage=none). Проверьте /etc/systemd/journald.conf. |
Нет логов в /var/log/journal/ | Папка не создана или права некорректны. Выполните: sudo mkdir -p /var/log/journal && sudo chown root:systemd-journal /var/log/journal && sudo chmod 2755 /var/log/journal |
| Очистка не удаляет старые записи | Убедитесь, что MaxRetentionSec не превышает время жизни записей. Используйте journalctl --list-boots для просмотра загрузок. |
| Ошибка "Failed to open directory" | Не хватает прав. Все операции очистки требуют sudo. |
| Журнал растёт слишком быстро | Проверьте, нет ли "болтливых" сервисов. Уменьшите SystemMaxFileSize или включите RateLimitIntervalSec/RateLimitBurst в конфиге. |
| Потеря логов после перезагрузки | Убедитесь, что Storage=persistent. Если Storage=volatile, логи хранятся только в RAM и теряются при выключении. |
Следующие шаги:
- Изучите мониторинг загрузки через
journalctl -b -1(логи предыдущей загрузки). - Настройте перенаправление логов в внешние системы (например, Elasticsearch) через
systemd-journal-remote. - Используйте
journalctl -o exportдля конвертации в стандартные форматы (CSV, XML).