Управление логгированием в systemd

от автора

Systemd Journal

Демон инициализации systemd де-факто уже стал стандартом в современных Linux-системах. На него перешли многие популярные дистрибутивы: Debian, RHEL/CentOS, Ubuntu (начиная с версии 15.04). В systemd используется принципиально иной (по сравнению с традиционным инструментом syslog) подход к логгированию.
В его основе лежит централизация: специализированный компонент journal cобирает все системные сообщения (сообщения ядра, различных служб и приложений). При этом специально настраивать отправку логов не нужно: приложения могут просто писать в stdout и stderr, a journal сохранит эти сообщения автоматически. Работа в таком режиме возможна и с Upstart, но он сохраняет все логи в отдельный файл, тогда как systemd сохраняет их в бинарной базе, что существенно упрощает  систематизацию и поиск.

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

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

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

 $ timedatectl list-timezones 

Установка нужного часового пояса осуществляется так:

 $ timedatectl set-timezone <часовой пояс> 

По завершении установки будет нелишним убедиться в том, что всё сделано правильно:

 $ timedatectl status Local time: Thu 2015-07-30 11:24:15 MSK Universal time: Thu 2015-07-30 08:24:15 UTC RTC time: Thu 2015-07-30 08:24:15 Time zone: Europe/Moscow (MSK, +0300) NTP enabled: no NTP synchronized: no RTC in local TZ: no DST active: n/a 

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

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

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

  -- Logs begin at Wed 2015-07-29 17:12:48 MSK, end at Thu 2015-07-30 11:24:15 MSK. -- Jul 29 17:12:48 host-10-13-37-10 systemd-journal[181]: Runtime journal is using 4.0M (max allowed 20.0M, trying to leave 30.0M free of 195.9M available → current limit 20.0M). Jul 29 17:12:48 host-10-13-37-10 systemd-journal[181]: Runtime journal is using 4.0M (max allowed 20.0M, trying to leave 30.0M free of 195.9M available → current limit 20.0M). Jul 29 17:12:48 host-10-13-37-10 kernel: Initializing cgroup subsys cpuset Jul 29 17:12:48 host-10-13-37-10 kernel: Initializing cgroup subsys cpu Jul 29 17:12:48 host-10-13-37-10 kernel: Initializing cgroup subsys cpuacct Jul 29 17:12:48 host-10-13-37-10 kernel: Linux version 3.16.0-4-amd64 (debian-kernel@lists.debian.org) (gcc version 4.8.4 (Debian 4.8.4-1) ) #1 SMP Debian 3.16.7-ckt11-1+deb8u2 (2015-07-17) Jul 29 17:12:48 host-10-13-37-10 kernel: Command line: BOOT_IMAGE=/boot/vmlinuz-3.16.0-4-amd64 root=UUID=b67ea972-1877-4c5b-a328-29fc0d6c7bc4 ro console=tty1 console=ttyS0 video=640x480 consoleblank=0 panic=15 c 

Здесь мы привели лишь небольшой его фрагмент; на самом деле он включает гигантское количество записей.

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

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

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

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

 $ journalctl -b 

Просмотр логов предыдущих сессий

С помощью journalctl можно просматривать информацию о предыдущих сессиях работы в системе — в некоторых случаях это бывает полезным.
Следует, однако, учитывать, что сохранение информации о предыдущих сессиях поддерживается по умолчанию не во всех дистрибутивах Linux. Иногда его требуется активировать

Для этого нужно открыть конфигурационный файл journald.conf, найти в нём раздел [Journal] и изменить значение параметра storage на persistent:

 $ sudo nano /etc/systemd/journald.conf ... [Journal] Storage=persistent 

Просмотреть список предыдущих загрузок можно с помощью команды:

 $ journalctl --list-boots  0 9346310348bc4edea250555dc046b30c Thu 2015-07-30 12:39:49 MSK—Thu 2015-07-30 12:39:59 MSK 

Её вывод состоит из четырёх колонок. В первой из них указывается порядковый номер загрузки, во второй — её ID, в третьей — дата и время. Чтобы просмотреть лог для конкретной загрузки, можно использовать идентификаторы как из первой, так и из второй колонки:

 $ journalctl -b 0 

или

 $ journalctl -b 9346310348bc4edea250555dc046b30c 

Фильтрация по дате и времени

В journalctl имеется также возможность просмотра логов за определённые периоды времени. Для этого используются опции —since и —until. Предположим, нам нужно просмотреть логи начиная с 17 часов 15 минут 20 июля 2015 года. Для этого потребуется будет выполнить команду:

 $ journalctl --since "2015-07-20 17:15:00" 

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

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

 $ journalctl ---since yesterday $ journalctl --since 09:00 --until now $ journalctl --since 10:00 --until "1 hour ago" 

Фильтрация по приложениям и службам

Для просмотра логов конкретного приложения или службы используется опция -u, например:

 $ journalctl -u nginx.service 

Приведённая команда выведет на консоль логи веб-сервера nginx.
Нередко возникает необходимость просмотреть логи какой-либо службы за определённый период времени. Это можно сделать при помощи команды вида:

 $ journalctl -u nginx.service --since yesterday 

C опцией -u также используется фильтрация по дате и времени, например:

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

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

Фильтрация по процессам, пользователям и группам

Просмотреть логи для какого-либо процесса можно, указав в команде journalctl его идентификационный номер (PID), например:

 $ journalctl _PID=381 

Для просмотра логов процессов, запущенных от имени определённого пользователя или группы, используются фильтры _UID и _GID соответственно. Предположим, у нас имеется веб-сервер, запущенный от имени пользователя www-data. Определим сначала ID этого пользователя:

 $id -u www-data  33 

Теперь можно просмотреть логи всех процессов, запущенных от имени этого пользователя:

 $ journalctl _UID=33 

Вывести на консоль список пользователей, о которых имеются записи в логах, можно так:

 $ journalctl -F _UID 

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

 $ journalctl -F _GUID 

С командной journalctl можно использовать и другие фильтры. Просмотреть список всех доступных фильтров можно, выполнив команду

 $ man systemd.journal-fields 

Фильтрация по пути

Просмотреть логи для какого-либо процесса также можно, указав путь к нему, например:

 $ journalctl /usr/bin/docker 

Иногда таким способом можно получить более подробную информацию (например, просмотреть записи для всех дочерних процессов).

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

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

 $ journalctl -k 

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

 $ journalctl -k -b -2 

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

Во время диагностики и исправления неполадок в системе нередко требуется просмотреть логи и выяснить, есть ли в них сообщения о критических ошибках. Специально для этого в 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 

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

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

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

 $ journalctl  -u nginx.service -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" } 

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

 $ journalctl -u nginx.service -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" } 

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

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

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

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

 $ journalctl -n 

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

 $ journalctl -n 20 

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

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

 $ journalctl -f  

Управление логгированием

Определение текущего объёма логов

Со временем объём логов растёт, и они занимают всё больше места на жёстком диске. Узнать объём имеющихся на текущий момент логов можно с помощью команды:

 $ journalctl --disk-usage Journals take up 16.0M on disk. 

Ротация логов

Настройка ротации логов осуществляется с помощью опций −−vacuum-size и −−vacuum-time.
Первая из них устанавливает предельно допустимый размер для хранимых на диске логов (в нашем примере — 1 ГБ):

 $ sudo journalctl --vacuum-size=1G 

Как только объём логов превысит указанную цифру, лишние файлы будут автоматические удалены.
Аналогичным образом работает опция −−vacuum-time. Она устанавливает для логов срок хранения, по истечении которого они будут автоматически удалены:

 $ sudo journalctl --vacuum-time=1years 

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

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

  • SystemMaxUse= максимальный объём, который логи могут занимать на диске;
  • SystemKeepFree= объём свободного места, которое должно оставаться на диске после сохранения логов;
  • SystemMaxFileSize= объём файла лога, по достижении которого он должен быть удален с диска;
  • RuntimeMaxUse= максимальный объём, который логи могут занимать в файловой системе /run;
  • RuntimeKeepFree= объём свободного места, которое должно оставаться в файловой системе /run после сохранения логов;
  • RuntimeMaxFileSize= объём файла лога, по достижении которого он должен быть удален из файловой системы /run.
  • Как видно из проделанного рассмотрения, systemd journal представляет собой гибкий и удобный инструмент для сбора системных данных и данных приложений. Высокого уровня гибкости и удобства удалось добиться, во-первых, благодаря централизованному подходу к логгированию, а во-вторых — благодаря автоматической записи в логи подробных метаданных. С помощью journalctl можно просматривать логи, получая необходимую информацию для анализа работы и отладки различных системных компонентов.
    Если у вас есть вопросы и дополнения — добро пожаловать в комментарии. Разговор о systemd и его компонентах будет продолжен в следующих публикациях.

ссылка на оригинал статьи http://habrahabr.ru/post/264731/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *