sadrix logoSadriX
Минцифры готовит обязательную регистрацию IMEI смартфонов, купленных за границей
Гайды

Как смотреть логи сервисов через journalctl: полный гайд

От базового просмотра журнала до точечной фильтрации и постоянного хранения логов

06 517 просмотров7 мин
0
Поделиться:TelegramVK

Введение

В современных дистрибутивах Linux (Ubuntu, Debian, Fedora, CentOS, Arch и большинстве других) сбором системных сообщений занимается systemd-journald. Он пишет журнал в бинарном формате, а для чтения используется утилита journalctl. В отличие от текстовых файлов в /var/log, здесь нет привычных grep-простыней: записи индексируются по метаданным — имени сервиса, PID, приоритету, времени, UID и другим полям.

Это одновременно и плюс, и источник путаницы. Новичок открывает journalctl, видит тысячи строк и не понимает, как вычленить логи конкретного сервиса. В этом гайде разберём практический сценарий: вы администрируете сервер или рабочую станцию и хотите быстро находить сообщения нужной службы, отслеживать ошибки в реальном времени и сохранять историю между перезагрузками.

Материал рассчитан на пользователей, знакомых с командной строкой и базовыми правами sudo. Специальных знаний systemd не требуется — все шаги даны последовательно.

Требования и подготовка

Перед началом проверьте окружение:

1. Дистрибутив с systemd. Проверить можно командой ps -p 1 -o comm=. Если в ответе systemd, всё в порядке. В контейнерах и WSL возможны исключения. 2. Права. Чтение системного журнала обычно требует членства в группе systemd-journal или прав root. Если journalctl без sudo выдаёт пустой вывод или «No journal files were found», используйте sudo. 3. Установленный пакет. В большинстве систем утилита уже есть. Если нет — установите systemd (или systemd-journal-remote для удалённого сбора) штатным пакетным менеджером. 4. Понимание имени юнита. Логи привязаны к systemd-юнитам вида nginx.service, sshd.service. Список активных юнитов даёт systemctl list-units --type=service.

Полезно сразу запомнить: journalctl без аргументов показывает весь журнал с начала (в пределах доступной истории), а вывод открывается в пейджере less. Навигация — стрелки, поиск — /, выход — q.

Шаг 1. Базовый просмотр журнала

Начните с общей картины:

sudo journalctl

Вы увидите записи в хронологическом порядке: время, имя хоста, процесс и сообщение. Обратите внимание на маркеры: строки с error и warning встречаются часто, но не все они критичны.

Полезные варианты первого знакомства:

  • journalctl -n 50 — последние 50 строк, без открытия всего журнала.

  • journalctl -e — сразу перейти к концу журнала.

  • journalctl --no-pager — вывести всё в stdout, удобно для перенаправления в файл.

  • journalctl -o short-precise — более точные метки времени с микросекундами.

Если вывод пуст, скорее всего журнал не ведётся в постоянном режиме или у вас нет прав. Об этом — ниже.

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

Главный практический приём — фильтр по юниту:

sudo journalctl -u nginx.service

Флаг -u (от unit) принимает имя юнита. Можно указывать несколько раз: -u nginx -u php-fpm. Это удобно, когда сервис состоит из нескольких компонентов.

Дополните фильтр по времени и количеству строк:

sudo journalctl -u sshd.service --since "today" -n 100

Если не уверены в точном имени, найдите его:

systemctl list-units --type=service | grep -i nginx

Обратите внимание: journalctl -u показывает сообщения, которые systemd связал с юнитом. Некоторые программы пишут в журнал через syslog с другим идентификатором, и тогда их записи могут не попасть в выборку по -u. В таких случаях используйте фильтр по _SYSTEMD_UNIT или по SYSLOG_IDENTIFIER (см. шаг 6).

Шаг 3. Фильтрация по времени

Флаг --since и --until принимают как абсолютные даты, так и относительные выражения:

sudo journalctl -u nginx --since "2025-01-15 10:00:00" --until "2025-01-15 12:00:00"

Относительные варианты, которые экономят время:

  • --since "1 hour ago"

  • --since yesterday

  • --since "-30 min"

  • --until "2025-01-15" (до начала указанного дня)

Комбинируйте с -u и -p, чтобы сузить выборку. Например, ошибки nginx за последний час:

sudo journalctl -u nginx --since "1 hour ago" -p err

Важно: относительное время вычисляется на момент запуска команды, поэтому для воспроизводимых отчётов лучше фиксировать абсолютные даты.

Шаг 4. Слежение за журналом в реальном времени

Аналог tail -f — флаг -f:

sudo journalctl -u myapp.service -f

Вывод будет обновляться по мере появления новых записей. Выход — Ctrl+C.

Полезные дополнения:

  • -n 20 -f — показать последние 20 строк и продолжить слежение.

  • --since "now" -f — начать только с текущего момента, без исторического контекста.

  • -o cat — убрать служебные префиксы и оставить только текст сообщения, удобно для мониторинга.

Если сервис перезапускается, слежение не прервётся: journalctl продолжит показывать записи по юниту. Это удобно при отладке деплоя.

Шаг 5. Фильтрация по приоритету

Каждое сообщение имеет приоритет syslog от 0 (emerg) до 7 (debug). Флаг -p выбирает записи с указанным уровнем и выше:

sudo journalctl -p err

Покажет ошибки, критические и аварийные сообщения. Уровни: emerg, alert, crit, err, warning, notice, info, debug. Можно использовать числа: -p 3 эквивалентно err.

Практический сценарий — быстрый обзор проблем за сутки:

sudo journalctl --since yesterday -p warning --no-pager | less

Учтите: приоритет выставляется самой программой. Некоторые приложения пишут всё как info, поэтому -p err может не показать их реальные ошибки. В таких случаях фильтруйте по тексту (шаг 8).

Шаг 6. Продвинутые фильтры по полям

journalctl умеет фильтровать по произвольным полям записи. Посмотреть доступные поля можно так:

sudo journalctl -o verbose -n 1

Вы увидите _PID, _UID, _SYSTEMD_UNIT, SYSLOG_IDENTIFIER, _COMM, _EXE и другие. Фильтр задаётся выражением ПОЛЕ=значение:

sudo journalctl _SYSTEMD_UNIT=nginx.service
sudo journalctl SYSLOG_IDENTIFIER=sshd
sudo journalctl _PID=1234

Это выручает, когда сервис запущен не через systemd или пишет под собственным идентификатором. Например, логи PHP-FPM часто ищутся по SYSLOG_IDENTIFIER=php-fpm.

Можно комбинировать несколько полей — они объединяются по логическому И. Для объединения по ИЛИ используйте несколько вызовов или + между выражениями (в новых версиях systemd).

Шаг 7. Поиск по тексту сообщения

Флаг -g (grep) фильтрует по регулярному выражению в тексте:

sudo journalctl -u nginx -g "error|timeout" --since "2 hours ago"

По умолчанию поиск регистрозависим. Для нечувствительности используйте --case-sensitive=no (в свежих версиях) или комбинацию с grep -i через пайп:

sudo journalctl -u myapp --no-pager | grep -i "exception"

Пайп с grep проще и переносим, но теряет структурированные поля. -g работает быстрее на больших журналах, так как фильтрация идёт внутри journalctl.

Шаг 8. Форматы вывода и экспорт

По умолчанию используется short. Другие полезные форматы:

  • -o json-pretty — структурированный JSON, удобно для разбора скриптами.

  • -o cat — только сообщения.

  • -o short-iso — ISO-время, удобно для сопоставления с другими логами.

  • -o verbose — все поля записи.

Экспорт в файл:

sudo journalctl -u nginx --since "2025-01-01" --no-pager > nginx-jan.log

Для машинной обработки:

sudo journalctl -u myapp -o json --no-pager | jq -r ".MESSAGE"

Помните, что --no-pager обязателен при перенаправлении, иначе вывод может обрезаться или зависнуть.

Шаг 9. Постоянное хранение журнала

По умолчанию во многих дистрибутивах журнал хранится только в памяти (/run/log/journal) и теряется после перезагрузки. Чтобы логи сохранялись, включите постоянное хранилище:

1. Создайте каталог: sudo mkdir -p /var/log/journal. 2. Настройте права: sudo systemd-tmpfiles --create --prefix /var/log/journal. 3. Перезапустите службу: sudo systemctl restart systemd-journald.

Проверьте, что журнал пишется на диск: journalctl --disk-usage покажет путь и объём. Если путь указывает на /run, настройка не применилась.

Дополнительно можно задать лимиты в /etc/systemd/journald.conf: SystemMaxUse=1G, SystemMaxFileSize=100M, MaxRetentionSec=2week. После правки — sudo systemctl restart systemd-journald. Не редактируйте файл вслепую: сохраните резервную копию.

Шаг 10. Обслуживание и очистка

Журнал растёт и может занять диск. Проверить объём:

journalctl --disk-usage

Очистить старые записи:

sudo journalctl --vacuum-time=7d
sudo journalctl --vacuum-size=500M

Первая команда удалит записи старше недели, вторая — оставит не более 500 МБ. Ротация также управляется настройками SystemMaxUse и MaxRetentionSec.

Не удаляйте файлы журнала вручную из /var/log/journal — используйте --vacuum-*, чтобы не повредить индекс.

Типичные ошибки

1. Пустой вывод без sudo. Пользователь не входит в группу systemd-journal. Решение: запускать через sudo или добавить пользователя в группу. 2. «No journal files were found». Журнал не постоянный, либо система не использует systemd. Проверьте /var/log/journal и статус systemd-journald. 3. Фильтр `-u` не показывает логи приложения. Программа пишет через syslog с другим идентификатором. Используйте SYSLOG_IDENTIFIER или _COMM. 4. `-p err` не находит ошибок. Приложение помечает всё как info. Ищите по тексту через -g. 5. Обрезанный вывод при экспорте. Забыт --no-pager. 6. Слишком широкий `--since`. Журнал может быть огромным; сначала ограничьте -n или временем. 7. Правка `journald.conf` без перезапуска. Изменения не применяются до systemctl restart systemd-journald. 8. Ручное удаление файлов журнала. Приводит к ошибкам индекса; используйте vacuum-команды.

FAQ

Чем journalctl отличается от просмотра `/var/log/syslog`? Journalctl читает бинарный индексированный журнал systemd и умеет фильтровать по полям, времени и приоритету. Текстовые файлы в /var/log ведутся отдельными службами (rsyslog) и могут дублировать часть сообщений.

Как посмотреть логи только за последний запуск системы? journalctl -b — текущая загрузка, journalctl -b -1 — предыдущая. Список загрузок: journalctl --list-boots.

Почему после перезагрузки логи пропали? Журнал хранился в /run/log/journal. Включите постоянное хранилище (шаг 9).

Как найти логи конкретного PID? journalctl _PID=1234. PID можно получить через systemctl show -p MainPID myapp.service.

Можно ли смотреть журнал другого пользователя? Да, с правами root: journalctl _UID=1000. Обычный пользователь увидит только свои записи, если настроено соответствующее разграничение.

Как отследить, кто перезапустил сервис? Ищите записи systemd по юниту: journalctl -u myapp.service | grep -i "start\|stop\|restart". Точные причины часто видны в сообщениях самого юнита.

Итог

journalctl — основной инструмент диагностики в системах с systemd. Начните с -u для конкретного сервиса, добавьте --since и -p для сужения выборки, используйте -f для наблюдения в реальном времени. Если стандартных фильтров не хватает, переходите к полям _SYSTEMD_UNIT, SYSLOG_IDENTIFIER и поиску по тексту через -g. И не забудьте включить постоянное хранение журнала — иначе после перезагрузки история исчезнет, а вместе с ней и контекст для разбора инцидента.

Читайте также

Комментарии

Комментарии доступны только зарегистрированным пользователям. Войти

  • Пока нет комментариев. Будьте первым.