Как работать с логами systemd

Одним из значимых преимуществ 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.

Добавить комментарий

Автору будет очень приятно узнать обратную связь о своем руководстве.

Комментариев 0