journalctl disk usage — vacuum — черпак, SystemMaxUse — кран

journalctl disk usage — vacuum — черпак, SystemMaxUse — кран

journalctl disk usage с замерами: что считает --disk-usage, почему после --vacuum-size всё возвращается и какой один drop-in навсегда закрывает кран.

HUMANавтор @mrkeepalive1d8 мин чтения
журнал (ванна)/var/log/journalрастёт с каждой строкой лога48.2M → 56.2M замерено кран (открыт)без SystemMaxUse --vacuum-size (черпак)56.2M → 16M → снова 20.3M маховик вентиляSystemMaxUse=5M журнал с потолкомтот же поток → 1.2M, держится
Рис. 1 — vacuum один раз вычерпывает воду; кран продолжает лить. SystemMaxUse — это вентиль на трубе.

Что на самом деле измеряет journalctl --disk-usage?

Главное предложение: journalctl --disk-usage показывает размер файлов журнала на диске — и архивных, и активных, — которые живут в /var/log/journal на любой постоянной установке. Это чтение: команда ничего не удаляет и ничего не перезапускает. На стендовой VM, до добавления каких-либо логов:

$ sudo journalctl --disk-usage
Archived and active journals take up 48.2M in the file system.
$ ls /var/log/journal/
fd766b9ea5a540e68e6c43ea74f98a15   ← one directory per machine-id

проверка: стоковый Arch несёт /var/log/journal сразу — Storage=auto (закомментированный дефолт #Storage=persistent) означает persistent с первой загрузки. Запускай с sudo: без членства в adm/systemd-journal/wheel чтение обычного пользователя покрывает только его собственные файлы — стенд замерил 16M от пользователя и 48.2M от root в одну и ту же секунду.

Здесь людей подводят две вещи. Первая: число включает активный журнал — файл, в который journald пишет прямо сейчас, — так что даже свежая загрузка никогда не равна нулю. Вторая: если /var/log/journal не существует, journald волатилен: всё живёт в /run/log/journal (tmpfs), читается около нуля и умирает при перезагрузке. Это не «маленький журнал» — это отсутствие истории журнала вообще. sudo mkdir -p /var/log/journal && sudo systemctl restart systemd-journald переключает тебя на persistent.

Почему журнал всё растёт и растёт?

Потому что кран открыт — так задумано. Стоковый /etc/systemd/journald.conf несёт все ручки размера закомментированными:

$ grep -E '^#(Storage|Compress|SystemMaxUse)' /etc/systemd/journald.conf
#Storage=persistent
#Compress=yes
#SystemMaxUse=

проверка: скопировано со стендовой машины — SystemMaxUse есть в файле только как комментарий; journald читает его как незаданный и не держит никакого потолка.

Без потолка ничто не стареет и ничто не ограничивает: болтливый сервис или один шумный cron добавляют мегабайты в день — вечно. Стенд доказал наклон честным способом — устроить поток, форсировать ротацию и снова прочитать счётчик:

$ for i in $(seq 1 400); do logger -t benchflood "entry $i: …~1KB line…"; done
$ sudo journalctl -t benchflood --no-pager | wc -l     # all 400 landed
400
$ sudo journalctl --rotate                             # close the active file
$ sudo journalctl --disk-usage
Archived and active journals take up 56.2M in the file system.

проверка: 48.2M → 56.2M от одного небольшого потока. В этом спрятаны две квитанции: рост становится виден только на ротации — journald преаллоцирует активный файл чанками по 8M, так что потоки внутри файла не двигают счётчик, пока файл не закроется, — и du -sh /var/log/journal (57M) сходится с числом самого journald в пределах округления.

Поток был 400 строк по килобайту — погрешность округления на фоне дневного шума настоящей машины. Размер не главное; главное — направление: без потолка единственное устойчивое состояние — «больше», шагами по 8M, которые ты не выбирал.

Удаляет ли journalctl --vacuum-size это насовсем?

Нет — и признание напечатано в собственном выводе команды. Vacuum — ведро для вычерпывания: один зачерпок, мгновенное облегчение, конструктивно ничего:

$ sudo journalctl --vacuum-size=1M
Deleted archived journal …/system@…-adf16c8ac48706f4.journal~ (8M).
Deleted archived journal …/system@d1d286….journal (8.2M).
Deleted archived journal …/user-1000@…journal~ (8M).
Deleted archived journal …/system@…c3f9281226bbfdc4.journal~ (8M).
Deleted archived journal …/system@…5244-….journal (4.4M).
Deleted archived journal …/user-1000@…57b6-….journal (3.4M).
Deleted archived journal …/system@…59c8-….journal (976K).
Deleted archived journal …/user-1000@…59cb-….journal (296K).
Vacuuming done, freed 41.4M of archived journals from /var/log/journal/fd766b9e….
$ sudo journalctl --disk-usage
Archived and active journals take up 16M in the file system.

проверка: список удалений и «Vacuuming done, freed 41.4M» — это собственный stdout --vacuum-size, вставлен как есть — 56.2M упал до 16M.

Всмотрись в пол, потому что именно его cron-задачи никогда не замечают: 16M остались. Это два активных файла журнала — system.journal и user-1000.journal, преаллоцированные по 8M каждый, — а --vacuum-size удаляет только архивные файлы. Vacuum не может срезаться ниже того, в что journald пишет прямо сейчас, каким бы маленьким ни было переданное число.

Затем тест на долив — часть, которую никто не запускает. Тот же поток снова, ротация, чтение:

$ sudo journalctl --disk-usage
Archived and active journals take up 20.3M in the file system.
$ sudo du -sh /var/log/journal
21M	/var/log/journal

проверка: 16M → 20.3M от идентичного потока в 400 строк — vacuum удалил историю; о завтрашнем дне он не изменил ничего.

Вот почему vacuum-cron — народное средство, которое так и не работает как надо: он борется с краном ведром, по расписанию, вечно. Если cron еженедельно запускает --vacuum-size=100M, а журнал достигает 1G посреди недели, читатели платят за 1G всю неделю. И каждый проход — тихое событие потери данных: освобождаются самые старые строки, ровно та история, за которой ты тянешься во время инцидента.

Как ограничить размер журнала навсегда?

Один drop-in, один рестарт — и дальше journald сам держит потолок, на каждой ротации, вечно:

$ sudo mkdir -p /etc/systemd/journald.conf.d
$ sudo tee /etc/systemd/journald.conf.d/size.conf >/dev/null <<'EOF'
[Journal]
SystemMaxUse=5M
EOF
$ sudo systemctl restart systemd-journald
$ sudo systemd-analyze cat-config systemd/journald.conf | grep SystemMaxUse
SystemMaxUse=5M

проверка: systemd-analyze cat-config печатает ОБЪЕДИНЁННЫЙ конфиг — SystemMaxUse=5M из drop-in живой, а не просто записан в файл, который никто не читает.

Теперь тот же идентичный поток, который поднял вычерпанный журнал до 20.3M:

$ for i in $(seq 1 400); do logger -t benchflood "entry $i: …"; done
$ sudo journalctl --rotate
$ sudo journalctl --disk-usage
Archived and active journals take up 1.2M in the file system.
$ sudo ls -lh /var/log/journal/*/ | awk '{print $5, $9}'
640K system.journal
640K user-1000.journal
$ sudo journalctl -t benchflood --no-pager | wc -l
0

проверка: тот же поток, который поднял журнал без потолка до 20.3M, оставил журнал с потолком на 1.2M — journald ротировал, применил потолок и удалил поток начисто: 400 записей вошло, 0 удержано, без cron, без надзора.

Заметь, что потолок сделал то, чего не мог vacuum: он спустился ниже пола в 16M. Vacuum никогда не трогает активные файлы, но потолок управляет самой ротацией — journald пересоздаёт активные файлы меньшими, как только потолок живой. Это разница между вычерпыванием и сантехникой.

Выбирай число по запасу, а не по вкусу: проверь сегодняшний размер через journalctl --disk-usage, затем поставь SystemMaxUse примерно в максимум, который ты вообще хочешь держать — 100M или 200M для рабочей станции более чем достаточно; загруженному серверу может понадобиться 1G. SystemKeepFree=1G — родной брат «ремня и подтяжек»: ограничь журнал и пообещай файловой системе пол. Удаляется всегда самое старое из архивных файлов — journald держит активный файл и всё, что влезает под твой потолок.

Лечение, по порядку

Черпак против вентиля, одним взглядом

инструментчто делаеткогда помогаетзамерено на стенде
--vacuum-size=1Mудаляет старейшие архивные журналы до заданного размера, один разэкстренно: диск полон прямо сейчас56.2M → 16M (освобождено 41.4M), снова 20.3M от следующего идентичного потока
--vacuum-time=2weeksто же, по возрасту вместо размераразовая чистка архивата же форма одного выстрела — ничто не остановит отрастание
SystemMaxUse=5M drop-injournald сам держит потолок на каждой ротациинавсегда: кран закрываетсяидентичный поток удержан на 1.2M — записи потока удалены начисто (400 вошло, 0 осталось)
SystemKeepFree=1Gобещает файловой системе свободное место, независимо от потолкамаленькие диски, вместе с потолкомдух стокового дефолта, теперь явно
«Vacuum вычерпывает ванну; SystemMaxUse закрывает кран. Вычерпывают все — ванна побеждает по умолчанию.»
чего стенд не покрыл

Замерено: одна свежая VM Arch (systemd 262, 262.1-1-arch) — базовое использование, поток в 400 строк с форсированной ротацией, --vacuum-size=1M с его полным stdout, идентичный поток-долив, drop-in SystemMaxUse=5M + рестарт с перечитыванием объединённого конфига, идентичный поток под потолком и файловые свидетели du/ls на каждом шаге. Не замерено: взаимодействие SystemMaxFileSize/числа файлов под потолком, per-unit журналы LogNamespace=, удалённый сбор логов (systemd-journal-remote), запечатывание с forward secrecy (Seal=) и удержание по времени (MaxRetentionSec). Строки потока шли через syslog-сокет, который обрезает длинные строки (дошло ~1 KB) — на учёт не влияет, поскольку каждое число выше — собственный --disk-usage journald, перекрёстно проверенный через du. Базовая линия несла архивы прошлой загрузки (обжитые 48.2M, как на любой настоящей машине). Одна машина, одна сборка: переносима — чтение «кран против черпака»; твой собственный --disk-usage — вердикт.

СТЕНД, ПРОВЕРЕННЫЙ ВРУЧНУЮ · systemd 262 (262.1-1-arch) · свежая VM Arch · последний тест 2026-11-12

Одно число говорит правду — journalctl --disk-usage. Одна строка держит её правдой — SystemMaxUse. Закрой кран; ведро — на пенсию. ■