Пошаговая инструкция

Одним из значимых преимуществ systemd является его возможность работы с логами процессов и системы в целом. При использовании остальных инструментов, отличных от systemd, логи обычно сильно децентрализованы, разбросаны по разным демонам, что затрудняет управление ими. Система, собирающая логи, и управляющая ими называется журналом.
Журнал представлен демоном journald, который собирает сообщения ядра, сервисов, процессов и т.д. Мы же разберёмся, как работать с journalctl, позволяющим управлять записями, сохранёнными в журнале.
Логи, собранные в systemd, сохраняются централизованно — в двоичном формате, что сильно упрощает их обработку. Например, можно выбирать произвольные форматы вывода логов, в зависимости от текущих потребностей (например, JSON).
Журнал systemd может использоваться вместе с системной реализацией журнала, либо вообще заменить его.

Настройка системного времени

Одно из преимущество хранения данных журнала в бинарном виде — возможность просмотра лога в любой временной зоне, на лету, без преобразований. По умолчанию, показывается локальное время.
Для вывода списка временных зон введите команду:

$ timedatectl list-timezones

Для установки временной зоны, в свою очередь:

$ sudo timedatectl set-timezone zone

Для проверки правильности внесенных изменений — вывод статуса:

$ timedatectl status

Пример вывода:
Local time: Fri 2016-12-23 03:45:42 MSK Universal time: Fri 2016-12-23 00:45:42 UTC RTC time: Fri 2016-12-23 00:45:42 Time zone: Europe/Moscow (MSK, +0300) Network time on: yes NTP synchronized: yes RTC in local TZ: no

Обычный просмотр логов

Вывод логов, собранных демоном journald выполняется с помощью journalctl. Для примера, запуск без параметров — последние события внизу:

$ journalctl

Вывод:
Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Stopped target Basic System. Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Stopped target Sockets. Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Stopped target Timers. Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Stopped target Paths. Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Reached target Shutdown. Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Starting Exit the Session... Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Received SIGRTMIN+24 from PID 17216 (kill). ...Как видите, время локальное. Для вывода UTC-времени — добавьте параметр —utc:

$ journalctl --utc

Если необходимы только события с момента текущей загрузки, добавьте параметр -b:

$ journalctl -b

Если нужны только сообщения ядра — воспользуйтесь параметром -k:

$ journalctl -k

Как Вы понимаете, если добавить -b, останутся только записи, относящиеся к последней загрузке системы:

$ journalctl -k -b

Для вывода списка прошедших загрузок системы — выполните:
$ journalctl --list-boots Текущая загрузка под номер 0. Предыдущие имеют отрицательные номера: -1, -2, …
-2 6cc1de0fb9a8421094b47fab2a9d0296 Wed 2016-11-23 12:36:44 MSK-Thu 2016-12-01 13:42:09 MSK -1 28ed3b9d1fa44799927e41dedc875764 Thu 2016-12-01 13:43:30 MSK-Sun 2016-12-11 12:15:35 MSK 0 2ed1975fc7a742afad1e89839c0410c6 Sun 2016-12-11 12:16:11 MSK-Fri 2016-12-23 03:44:04 MSKМожно вывести информацию о предпоследней загрузке следующим образом:
$ journalctl -b -1 Или же сославшись на конкретный ID загрузки:

$ journalctl -b 

28ed3b9d1fa44799927e41dedc875764

Временные окна

Несмотря на то, что просматривать логи, распределенные по загрузкам системы — довольно удобно, бывают случаи, когда необходимо вывести события, заключенные в каких-либо других временных рамках.
Для этого предназначены опции —since и —until.
Формат даты-времени — следующий:
ГГГГ-ММ-ДД ЧЧ:ММ:СС
К примеру, вывод всех события, начиная с 3-х часов ночи 1 декабря 2016 года:

$ journalctl --since "2016-12-01 03:00:00"

Или показ событий между 1 и 8 декабря:

$ journalctl --since "2016-12-01 03:00:00" --until "2016-12-08 00:03:00"

Также, имеется поддержка ключевых слов «yesterday», «today», «now» (вчера, сегодня, сейчас).
К примеру, вчерашние события:

journalctl --since yesterday

Фильтрация записей

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

$ journalctl -u nginx.service

Как и всегда, можно добавлять параметры — к примеру, временные рамки. Например, вывод только сегодняшних событий с указанным юнитом:

$ journalctl -u nginx.service --since today

Помните, что в параметрах можно указать более одного юнита:

$ journalctl -u nginx.service -u php-fpm.service --since today

По процессу, пользователю, ID группы
К примеру, если нужны события только, относящиеся к процессу с заданным PID:

$ journalctl _PID=8125

Также можно узнать ID группы пользователей:
$ id -u www-data 33И также использовать его как параметр:

$ journalctl _UID=33 --since today

Полный список полей, по которым доступна фильтрация:

$ man systemd.journal-fields

По пути запуска
Допустим, нужны события, связанные с bash. Выполним:

$ journalctl /usr/bin/bash

По приоритету
Очень важна возможность фильтрации сообщений по их приоритету:
Допустим, так можно вывести только те записи, которые помечены как ошибки:

$ journalctl -p err -b

Приведём полный список приоритетов (добавьте цифру после параметра p):
0: авария
1: предупреждение
2: критический
3: ошибка
4: предупреждение
5: уведомление
6: информация
7: отладка

Изменение отображения журнала

Выше мы рассмотрели фильтрацию по различным критериям, сейчас же — перейдём к способам видоизменения журнала.
Ограничение или расширения вывода
По умолчанию, journalctl не переносит строки по ширине экрана. Чтобы сократить вывод по ширине экрана — выполните:

$ journalctl --no-full

Чтобы выводить даже непечатные символы:

$ journalctl -a

Если вы обрабатываете вывод утилиты какими-то программными инструментами, Вам может понадобиться вывод в standard out — тогда не будет разделения на страницы:

$ journalctl --no-pager

Форматы вывода
Посредством параметра -o нам доступен ряд форматов вывода.
Конечно же, JSON:

$ journalctl -b -u nginx -o json

Пример вывода:

{ "__CURSOR" : "s=13a21661cf4948289c63075db6c25c00;i=116f1;b=81b58db8fd9046ab9f847ddb82a2fa2d;m=19f0daa;t=50e33c33587ae;x=e307daadb4858635", "__REALTIME_TIMESTAMP" : "1422990364739502", "__MONOTONIC_TIMESTAMP" : "27200938", "_BOOT_ID" : "81b58db8fd9046ab9f847ddb82a2fa2d", "PRIORITY" : "6", "_UID" : "0", "_GID" : "0", "_CAP_EFFECTIVE" : "3fffffffff", "_MACHINE_ID" : "752737531a9d1a9c1e3cb52a4ab967ee", "_HOSTNAME" : "desktop", "SYSLOG_FACILITY" : "3", "CODE_FILE" : "src/core/unit.c", "CODE_LINE" : "1402", "CODE_FUNCTION" : "unit_status_log_starting_stopping_reloading", "SYSLOG_IDENTIFIER" : "systemd", "MESSAGE_ID" : "7d4958e842da4a758f6c1cdc7b36dcc5", "_TRANSPORT" : "journal", "_PID" : "1", "_COMM" : "systemd", "_EXE" : "/usr/lib/systemd/systemd", "_CMDLINE" : "/usr/lib/systemd/systemd", "_SYSTEMD_CGROUP" : "/", "UNIT" : "nginx.service", "MESSAGE" : "Starting A high performance web server and a reverse proxy server...", "_SOURCE_REALTIME_TIMESTAMP" : "1422990364737973" }

Это очень удобный формата для программного парсинга внешними утилитами. Можно отформатировать вывод:

$ journalctl -b -u nginx -o json-pretty

Вывод куда более удобен для чтения:
{ "__CURSOR" : "s=13a21661cf4948289c63075db6c25c00;i=116f1;b=81b58db8fd9046ab9f847ddb82a2fa2d;m=19f0daa;t=50e33c33587ae;x=e307daadb4858635", "__REALTIME_TIMESTAMP" : "1422990364739502", "__MONOTONIC_TIMESTAMP" : "27200938", "_BOOT_ID" : "81b58db8fd9046ab9f847ddb82a2fa2d", "PRIORITY" : "6", "_UID" : "0", "_GID" : "0", "_CAP_EFFECTIVE" : "3fffffffff", "_MACHINE_ID" : "752737531a9d1a9c1e3cb52a4ab967ee", "_HOSTNAME" : "desktop", "SYSLOG_FACILITY" : "3", "CODE_FILE" : "src/core/unit.c", "CODE_LINE" : "1402", "CODE_FUNCTION" : "unit_status_log_starting_stopping_reloading", "SYSLOG_IDENTIFIER" : "systemd", "MESSAGE_ID" : "7d4958e842da4a758f6c1cdc7b36dcc5", "_TRANSPORT" : "journal", "_PID" : "1", "_COMM" : "systemd", "_EXE" : "/usr/lib/systemd/systemd", "_CMDLINE" : "/usr/lib/systemd/systemd", "_SYSTEMD_CGROUP" : "/", "UNIT" : "nginx.service", "MESSAGE" : "Starting A high performance web server and a reverse proxy server...", "_SOURCE_REALTIME_TIMESTAMP" : "1422990364737973" }Приведём полный список форматов вывода:
cat: отображает только поле сообщения
export: бинарный формат вывода
json: стандартный JSON, одна запись на строку
json-pretty: отформатированный, человеко-читаемый JSON
short: стиль вывода syslog по умолчанию
short-iso: формат по-умолчанию, стандарт ISO 8601
short-monotonic: монотонные временные метки
short-precise: с добавлением микросекунд
verbose: принудительный вывод даже скрытых записей

Мониторинг текущих событий

Аналогично утилите tail, только соответствующая функциональность уже встроена в journalctl.
Вывод последних 25 записей:

$ journalctl -n 25

Отслеживание журнала
Для обновления вывода на экрана по мере поступления записей в лог — выполните:

$ journalctl -f

Управление журналом

Мы разобрали многое, теперь осталось затронуть некоторые вопросы администрирования журнала.
Вычисление занятого дискового пространства
Для вывода занятого журналом дискового пространства:

$ journalctl --disk-usage

Удаление старых записей
Мы можем удалить самые старые записей, чтобы сократить размер журнала до заданного нами размера. Например:

$ sudo journalctl --vacuum-size=1G

Или к примеру, можно удалить записи старше года:

$ sudo journalctl --vacuum-time=1years

Заключение

В данном руководстве мы рассмотрели основополагающие аспекты работы с утилитой journalctl.