Инструменты пользователя

Инструменты сайта


journald

journald

Немного о сабже

В systemd используется принципиально иной (по сравнению с традиционным инструментом syslog) подход к логированию.

В его основе лежит централизация: специализированный компонент journal собирает все системные сообщения (сообщения ядра, различных служб и приложений). При этом специально настраивать отправку логов не нужно: приложения могут просто писать в stdout и stderr, a journal сохранит эти сообщения автоматически. Работа в таком режиме возможна и с Upstart, но он сохраняет все логи в отдельный файл, тогда как systemd сохраняет их в бинарной базе, что существенно упрощает систематизацию и поиск.

Хранение логов в бинарных файлах также позволяет избежать сложностей с использованием парсеров для разных видов логов. При необходимости логи можно без проблем переконвертировать в другие форматы (более подробно об этом будет рассказано ниже). Journal может работать как совместно с syslog, так и полностью заменить его. Для просмотра логов используется утилита journalctl.

Установка времени

Одним из существенных недостатков syslog является сохранение записей без учёта часового пояса. В journal этот недостаток устранён. Для логируемых событий можно указывать как местное время, так и универсальное координированное время (UTC). Установка времени осуществляется с помощью утилиты timedatectl.

Просмотреть список часовых поясов можно при помощи команды:

timedatectl list-timezones

Установка нужного часового пояса осуществляется таким образом:

timedatectl set-timezone Europe/Moscow

После установки проверим текущий часовой пояс:

 timedatectl status

      Local time: Ср 2020-12-09 09:43:28 MSK
  Universal time: Ср 2020-12-09 06:43:28 UTC
        RTC time: Ср 2020-12-09 06:43:28
       Time zone: Europe/Moscow (MSK, +0300)
 Network time on: yes
NTP synchronized: yes
 RTC in local TZ: no

В самой первой строке (Local time), показаны точное текущее время и дата.

Хранение логов и их ротация

Для начала, убедимся что логи journald не очищаются с каждой перезагрузкой сервера. В случае если на сервере имеется директория /run/log/journal/ и она не пуста, если директории /var/log/journal не существует и если команда journalctl --list-boots показывает только один пункт из списка, то скорее всего в этом случае journald настроен на временное хранение логов до рестарта. Исправить эту ситуацию можно следующим образом:

Включаем постоянное хранение логов в конфигураторе /etc/systemd/journald.conf:

Storage=persistent

Создадим директорию для журналов и введем её в работу

mkdir /var/log/journal
systemd-tmpfiles --create --prefix /var/log/journal
systemctl restart systemd-journald

Теперь логи будут храниться на диске и к ним можно будет обращаться после перезагрузки.

Что бы логи не разрослись, имеет смысл настроить их ротацию, для этого у journalctl доступны параметры --vacuum-size и --vacuum-time.

Просмотрим на общий размер логов:

journalctl --disk-usage
Archived and active journals take up 160.0M on disk.

Ограничим размер логов объёмом в 1GB:

journalctl --vacuum-size=1G
Vacuuming done, freed 0B of archived journals on disk.

При надобности, ограничиваем времени хранения логов:

journalctl --vacuum-time=1years

Если логи занимали 2GB, при ограничении размера до 1GB, система удалит самые старые логи. Аналогично и со временем хранения журналов. Дополнительную настройку лимитов можно выполнить в конфигурационном файле /etc/systemd/journald.conf.

Настройка ротации логов в конфигурационном файле

Настройки ротации логов можно также прописать в конфигурационном файле /еtc/systemd/journald.conf, который включает в числе прочих следующие параметры:

  • SystemMaxUse= – максимальный объём, который логи могут занимать на диске;
  • SystemKeepFree= – объём свободного места, которое должно оставаться на диске после сохранения логов;
  • SystemMaxFileSize= – объём файла лога, по достижении которого он должен быть удален с диска;
  • RuntimeMaxUse= – максимальный объём, который логи могут занимать в файловой системе /run;
  • RuntimeKeepFree= – объём свободного места, которое должно оставаться в файловой системе /run после сохранения логов;
  • RuntimeMaxFileSize= – объём файла лога, по достижении которого он должен быть удален из файловой системы /run.

Централизованное хранение логов

Одной из самых распространённых задач является настройка сбора логов с нескольких машин с последующим помещением в централизованное хранилище.

В systemd предусмотрены специальные компоненты для решения этой задачи: systemd-journal-remote, systemd-journal-upload и systemd-journal-gatewayd.

С помощью команды systemd-journal-remote можно принимать логи с удалённых хостов и сохранять их (на каждом из этих хостов должен быть запущен демон systemd-journal-gatewayd), например:

systemd-journal-remote −−url https://host.name:7547/

В результате выполнения приведённой команды логи с хоста https://host.name/ будут сохранены в директории /var/log/journal/host.name/remote-some~host.journal.

С помощью команды systemd-journal-remote можно также складывать имеющиеся на локальной машине логи в отдельную директорию, например:

journalctl -o export | systemd-journal-remote -o /tmp/dir -

Команда systemd-journal-upload используется для загрузки логов с локальной машины в удалённое хранилище:

systemd-journal-upload --url https://host.name:7547/

Journalctl: просмотр логов

Для просмотра логов используется утилита journalctl. Если ввести команду journalсtl без каких-либо аргументов, на консоль будет выведен огромный список.

Просмотр информации о недавних событиях

Опция -n используется для просмотра информации о недавних событиях в системе:

journalctl -n

По умолчанию на консоль выводится информация о последних 10 событиях. С опцией -n можно указать необходимое число событий:

journalctl -n 20

Просмотр логов в режиме реального времени

Сообщения из логов можно просматривать не только в виде сохранённых файлов, но и в режиме реального времени. Для этого используется опция -f:

journalctl -f

Фильтрация логов

У утилиты journalctl есть опции, с помощью которых можно осуществлять фильтрацию логов и быстро извлекать из них нужную информацию.

С помощью опции -b можно просмотреть все логи, собранные с момента последней загрузки системы:

journalctl -b

Команда, которая показывает нам список всех загрузок системы

journalctl --list-boots
 0 3f92ddec48a747b6b596ab8006463935 Ср 2020-12-09 09:57:04 MSK—Ср 2020-12-09 10:14:14 MSK

Здесь мы получаем порядковый номер загрузки (0 — текущая, -1 – предыдущая и т. д.), ID загрузки и информацию о времени. Используя порядковый номер или ID можно обращаться к конкретному логу с помощью ключа -b

journalctl -b 3f92ddec48a747b6b596ab8006463935
journalctl -b -3

Обратившись к логу, мы получаем всё его содержимое. Для удобства можно отфильтровать данные.

Выборка по имени юнита

Можно указывать конкретный юнит, сообщения которого интересуют. Например, получить все сообщения от юнита </html>httpd</html>

journalctl -u httpd.service

Либо получить сообщения из лога сразу от двух юнитов httpd и mariadb.service:

journalctl -u httpd.service -u mariadb.service

.service в имени юнитов можно не дописывать. Команда ниже даст аналогичный предыдущей результат:

journalctl -u httpd -u mariadb

Выборка по номеру PID, UID, GID, по пути к бинарнику

Информацию из журнала можно выбрать по id пользователя или группы в системе, либо по номеру процесса. Для начала посмотрим у каких PID, UID и GID в журнале есть записи, сделать это можно командой journalctl -F

journalctl -F _UID # По пользователям
journalctl -F _PID # По процессам
journalctl -F _GID # По группам

Допустим хотим получить все события по определенному пользователю. Определяем id пользователя:

id -u www-data
33

И посмотрим, что есть в журналах от него

journalctl _UID=33

Просмотр сообщений ядра

Для просмотра сообщений ядра используется опция -k или −−dmesg:

journalctl -k

Приведённая команда покажет все сообщения ядра для текущей загрузки. Чтобы просмотреть сообщения ядра для предыдущих сессий, нужно воспользоваться опцией -b и указать один из идентификаторов сессии (порядковый номер в списке или ID):

journalctl -k -b -2
journalctl --dmesg -b 3f92ddec48a747b6b596ab8006463935

Фильтрация сообщений по уровню ошибки

Во время диагностики и исправления неполадок в системе нередко требуется просмотреть логи и выяснить, есть ли в них сообщения о критических ошибках. Специально для этого в journalctl предусмотрена возможность фильтрации по уровню ошибки. Просмотреть сообщения обо всех ошибках, имевших место в системе, можно с помощью опции -p:

journalctl -p err -b

Приведённая команда покажет все сообщения об ошибках, имевших место в системе.

Эти сообщения можно фильтровать по уровню. В journal используется такая же классификация уровней ошибок, как и в syslog:

  • 0 EMERG – система неработоспособна;
  • 1 ALERT – требуется немедленное вмешательство;
  • 2 CRIT – критическое состояние;
  • 3 ERR – ошибка;
  • 4 WARNING – предупреждение;
  • 5 NOTICE – всё нормально, но следует обратить внимание;
  • 6 INFO – информационное сообщение;
  • 7 DEBUG – отложенная печать.

Коды уровней ошибок указываются после опции -p.

Запись логов в стандартный вывод

По умолчанию journalctl использует для вывода сообщений логов внешнюю утилиту less. В этом случае к ним невозможно применять стандартные утилиты для обработки текстовых данных (например, grep). Эта проблема легко решается: достаточно воспользоваться опцией −−no-pager, и все сообщения будут записываться в стандартный вывод:

journalctl --no-pager

После этого их можно будет передать другим утилитам для дальнейшей обработки или сохранить в текстовом файле.

Выбор формата вывода

С помощью опции </html>-o</html> можно преобразовывать данные логов в различные форматы, что облегчает их парсинг и дальнейшую обработку, например:

 journalctl  -u mariadb -o json
{ "__CURSOR" : "s=3c5ff45f27e14e4eb7349323785e0c45;i=75d;b=6a3e7320eac84ce5a93f282b0bdbdf7>
...

Объект json можно представить в более структурированном и человеко понятном виде, указав формат json-pretty или json-sse:

journalctl  -u mariadb -o json-pretty
{
        "__CURSOR" : "s=3c5ff45f27e14e4eb7349323785e0c45;i=75d;b=6a3e7320eac84ce5a93f282b0>
        "__REALTIME_TIMESTAMP" : "1605185473186599",
        "__MONOTONIC_TIMESTAMP" : "2103867758",
        "_BOOT_ID" : "6a3e7320eac84ce5a93f282b0bdbdf76",
        "PRIORITY" : "6",
        "SYSLOG_FACILITY" : "3",
        "_MACHINE_ID" : "e5bb3e2f53034c18927895e618d60ff3",
        ...
}

Помимо JSON данные логов могут быть преобразованы в следующие форматы:

  • cat – только сообщения из логов без служебных полей;
  • export – бинарный формат, подходит для экспорта или резервного копирования логов;
  • short – формат вывода syslog;
  • short-iso – формат вывода syslog с метками времени в формате ISO 8601;
  • short-monotonic – формат вывода syslog c метками монотонного времени (monotonic timestamp);
  • short-precise – формат вывода syslog с метками точного времени (время событий указывается с точностью до микросекунд);
  • verbose – максимально подробный формат представления данных (включает даже те поля, которые в других форматах не отображаются).

Фильтрация по временным отрезкам

В journalctl имеется также возможность просмотра логов за определённые периоды времени. Для этого используются опции --since и --until. Предположим, нам нужно просмотреть логи начиная с 19:30 15 апреля 2020 года. Для этого выполнить команду используя формат даты YYYY-MM-DD HH:MM:SS

journalctl --since "2020-04-15 19:30:00"

Если с опцией --since не будет указано никакой даты, на консоль будут выведены логи начиная с текущей даты. Если дата указана, но при этом не указано время, будет применено значений времени по умолчанию — «00:00:00». Секунды также указывать необязательно (в этом случае применяется значение по умолчанию — 00).

Можно использовать вот такие конструкции:

journalctl ---since yesterday
journalctl --since 09:00 --until now
journalctl --since 10:00 --until "1 hour ago"
journald.txt · Последнее изменение: 2020/12/09 12:02 — 82.204.251.18