ServerAID
Найти гайд, команду, тег… ⌘ K
Сервер

journalctl: шпаргалка по логам systemd на Ubuntu

Все логи сервера на Ubuntu собирает systemd-journald, и достать из них нужное — задача одной команды с правильными фильтрами. Собрали рабочую шпаргалку: логи конкретного сервиса, за период, по уровню ошибки, с предыдущей загрузки, а также настройку размера журнала, чтобы он не съел диск.

На современной Ubuntu логи почти всех сервисов лежат не в текстовых файлах, а в бинарном журнале systemd. Это меняет привычки: вместо tail -f /var/log/... и grep работает journalctl с фильтрами. Ниже — набор команд, который закрывает подавляющее большинство задач диагностики.

Что такое journald

systemd-journald — служба, которая собирает сообщения от ядра, initrd, стандартных потоков всех сервисов и от syslog в единый индексированный журнал. Каждая запись хранится со структурированными полями: юнит, PID, UID, приоритет, время, идентификатор загрузки.

Отсюда главное отличие от текстовых логов: фильтровать нужно не grep-ом по строкам, а по полям — быстрее и точнее.

Часть сервисов по-прежнему пишет и в /var/log: nginx ведёт свои access.log и error.log, PostgreSQL — свой лог. А вот systemd-юниты, у которых вывод идёт в stdout, попадают именно в журнал.

Проверить, работает ли журнал и сколько занимает:

systemctl status systemd-journald
journalctl --disk-usage

Базовый просмотр

journalctl                # весь журнал с начала, в пейджере
journalctl -e             # сразу перейти в конец
journalctl -r             # в обратном порядке, новые сверху
journalctl -n 50          # последние 50 строк
journalctl -f             # следить в реальном времени, как tail -f
journalctl --no-pager     # без пейджера, удобно для скриптов

Комбинация -f с фильтром по сервису — самая частая команда при отладке:

journalctl -u nginx -f

Логи конкретного сервиса

journalctl -u nginx                   # весь журнал юнита
journalctl -u nginx -n 100 --no-pager # последние 100 строк
journalctl -u nginx --since today     # за сегодня
journalctl -u nginx -u php8.3-fpm     # сразу два юнита
journalctl -u 'nginx*'                # по шаблону

Суффикс .service можно опускать. Для таймеров и сокетов он обязателен: journalctl -u certbot.timer.

Посмотреть, какие юниты вообще писали в журнал:

journalctl --field _SYSTEMD_UNIT | sort | head -50

Про сами юниты и управление ими — в статье про systemd и systemctl enable.

Фильтр по времени

journalctl --since "2026-08-12 09:00" --until "2026-08-12 10:30"
journalctl --since today
journalctl --since yesterday
journalctl --since "1 hour ago"
journalctl --since "30 min ago"
journalctl --since "2 days ago" --until "1 day ago"

Формат времени понимает и абсолютные значения (ГГГГ-ММ-ДД ЧЧ:ММ:СС), и относительные фразы на английском. Это, пожалуй, самый полезный фильтр: инцидент почти всегда привязан ко времени.

Связка «сервис плюс период» отвечает на вопрос «что происходило перед падением»:

journalctl -u myapp --since "2026-08-12 03:00" --until "2026-08-12 03:15"

Фильтр по уровню важности

journalctl -p err                  # только ошибки и хуже
journalctl -p warning              # предупреждения и хуже
journalctl -p err..alert           # диапазон
journalctl -p err -b               # ошибки с текущей загрузки

Уровни соответствуют syslog:

Код Имя Смысл
0 emerg Система неработоспособна
1 alert Требуется немедленное вмешательство
2 crit Критическая ошибка
3 err Ошибка
4 warning Предупреждение
5 notice Заметное, но нормальное событие
6 info Информационное сообщение
7 debug Отладка

Указание уровня всегда включает все, что выше по важности: -p warning покажет и err, и crit.

Первая команда при разборе «что не так с сервером»:

journalctl -p err -b --no-pager

Логи загрузки и ядра

journalctl -b               # с текущей загрузки
journalctl -b -1            # с предыдущей
journalctl -b -2            # с позапрошлой
journalctl --list-boots     # список всех загрузок с датами
journalctl -k               # только сообщения ядра (аналог dmesg)
journalctl -k -b -1         # сообщения ядра с прошлой загрузки

journalctl -b -1 -p err — то, с чего начинают разбор внезапной перезагрузки: показывает ошибки, записанные до того, как сервер ушёл в ребут.

Если --list-boots показывает только текущую загрузку, значит журнал не сохраняется между перезагрузками — как это исправить, ниже.

Поиск по тексту

Встроенный поиск по регулярному выражению:

journalctl -g "connection refused"
journalctl -u nginx -g "50[0-9]" --since today
journalctl -g "timeout" --case-sensitive=false

Флаг -g (--grep) работает быстрее внешнего grep, потому что фильтрация идёт на уровне журнала. Классический конвейер тоже никто не отменял — например, чтобы посчитать частоту:

journalctl -u myapp --since today --no-pager \
  | grep -oE 'code=[0-9]+' | sort | uniq -c | sort -rn

Разбор таких конвейеров — в статьях про grep и awk.

Фильтр по процессу и пользователю

journalctl _PID=1234
journalctl _UID=1000
journalctl _COMM=sshd                    # по имени исполняемого файла
journalctl /usr/sbin/sshd                # то же, но путём
journalctl --user-unit=myapp             # пользовательский юнит
journalctl _SYSTEMD_UNIT=ssh.service _PID=987   # несколько полей = И

Список доступных полей у конкретной записи показывает подробный формат:

journalctl -u ssh -n 1 -o verbose

Оттуда удобно брать точные имена полей для последующей фильтрации.

Форматы вывода

journalctl -u nginx -o short-iso     # время в ISO-8601, удобно для отчётов
journalctl -u nginx -o cat           # только текст сообщения, без метаданных
journalctl -u nginx -o json-pretty   # структура со всеми полями
journalctl -u nginx -o verbose       # все поля в читаемом виде
journalctl -u nginx -o short-precise # время с микросекундами

Формат cat удобен, когда нужно скормить лог другой утилите, а json — для машинной обработки:

journalctl -u myapp --since today -o json --no-pager \
  | jq -r 'select(.PRIORITY <= "3") | .MESSAGE'

Отключить сокращение длинных строк:

journalctl -u myapp --no-hostname -a

Размер журнала и очистка

Журнал не растёт бесконечно, но настройки по умолчанию щедрые: до 10% от размера раздела /var.

journalctl --disk-usage

Ручная очистка:

sudo journalctl --vacuum-size=500M    # оставить не больше 500 МБ
sudo journalctl --vacuum-time=14d     # оставить только за 14 дней
sudo journalctl --vacuum-files=5      # оставить 5 файлов журнала

Постоянные лимиты задаются в /etc/systemd/journald.conf:

[Journal]
Storage=persistent
SystemMaxUse=1G
SystemMaxFileSize=100M
MaxRetentionSec=1month
sudo systemctl restart systemd-journald

SystemMaxUse — общий потолок, MaxRetentionSec — предельный возраст записей. Ставить оба разумно: первый защищает диск, второй ограничивает глубину истории.

Если место на разделе кончилось внезапно, проверьте журнал в первую очередь — вместе с du -sh /var/log/journal. Про случай, когда место не освобождается после удаления файлов, написано в статье про удаление файлов и каталогов, а посмотреть разделы поможет lsblk.

Журнал не сохраняется после перезагрузки

Если journalctl -b -1 отвечает Specified boot ID does not exist, журнал хранится только в памяти и очищается при каждой перезагрузке. На сервере это неприемлемо — именно логи до ребута обычно и нужны.

Проверяем настройку:

grep -E "^#?Storage" /etc/systemd/journald.conf
ls -ld /var/log/journal

Значение Storage=auto (по умолчанию) означает: хранить на диске, если существует каталог /var/log/journal, иначе — только в памяти. В штатной установке Ubuntu каталог есть, но в контейнерах и на урезанных образах его часто нет.

Включаем постоянное хранение:

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald
journalctl --list-boots

После этого в списке начнут накапливаться загрузки.

Практические рецепты

Всё, что сломалось с момента загрузки:

journalctl -p err -b --no-pager

Почему упал сервис:

journalctl -u myapp -n 100 --no-pager
systemctl status myapp

Кто и когда перезагрузил сервер:

journalctl -u systemd-logind --since "1 day ago" | grep -i "power\|reboot"
last -x | head -20

Сработал ли OOM killer:

journalctl -k --since "1 day ago" -g "Out of memory|oom_kill"

Неудачные попытки входа по SSH:

journalctl -u ssh --since today -g "Failed password" --no-pager | tail -30

Если таких строк много, значит сервер перебирают — как это лечится, разобрано в статье про fail2ban.

Что делал cron прошлой ночью:

journalctl -u cron --since "yesterday 23:00" --until "today 06:00"

Логи 404-х у своего приложения:

journalctl -u myapp --since "7 days ago" --no-pager \
  | grep -oE 'GET [^ ]+ responded 404' | awk '{print $2}' \
  | sort | uniq -c | sort -rn | head -20

Экспорт для передачи коллеге:

journalctl -u myapp --since "2026-08-12" --no-pager -o short-iso > myapp.log

Шпаргалка

journalctl -u nginx -f              следить за сервисом
journalctl -u nginx -n 100          последние 100 строк
journalctl -p err -b                ошибки с текущей загрузки
journalctl --since "1 hour ago"     за последний час
journalctl -b -1                    с предыдущей загрузки
journalctl -k                       сообщения ядра
journalctl -g "текст"               поиск по регулярке
journalctl -o cat                   только сообщения, без метаданных
journalctl --disk-usage             размер журнала
sudo journalctl --vacuum-time=14d   почистить старше 14 дней

Частые вопросы

Где хранятся логи systemd в Ubuntu?

В бинарных файлах каталога /var/log/journal/<machine-id>/, если включено постоянное хранение, либо в /run/log/journal/ — тогда журнал живёт только до перезагрузки.

Читать эти файлы напрямую нельзя, для доступа используется journalctl. Часть сервисов дополнительно ведёт собственные текстовые логи в /var/log.

Как посмотреть логи конкретного сервиса?

journalctl -u имя_сервиса. Например, journalctl -u nginx -n 100 --no-pager покажет последние сто строк без пейджера, а journalctl -u nginx -f будет следить за новыми записями.

Суффикс .service можно опускать, но для таймеров и сокетов его нужно указывать явно.

Как очистить журнал, если он занял всё место?

sudo journalctl --vacuum-size=500M оставит не больше 500 МБ, sudo journalctl --vacuum-time=7d — только записи за последнюю неделю.

Чтобы ситуация не повторилась, задайте SystemMaxUse в /etc/systemd/journald.conf и перезапустите systemd-journald.

Почему journalctl -b -1 пишет, что загрузки не существует?

Журнал хранится в памяти и стирается при перезагрузке. Так бывает, когда отсутствует каталог /var/log/journal — при Storage=auto это переключает journald в режим временного хранения.

Создайте каталог, выполните sudo systemd-tmpfiles --create --prefix /var/log/journal и перезапустите службу — после этого история загрузок начнёт сохраняться.

Чем journalctl -k отличается от dmesg?

Оба показывают сообщения ядра, но dmesg читает кольцевой буфер ядра, который очищается при перезагрузке и перезаписывается по кругу. journalctl -k берёт те же сообщения из журнала, поэтому умеет показывать их за прошлые загрузки (journalctl -k -b -1) и фильтровать по времени.

Для разбора инцидента, который случился вчера, подходит только journalctl.

Что запомнить

  • journalctl -u сервис -f — постоянная команда при отладке; -n 100 --no-pager — быстрый взгляд на последние строки.
  • Фильтры комбинируются и работают как «И»: journalctl -u nginx -p err --since today.
  • -b -1 показывает логи предыдущей загрузки — с этого начинается разбор внезапной перезагрузки.
  • Журнал занимает до 10% от /var по умолчанию: задайте SystemMaxUse в journald.conf, чтобы не упереться в диск.
  • Нет каталога /var/log/journal — журнал живёт только в памяти и исчезает при перезагрузке.

Похожие материалы

Сервер

Установка Webmin на Ubuntu Server: веб-панель управления и её безопасность

Webmin даёт браузерный интерфейс к настройкам сервера: пользователи, сервисы, фаервол, cron, диски. Ставим его из официального репозитория, закрываем доступ к порту 10000 и разбираем главное — панель работает с правами root, поэтому вопрос её защиты важнее вопроса установки.

Редакция
Сервер

Установка Zabbix на Ubuntu Server: сервер, PostgreSQL, веб-интерфейс и агент

Разворачиваем систему мониторинга Zabbix на Ubuntu Server 24.04: официальный репозиторий, база PostgreSQL, фронтенд на nginx, первый вход и подключение агентов. Отдельно — почему zabbix-server не стартует после установки и как читать его лог, когда мониторинг сам требует диагностики.

Редакция
Сервер

Ubuntu Server в VirtualBox: создание виртуальной машины и настройка сети

Разворачиваем Ubuntu Server в VirtualBox для учёбы и тестов: параметры виртуальной машины, установка без графики, разбор сетевых режимов NAT и «сетевой мост», проброс порта для SSH с хоста и снапшоты, которые позволяют ломать систему без последствий.

Редакция
Сервер

Что сделать после установки Ubuntu Server: чек-лист первых шагов

Инсталлятор отработал, вы вошли в систему — дальше идут пятнадцать минут, которые определяют, насколько удобно будет жить с этим сервером. Собрали чек-лист: имя хоста и часовой пояс, пользователи и sudo, автообновления безопасности, swap, синхронизация времени и проверка, что всё это применилось.

Редакция