Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Systemd journald: логи и ротация

Журнал systemd: journalctl, настройка journald и ротация логов

Практика работы с journald: journalctl-фильтры по юнитам и времени, лимиты диска в journald.conf, persistent-журнал, связка с rsyslog и пересылка логов.

Прямой ответ

На systemd-сервере все логи сервисов по умолчанию уходят в journald — структурированное бинарное хранилище, читаемое через journalctl; четыре команды покрывают 95% повседневности: journalctl -u app -f (live-хвост конкретного сервиса), journalctl -u app --since "1 hour ago" (окно времени), journalctl -p err -b (ошибки текущей загрузки), journalctl --disk-usage (сколько съедает журнал). Три настройки, которые стоит сделать осознанно: persistent-хранение (Storage=persistent в /etc/systemd/journald.conf — в Debian по умолчанию auto: журнал живёт в /var/log/journal только если каталог создан, иначе теряется при ребуте — для сервера создать обязательно), лимиты диска (SystemMaxUse=2G, MaxRetentionSec=1month — иначе журнал молча съест десятки гигабайт или, наоборот, вытеснится за сутки на болтливом сервисе), и RateLimit (болтливое приложение в цикле ошибок забивает журнал и вытесняет полезные записи — лимиты по умолчанию 10k сообщений/30с на сервис, их стоит знать). Важное разделение: journald — про системные и сервисные логи; прикладная аналитика и структурированные логи приложения — своя забота (формат и ротация), а централизация парка — отдельный слой (Loki/EFK), journald — лишь источник на хосте.

Journalctl: фильтры, которые экономят время

Синтаксис фильтров комбинируется: -u app.service (юнит; несколько -u = объединение — «покажи app и nginx вместе»), -b/-b -1 (текущая/предыдущая загрузка — «что было перед ребут-падением» — ключ к посмертному анализу OOM/паник), --since/--until ("2026-10-21 14:00", "today", "-30min"), -p warning (приоритет syslog-шкалы: err/warning/info — «только ошибки и хуже»), -f (follow), _PID=, SYSLOG_IDENTIFIER= (поля журнала — journalctl -N выводит все имена полей, _SYSTEMD_UNIT/_UID фильтруют точнее, чем -u). Полезные режимы: -o json (машиночитаемый вывод — парсинг скриптами, экспорт), -o short-precise (точные таймстампы — разбор гонок), -o verbose (все поля записи — отладка самого логирования), --no-pager -n 100 (в скриптах). Паттерны практики: «сервис упал в 14:33» — journalctl -u app --since "14:30" --until "14:40" (весь контекст вокруг, не только хвост); «что ядро сказало» — journalctl -k (kernel ring — OOM/диски/сеть); «последствия ребута» — journalctl -b -1 -e (хвост прошлой загрузки). Для cron-задач и таймеров — тот же журнал (таймеры: вывод задачи виден в journalctl -u).

Настройка journald.conf: диск, retention, rate limit

Ключи /etc/systemd/journald.conf (после правки — systemctl restart systemd-journald): Storage=persistent (+ mkdir -p /var/log/journal && systemd-tmpfiles --create --prefix /var/log/journal — каталог с правильными правами) — журнал переживает ребуты; SystemMaxUse=2G / SystemKeepFree=1G — потолок и резерв диска (по умолчанию journald берёт до 10% ФС — на большом диске это незаметные 50 ГБ); MaxRetentionSec=1month — возрастной предел (что наступит раньше — размер или срок); MaxFileSec=1week — ротация файлов внутри лимита; Compress=yes (дефолт — большие сообщения сжимаются); RateLimitIntervalSec=30s/RateLimitBurst=10000 — защита от флуда (превышение — записи дропаются с пометкой в журнале: «Suppressed N messages» — если видите такую строку, у сервиса проблема и часть логов потеряна — чинить источник флуда, не поднимать лимит в разы). Отдельный сценарий — ForwardToSyslog=: при использовании внешнего агрегатора через file-коллектор может понадобиться syslog-форвардинг (или наоборот, отключить его за ненадобностью — дублирование логов в двух хранилищах стоит диска).

Приложение и journald: что писать, чего не писать

Сервис под systemd пишет в stdout/stderr — journald подхватывает и структурирует (приоритет — по syslog-конвенции префиксов или эвристике). Практика для Python-приложений: stdout — нормальный путь (12-factor: приложение не управляет файлами логов — ротация/лимиты — забота платформы в лице journald — подход); структурированный JSON в stdout — читается человеком через journalctl хуже, но парсится коллектором отлично (выбор «человек vs машина» решается -o json и агрегатором); уровни через префиксы (<4> — err по syslog-шкале в начале строки) — тогда -p err фильтрует осмысленно, иначе всё пишется info-уровнем и фильтр бесполезен; не логировать секреты (журнал читают все с группой systemd-journal — токены в логе = утечка с локальным доступом). Что не стоит отдавать journald: высокочастотную телеметрию (метрики — в Prometheus, не в журнал — метрики), аудит-потоки с требованиями неизменяемости (отдельное защищённое хранилище), и мегабайтные дампы (RateLimit съест, полезное вытеснится).

Практический сценарий: «ночью что-то упало»

Утро: алерт — сервис недоступен с 03:40. Разбор через журнал: (1) journalctl -u app -b --since "03:30" --until "04:00" — в 03:41 всплеск ошибок БД, затем systemd: Main process exited, code=killed — сервис убит; (2) journalctl -k --since "03:35" — kernel: Out of memory: Killed process ... (python) — OOM-подтверждение: ночной отчёт съел память; (3) journalctl -u app -b -1 | tail — хвост до прошлой перезагрузки (если сервер ребутался — без persistent-журнала этой истории бы не было: пункт 0 профилактики); (4) виновник — cron-задача отчёта в 03:40 — перенести на лимитированный воркер с MemoryMax (юниты); (5) профилактика журнала: Storage=persistent проверен, SystemMaxUse=2G выставлен (до этого журнал жил 10 ГБ и вытеснял историю за 3 дня — на разборе не хватало контекста недельной давности), алерт на «Suppressed messages» в логах. Разбор занял 10 минут благодаря точным окнам и фильтрам; «grep по /var/log всему» — это полчаса и пропущенная kernel-строка.

FAQ

Чем journald отличается от rsyslog и нужен ли rsyslog? journald — сбор и структурированное бинарное хранение (быстрые фильтры по полям); rsyslog — классическая пересылка/запись в текстовые файлы. Связка нужна при требованиях «логи в плоских файлах» (легаси-тулинга) или пересылке на внешний сервер по syslog-протоколу; для чистого systemd-стека journald самодостаточен, а агрегация — за promtail/вектор-агентами.

Журнал растёт и не ротируется — что проверить? journalctl --disk-usage (фактический размер), SystemMaxUse (задан ли — без него до 10% ФС), journalctl --vacuum-size=1G (ручная немедленная чистка), и источник флуда (journalctl --since today | awk '{print $5}' | sort | uniq -c — кто пишет больше всех; лечить болтуна, не только лимиты).

Как читать журнал другого пользователя/сервиса без рута? Группа systemd-journal даёт чтение всего журнала (usermod -aG systemd-journal user); по умолчанию обычный пользователь видит только свои сессии — это фича (логи сервисов могут содержать чувствительное).

Куда journald пишет физически и можно ли бэкапить? /var/log/journal/<machine-id>/*.journal (persistent) или /run/log/journal (volatile — живёт до ребута); файлы бинарные — бэкап копированием возможен (читать на другой машине — с учётом machine-id), но типично журнал не бэкапят, а пересылают важное во внешний агрегатор.

Источники: man journald.conf, journalctl, systemd-journal-remote — ссылки в шапке.