Содержание[Скрыть]
Введение
Одним из значимых преимуществ systemd является его возможность работы с логами процессов и системы в целом. При использовании остальных инструментов, отличных от systemd, логи обычно сильно децентрализованы, разбросаны по разным демонам, что затрудняет управление ими. Система, собирающая логи, и управляющая ими называется журналом. Журнал представлен демоном journald, который собирает сообщения ядра, сервисов, процессов и т.д. Мы же разберёмся, как работать с journalctl, позволяющим управлять записями, сохранёнными в журнале. Логи, собранные в systemd, сохраняются централизованно — в двоичном формате, что сильно упрощает их обработку. Например, можно выбирать произвольные форматы вывода логов, в зависимости от текущих потребностей (например, JSON). Журнал systemd может использоваться вместе с системной реализацией журнала, либо вообще заменить его.
Настройка системного времени
Одно из преимущество хранения данных журнала в бинарном виде — возможность просмотра лога в любой временной зоне, на лету, без преобразований. По умолчанию, показывается локальное время. Для вывода списка временных зон введите команду:
1 |
$ timedatectl list-timezones |
Для установки временной зоны, в свою очередь:
1 |
$ sudo timedatectl set-timezone zone |
Для проверки правильности внесенных изменений — вывод статуса:
1 |
$ timedatectl status |
Пример вывода:
1 |
Local time: Fri 2016-12-23 03:45:42 MSK<br> Universal time: Fri 2016-12-23 00:45:42 UTC<br> RTC time: Fri 2016-12-23 00:45:42<br> Time zone: Europe/Moscow (MSK, +0300)<br> Network time on: yes<br>NTP synchronized: yes<br> RTC in local TZ: no |
Обычный просмотр логов
Вывод логов, собранных демоном journald выполняется с помощью journalctl. Для примера, запуск без параметров — последние события внизу:
1 |
$ journalctl |
Вывод:
1 |
Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Stopped target Basic System.<br>Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Stopped target Sockets.<br>Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Stopped target Timers.<br>Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Stopped target Paths.<br>Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Reached target Shutdown.<br>Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Starting Exit the Session...<br>Dec 20 17:24:29 ubuntu-512mb systemd[20583]: Received SIGRTMIN+24 from PID 17216 (kill).<br>... |
Как видите, время локальное. Для вывода UTC-времени — добавьте параметр —utc:
1 |
$ journalctl --utc |
Если необходимы только события с момента текущей загрузки, добавьте параметр -b:
1 |
$ journalctl -b |
Если нужны только сообщения ядра — воспользуйтесь параметром -k:
1 |
$ journalctl -k |
Как Вы понимаете, если добавить -b, останутся только записи, относящиеся к последней загрузке системы:
1 |
$ journalctl -k -b |
Для вывода списка прошедших загрузок системы — выполните:
1 |
$ journalctl --list-boots |
Текущая загрузка под номер 0. Предыдущие имеют отрицательные номера: -1, -2, …
1 |
-2 6cc1de0fb9a8421094b47fab2a9d0296 Wed 2016-11-23 12:36:44 MSK—Thu 2016-12-01 13:42:09 MSK<br>-1 28ed3b9d1fa44799927e41dedc875764 Thu 2016-12-01 13:43:30 MSK—Sun 2016-12-11 12:15:35 MSK<br> 0 2ed1975fc7a742afad1e89839c0410c6 Sun 2016-12-11 12:16:11 MSK—Fri 2016-12-23 03:44:04 MSK |
Можно вывести информацию о предпоследней загрузке следующим образом:
1 |
$ journalctl -b -1 |
Или же сославшись на конкретный ID загрузки:
1 |
$ journalctl -b 28ed3b9d1fa44799927e41dedc875764 |
Временные окна
Несмотря на то, что просматривать логи, распределенные по загрузкам системы — довольно удобно, бывают случаи, когда необходимо вывести события, заключенные в каких-либо других временных рамках. Для этого предназначены опции —since и —until.
Формат даты-времени — следующий: ГГГГ-ММ-ДД ЧЧ:ММ:СС К примеру, вывод всех события, начиная с 3-х часов ночи 1 декабря 2016 года:
1 |
$ journalctl --since "2016-12-01 03:00:00" |
Или показ событий между 1 и 8 декабря:
1 |
$ journalctl --since "2016-12-01 03:00:00" --until "2016-12-08 00:03:00" |
Также, имеется поддержка ключевых слов «yesterday», «today», «now» (вчера, сегодня, сейчас). К примеру, вчерашние события:
1 |
journalctl --since yesterday |
Фильтрация записей
Выше мы узнали, как задать временные рамки для просмотра логов. Но есть и другие способы фильтрации.
По юниту Собственно, самый часто используемая возможность — фильтрация по имени юнита:
1 |
$ journalctl -u nginx.service |
Как и всегда, можно добавлять параметры — к примеру, временные рамки. Например, вывод только сегодняшних событий с указанным юнитом:
1 |
$ journalctl -u nginx.service --since today |
Помните, что в параметрах можно указать более одного юнита:
1 |
$ journalctl -u nginx.service -u php-fpm.service --since today |
По процессу, пользователю, ID группы
К примеру, если нужны события только, относящиеся к процессу с заданным PID:
1 |
$ journalctl _PID=8125 |
Также можно узнать ID группы пользователей:
1 |
$ id -u www-data |
И также использовать его как параметр:
1 |
$ journalctl _UID=33 --since today |
Полный список полей, по которым доступна фильтрация:
1 |
$ man systemd.journal-fields |
По пути запуска Допустим, нужны события, связанные с bash. Выполним:
1 |
$ journalctl /usr/bin/bash |
По приоритету
Очень важна возможность фильтрации сообщений по их приоритету: Допустим, так можно вывести только те записи, которые помечены как ошибки:
1 |
$ journalctl -p err -b |
Приведём полный список приоритетов (добавьте цифру после параметра p): 0: авария 1: предупреждение 2: критический 3: ошибка 4: предупреждение 5: уведомление 6: информация 7: отладка
Изменение отображения журнала
Выше мы рассмотрели фильтрацию по различным критериям, сейчас же — перейдём к способам видоизменения журнала.
Ограничение или расширения вывода По умолчанию, journalctl не переносит строки по ширине экрана. Чтобы сократить вывод по ширине экрана — выполните:
1 |
$ journalctl --no-full |
Чтобы выводить даже непечатные символы:
1 |
$ journalctl -a |
Если вы обрабатываете вывод утилиты какими-то программными инструментами, Вам может понадобиться вывод в standard out — тогда не будет разделения на страницы:
1 |
$ journalctl --no-pager |
Форматы вывода Посредством параметра -o нам доступен ряд форматов вывода. Конечно же, JSON:
1 |
$ journalctl -b -u nginx -o json |
Пример вывода:
1 |
{ "__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" } |
Это очень удобный формата для программного парсинга внешними утилитами. Можно отформатировать вывод:
1 |
$ journalctl -b -u nginx -o json-pretty |
Вывод куда более удобен для чтения:
1 |
<pre class="inline:true decode:1 ">{<br> "__CURSOR" : "s=13a21661cf4948289c63075db6c25c00;i=116f1;b=81b58db8fd9046ab9f847ddb82a2fa2d;m=19f0daa;t=50e33c33587ae;x=e307daadb4858635",<br> "__REALTIME_TIMESTAMP" : "1422990364739502",<br> "__MONOTONIC_TIMESTAMP" : "27200938",<br> "_BOOT_ID" : "81b58db8fd9046ab9f847ddb82a2fa2d",<br> "PRIORITY" : "6",<br> "_UID" : "0",<br> "_GID" : "0",<br> "_CAP_EFFECTIVE" : "3fffffffff",<br> "_MACHINE_ID" : "752737531a9d1a9c1e3cb52a4ab967ee",<br> "_HOSTNAME" : "desktop",<br> "SYSLOG_FACILITY" : "3",<br> "CODE_FILE" : "src/core/unit.c",<br> "CODE_LINE" : "1402",<br> "CODE_FUNCTION" : "unit_status_log_starting_stopping_reloading",<br> "SYSLOG_IDENTIFIER" : "systemd",<br> "MESSAGE_ID" : "7d4958e842da4a758f6c1cdc7b36dcc5",<br> "_TRANSPORT" : "journal",<br> "_PID" : "1",<br> "_COMM" : "systemd",<br> "_EXE" : "/usr/lib/systemd/systemd",<br> "_CMDLINE" : "/usr/lib/systemd/systemd",<br> "_SYSTEMD_CGROUP" : "/",<br> "UNIT" : "nginx.service",<br> "MESSAGE" : "Starting A high performance web server and a reverse proxy server...",<br> "_SOURCE_REALTIME_TIMESTAMP" : "1422990364737973"<br>} |
Приведём полный список форматов вывода: cat: отображает только поле сообщения export: бинарный формат вывода json: стандартный JSON, одна запись на строку json-pretty: отформатированный, человеко-читаемый JSON short: стиль вывода syslog по умолчанию short-iso: формат по-умолчанию, стандарт ISO 8601 short-monotonic: монотонные временные метки short-precise: с добавлением микросекунд verbose: принудительный вывод даже скрытых записей
Мониторинг текущих событий
Аналогично утилите tail, только соответствующая функциональность уже встроена в journalctl. Вывод последних 25 записей:
1 |
$ journalctl -n |
Отслеживание журнала Для обновления вывода на экрана по мере поступления записей в лог — выполните:
1 |
$ journalctl -f |
Управление журналом
Мы разобрали многое, теперь осталось затронуть некоторые вопросы администрирования журнала.
Вычисление занятого дискового пространства Для вывода занятого журналом дискового пространства:
1 |
$ journalctl --disk-usage |
Удаление старых записей Мы можем удалить самые старые записей, чтобы сократить размер журнала до заданного нами размера. Например:
1 |
$ sudo journalctl --vacuum-size=1G |
Или к примеру, можно удалить записи старше года:
1 |
$ sudo journalctl --vacuum-time=1years |
Заключение
В данном руководстве мы рассмотрели основополагающие аспекты работы с утилитой journalctl.
Ваш комментарий будет первым