Одни из самых убедительных преимуществ systemd - это протоколирование процессов и систем. При использовании других инструментов журналы обычно разбросаны по всей системе, обрабатываются различными демонами и процессами и могут быть довольно сложными для интерпретации, когда они охватывают несколько приложений. systemd пытается решить эти проблемы, предоставляя централизованное решение для управления журналами всех процессов ядра и пользовательского пространства. Система, которая собирает и управляет этими журналами, известна как журнал.
Журнал реализуется с помощью демона journald, который обрабатывает все сообщения, создаваемые ядром, initrd, службами и т. д. В этом руководстве мы рассмотрим, как использовать утилиту journalctl, с помощью которой можно получить доступ к данным, хранящимся в журнале, и манипулировать ими.
Общая идея
Одним из стимулов создания журнала systemd является централизованное управление журналами, независимо от того, откуда они поступают. Поскольку большая часть управления процессом загрузки и службами осуществляется процессом systemd, имеет смысл стандартизировать способ сбора и доступа к журналам. Демон journald собирает данные из всех доступных источников и хранит их в двоичном формате для удобного и динамического манипулирования.
Это дает нам ряд существенных преимуществ. Взаимодействуя с данными с помощью одной утилиты, администраторы могут динамически отображать данные журнала в соответствии со своими потребностями. Это может быть просто просмотр данных о загрузке, произошедшей три загрузки назад, или последовательное объединение записей журнала от двух связанных служб для отладки проблемы взаимодействия.
Хранение данных журнала в двоичном формате также означает, что их можно выводить в произвольных форматах в зависимости от того, что вам нужно в данный момент. Например, для ежедневного управления журналами вы можете привыкнуть просматривать их в стандартном формате syslog, но если впоследствии вы решите построить график прерываний сервиса, вы можете вывести каждую запись в виде объекта JSON, чтобы сделать ее пригодной для использования в службе построения графиков. Поскольку данные не записываются на диск в виде обычного текста, не нужно преобразовывать их, если вам нужен другой формат по требованию.
Журнал systemd можно использовать вместе с существующей реализацией syslog или заменить им функциональность syslog, в зависимости от ваших потребностей. Хотя журнал systemd удовлетворит большинство потребностей администраторов в ведении журналов, он также может дополнить существующие механизмы ведения журналов. Например, у вас может быть централизованный сервер syslog, который вы используете для сбора данных с нескольких серверов, но вы также можете захотеть перемежать журналы от нескольких служб в одной системе с помощью журнала systemd. Вы можете сделать и то, и другое, объединив эти технологии.
Установка системного времени
Одним из преимуществ использования двоичного журнала для ведения журнала является возможность просмотра записей журнала в UTC или по местному времени по своему усмотрению. По умолчанию systemd отображает результаты по местному времени.
Поэтому, прежде чем начать работу с журналом, мы убедимся, что часовой пояс настроен правильно. В комплект systemd входит инструмент timedatectl, который может помочь в этом.
Сначала посмотрите, какие часовые пояса доступны, с помощью опции list-timezones:
1 | timedatectl list-timezones |
В результате вы получите список часовых поясов, доступных в вашей системе. Когда вы найдете тот, который соответствует местоположению вашего сервера, вы можете установить его с помощью опции set-timezone:
1 | sudo timedatectl set-timezone zone |
Чтобы убедиться, что на вашем компьютере сейчас правильное время, используйте команду timedatectl отдельно или с опцией status. Отображение будет одинаковым:
1 | timedatectl status |
В первой строке должно отображаться правильное время.
Базовый просмотр журналов
Чтобы просмотреть журналы, которые собрал демон journald, используйте команду journalctl.
При ее использовании каждая запись журнала, находящаяся в системе, будет отображена на странице (обычно меньше), которую вы сможете просмотреть. Самые старые записи будут находиться вверху:
1 | journalctl |
Скорее всего, вам придется пролистывать страницы и страницы данных, которые могут состоять из десятков или сотен тысяч строк, если systemd работает в вашей системе уже долгое время. Это демонстрирует, как много данных доступно в базе данных журнала.
Формат будет знаком тем, кто привык к стандартному журналу syslog. Однако на самом деле здесь собраны данные из большего количества источников, чем это возможно в традиционных реализациях syslog. Он включает в себя журналы процесса начальной загрузки, ядра, initrd, стандартных ошибок и выходов приложений. Все они доступны в журнале.
Вы можете заметить, что все отображаемые временные метки - это местное время. Это доступно для каждой записи журнала теперь, когда мы правильно установили местное время в нашей системе. Все журналы отображаются с использованием этой новой информации.
Если вы хотите отображать временные метки в UTC, вы можете использовать флаг --utc:
1 | journalctl --utc |
Фильтрация журналов по времени
Хотя доступ к такой большой коллекции данных, безусловно, полезен, такой объем информации может быть трудно или невозможно проверять и обрабатывать вручную. Поэтому одной из важнейших функций journalctl являются возможности фильтрации.
Отображение журналов текущей загрузки
Самым основным из них, который вы можете использовать ежедневно, является флаг -b. Он покажет вам все записи журнала, которые были собраны с момента последней перезагрузки.
1 | journalctl -b |
Это поможет вам определить и управлять информацией, относящейся к вашей текущей среде.
В тех случаях, когда вы не используете эту функцию и отображаете более одного дня загрузки, вы увидите, что journalctl вставил строку, которая выглядит следующим образом, когда система была отключена:
1 | -- Reboot -- |
Это может быть использовано для логического разделения информации по сессиям загрузки.
Прошлые загрузки
Хотя обычно требуется отображать информацию о текущей загрузке, бывают случаи, когда полезными оказываются и прошлые загрузки. Журнал может сохранять информацию о многих предыдущих загрузках, поэтому journalctl можно заставить легко отображать информацию.
В некоторых дистрибутивах сохранение информации о предыдущих загрузках включено по умолчанию, в других эта функция отключена. Чтобы включить сохранение информации о предыдущих загрузках, вы можете создать каталог для хранения журнала, набрав
1 | sudo mkdir -p /var/log/journal |
Или вы можете отредактировать файл конфигурации журнала:
1 | sudo nano /etc/systemd/journald.conf |
В разделе [Journal] установите для параметра Storage= значение "persistent", чтобы включить постоянное ведение журнала:
1 2 | [Journal] Storage=persistent |
Если на вашем сервере включено сохранение предыдущих ботов, journalctl предоставляет несколько команд, которые помогут вам работать с ботами как с единицей разделения. Чтобы увидеть боты, о которых знает journald, используйте опцию --list-boots в journalctl:
1 | journalctl --list-boots |
Это выведет строку для каждого бута. Первый столбец - это смещение загрузки, которое можно использовать для удобного обращения к загрузке с помощью journalctl. Если вам нужна абсолютная ссылка, идентификатор загрузки находится во втором столбце. Время, к которому относится сессия загрузки, можно определить по двум временным характеристикам, указанным в конце.
Чтобы отобразить информацию из этих загрузок, вы можете использовать информацию из первого или второго столбца.
Например, чтобы увидеть журнал предыдущей загрузки, используйте относительный указатель -1 с флагом -b:
1 | journalctl -b -1 |
Вы также можете использовать идентификатор загрузки для повторного вызова данных из загрузки:
1 | journalctl -b 72c7f68e9e934f46a1b45fb03f36de8e |
Окна времени
Хотя просмотр записей журнала по загрузке невероятно полезен, часто вам может понадобиться запросить временные окна, которые не совпадают с загрузкой системы. Это особенно актуально при работе с серверами с длительным временем работы.
Вы можете фильтровать по произвольным временным ограничениям с помощью опций --since и --until, которые ограничивают отображаемые записи записями после или до заданного времени, соответственно.
Значения времени могут быть представлены в различных форматах. Для абсолютных значений времени следует использовать следующий формат:
1 | YYYY-MM-DD HH:MM:SS |
Например, мы можем увидеть все записи с 10 января 2024 года в 17:15, набрав
1 | journalctl --since "2024-01-10 17:15:00" |
Если компоненты приведенного выше формата не указаны, будут применены некоторые значения по умолчанию. Например, если пропущена дата, будет принята текущая дата. Если пропущен компонент времени, то будет заменено "00:00:00" (полночь). Поле секунд также можно не указывать, чтобы по умолчанию было установлено значение "00":
1 | journalctl --since "2024-01-10" --until "2024-01-11 03:00" |
Журнал также понимает некоторые относительные значения и именованные сокращения. Например, вы можете использовать слова "вчера", "сегодня", "завтра" или "сейчас". Вы можете указывать относительное время, добавляя "-" или "+" к пронумерованному значению или используя слова типа "ago" в конструкции предложения.
Чтобы получить данные за вчерашний день, вы можете набрать
1 | journalctl --since yesterday |
Если вы получили сообщение о перерыве в обслуживании, начавшемся в 9:00 утра и продолжавшемся до часа назад, вы можете набрать:
1 | journalctl --since 09:00 --until "1 hour ago". |
Как видите, определить гибкие временные окна для фильтрации записей, которые вы хотите увидеть, довольно просто.
Фильтрация по интересам к сообщениям
Выше мы рассмотрели некоторые способы фильтрации данных журнала по временным ограничениям. В этом разделе мы обсудим, как фильтровать по интересующему вас сервису или компоненту. Журнал systemd предоставляет множество способов сделать это.
По компонентам
Возможно, самый полезный способ фильтрации - по интересующему вас подразделению. Мы можем использовать опцию -u для такой фильтрации.
Например, чтобы просмотреть все журналы от подразделения Nginx в нашей системе, мы можем набрать
journalctl -u nginx.service
Как правило, для отображения интересующих вас строк вы, вероятно, захотите отфильтровать их и по времени. Например, чтобы проверить, как служба работает сегодня, вы можете набрать:
journalctl -u nginx.service --since today
Этот тип фокусировки становится чрезвычайно полезным, когда вы используете способность журнала перемежать записи из разных блоков. Например, если ваш процесс Nginx подключен к модулю PHP-FPM для обработки динамического контента, вы можете объединить записи из обоих модулей в хронологическом порядке, указав оба модуля:
journalctl -u nginx.service -u php-fpm.service --since today
Это может значительно облегчить выявление взаимодействия между различными программами и отладку систем, а не отдельных процессов.
По идентификатору процесса, пользователя или группы
Некоторые службы порождают множество дочерних процессов для выполнения работы. Если вы выяснили точный PID интересующего вас процесса, вы можете отфильтровать его и по нему.
Для этого мы можем отфильтровать, указав поле _PID. Например, если интересующий нас PID равен 1234, мы можем набрать:
1 | journalctl _PID=1234 |
В других случаях вы можете захотеть показать все записи, зарегистрированные от определенного пользователя или группы. Это можно сделать с помощью фильтров _UID или _GID. Например, если ваш веб-сервер работает под пользователем www-data, вы можете найти идентификатор пользователя, набрав:
1 | id -u www-data |
После этого вы можете использовать полученный идентификатор для фильтрации результатов журнала:
1 | journalctl _UID=33 --since today |
Журнал systemd имеет множество полей, которые можно использовать для фильтрации. Некоторые из них передаются от регистрируемого процесса, а некоторые применяются journald, используя информацию, которую он собирает из системы во время ведения журнала.
Ведущее подчеркивание указывает на то, что поле _PID относится к последнему типу. Журнал автоматически записывает и индексирует PID процесса, который записывается в журнал, для последующей фильтрации. Вы можете узнать обо всех доступных полях журнала, набрав:
1 | man systemd.journal-fields |
Мы обсудим некоторые из них в этом руководстве. Пока же мы рассмотрим еще одну полезную опцию, связанную с фильтрацией по этим полям. Параметр -F можно использовать для отображения всех доступных значений для данного поля журнала.
Например, чтобы посмотреть, для каких идентификаторов групп в журнале systemd есть записи, вы можете набрать:
1 | journalctl -F _GID |
Это покажет вам все значения, которые журнал сохранил для поля ID группы. Это поможет вам создать фильтры.
По пути компонента
Мы также можем фильтровать, указывая путь.
Если путь ведет к исполняемому файлу, journalctl отобразит все записи, связанные с этим файлом. Например, чтобы найти записи, связанные с исполняемым файлом bash, вы можете ввести:
1 | journalctl /usr/bin/bash |
Обычно, если для исполняемого файла доступно подразделение, этот метод чище и предоставляет более полную информацию (записи из связанных дочерних процессов и т. д.). Однако иногда это невозможно.
Отображение сообщений ядра
Сообщения ядра, которые обычно содержатся в выводе dmesg, также могут быть получены из журнала.
Чтобы отобразить только эти сообщения, мы можем добавить флаги -k или --dmesg к нашей команде:
1 | journalctl -k |
По умолчанию будут отображаться сообщения ядра из текущей загрузки. Вы можете указать альтернативную загрузку, используя обычные флаги выбора загрузки, рассмотренные ранее. Например, чтобы получить сообщения от пяти загрузок назад, вы можете ввести:
1 | journalctl -k -b -5 |
По приоритету
Один из фильтров, который часто интересует системных администраторов, - это приоритет сообщения. Хотя часто бывает полезно записывать информацию в журнал на очень подробном уровне, при реальном анализе имеющейся информации журналы с низким приоритетом могут отвлекать и сбивать с толку.
Вы можете использовать journalctl для отображения только сообщений с указанным приоритетом или выше, используя опцию -p. Это позволяет отфильтровать сообщения с более низким приоритетом.
Например, чтобы показать только записи, зарегистрированные на уровне ошибки или выше, вы можете набрать:
1 | journalctl -p err -b |
В результате будут показаны все сообщения, помеченные как ошибка, критическое, предупреждение или аварийное. Журнал реализует стандартные уровни сообщений syslog. Вы можете использовать как имя приоритета, так и соответствующее ему числовое значение. В порядке от высшего к низшему приоритету они следующие:
- 0: emerg
- 1: alert
- 2: crit
- 3: err
- 4: warning
- 5: notice
- 6: info
- 7: debug
Приведенные выше числа или имена можно использовать как взаимозаменяемые с опцией -p. При выборе приоритета будут отображаться сообщения, помеченные на указанном уровне и выше.
Изменение отображения журнала
Выше мы продемонстрировали выбор записей с помощью фильтрации. Однако есть и другие способы изменить вывод. Мы можем настроить отображение journalctl в соответствии с различными потребностями.
Усечение или расширение вывода
Мы можем настроить отображение данных в journalctl, указав ему сжимать или расширять вывод.
По умолчанию journalctl отображает всю запись в пейджере, позволяя записям уходить в правую часть экрана. Доступ к этой информации можно получить, нажав клавишу со стрелкой вправо.
Если вы предпочитаете, чтобы вывод был усеченным, вставляя многоточие там, где информация была удалена, вы можете использовать опцию --no-full:
1 | journalctl --no-full |
Вы также можете пойти в обратном направлении и указать journalctl отображать всю информацию, независимо от того, содержит ли она непечатаемые символы. Это можно сделать с помощью флага -a:
1 | journalctl -a |
Вывод в стандартный выход
По умолчанию journalctl выводит данные в виде странц для удобства восприятия. Однако если вы планируете обрабатывать данные с помощью инструментов для работы с текстом, вам, вероятно, захочется иметь возможность выводить данные в стандартный вывод.
Это можно сделать с помощью опции --no-pager:
1 | journalctl --no-pager |
В зависимости от ваших потребностей, этот вывод можно сразу направить в утилиту обработки или перенаправить в файл на диске.
Форматы вывода
Если вы обрабатываете записи в журнале, как уже говорилось выше, вам, скорее всего, будет легче разбирать данные, если они будут представлены в более удобном для использования формате. К счастью, журнал может быть выведен в различных форматах по мере необходимости. Для этого используется опция -o с указателем формата.
Например, вы можете вывести записи журнала в формате JSON, набрав:
1 | journalctl -b -u nginx -o json |
Это удобно для парсинга с помощью утилит. Вы можете использовать формат json-pretty, чтобы лучше разобраться со структурой данных перед передачей их потребителю JSON:
1 | journalctl -b -u nginx -o json-pretty |
Для отображения можно использовать следующие форматы:
- cat: Отображает только само поле сообщения.
- export: Бинарный формат, подходящий для передачи или резервного копирования.
- json: Стандартный JSON с одной записью в строке.
- json-pretty: JSON, отформатированный для лучшей читаемости человеком.
- json-sse: Вывод в формате JSON, обернутый для обеспечения совместимости с событиями, отправляемыми сервером.
- short: вывод в стиле syslog по умолчанию
- short-iso: Формат по умолчанию, дополненный для отображения временных меток ISO 8601.
- short-monotonic: Формат по умолчанию с монотонными временными метками.
- short-precise: Формат по умолчанию с микросекундной точностью.
- verbose: Показывает все поля журнала, доступные для записи, включая те, которые обычно скрыты внутри.
Эти опции позволяют отображать записи в журнале в том формате, который лучше всего соответствует вашим текущим потребностям.
Мониторинг активных процессов
Команда journalctl имитирует то, как многие администраторы используют tail для мониторинга активной или недавней активности. Эта функциональность встроена в journalctl, что позволяет вам получить доступ к этим функциям без необходимости подключаться к другому инструменту.
Отображение последних журналов
Чтобы отобразить определенное количество записей, вы можете использовать опцию -n, которая работает точно так же, как tail -n.
По умолчанию она отображает 10 последних записей:
1 | journalctl -n |
Вы можете указать количество записей, которые вы хотите увидеть, с помощью цифры после -n:
1 | journalctl -n 20 |
Слежение за журналами
Чтобы активно следить за журналами по мере их записи, вы можете использовать флаг -f. Опять же, это работает так, как вы ожидаете, если у вас есть опыт использования tail -f:
1 | journalctl -f |
Чтобы выйти из этой команды, введите CTRL+C.
Обслуживание журнала
Вам может быть интересно, сколько стоит хранение всех данных, которые мы видели до сих пор. Кроме того, вам может быть интересно очистить некоторые старые журналы и освободить место.
Определение текущего использования диска
Вы можете узнать, сколько места журнал занимает на диске в данный момент, используя флаг --disk-usage:
1 | journalctl --disk-usage |
Удаление старых журналов
Если вы хотите уменьшить размер журнала, вы можете сделать это двумя разными способами (доступны в systemd версии 218 и более поздних).
Если вы используете опцию --vacuum-size, вы можете уменьшить журнал, указав его размер. При этом старые записи будут удаляться до тех пор, пока общее пространство, занимаемое журналом на диске, не достигнет требуемого размера:
1 | sudo journalctl --vacuum-size=1G |
Другой способ сократить журнал - указать время отключения с помощью опции --vacuum-time. Любые записи по истечении этого времени будут удалены. Это позволяет сохранить записи, созданные после определенного времени.
Например, чтобы сохранить записи за последний год, вы можете ввести:
1 | sudo journalctl --vacuum-time=1years |
Ограничение объема журнала
Вы можете настроить свой сервер таким образом, чтобы он ограничивал объем занимаемого журналом пространства. Это можно сделать, отредактировав файл /etc/systemd/journald.conf.
1 | sudo nano /etc/systemd/journald.conf |
Следующие элементы могут быть использованы для ограничения роста журнала:
- SystemMaxUse- Определяет максимальное дисковое пространство, которое может быть использовано журналом в постоянном хранилище.
- SystemKeepFree - Указывает объем пространства, которое журнал должен оставлять свободным при добавлении записей журнала в постоянное хранилище.
- SystemMaxFileSize - Определяет, до какого размера могут вырасти отдельные файлы журнала в постоянном хранилище перед ротацией.
- RuntimeMaxUse - Определяет максимальное дисковое пространство, которое может быть использовано в энергонезависимом хранилище (в файловой системе /run).
- RuntimeKeepFree - Указывает объем пространства, которое должно быть отведено для других целей при записи данных в энергонезависимое хранилище (в файловой системе /run).
- RuntimeMaxFileSize - Определяет объем пространства, который отдельный файл журнала может занимать в энергонезависимом хранилище (в файловой системе /run) перед ротацией.
Задавая эти значения, вы можете контролировать, как journald потребляет и сохраняет пространство на вашем сервере. Помните, что SystemMaxFileSize и RuntimeMaxFileSize будут нацелены на архивированные файлы, чтобы достичь указанных пределов. Это важно помнить при интерпретации количества файлов после операции вакуумирования.
Заключение
Как видите, журнал systemd невероятно полезен для сбора и управления данными системы и приложений. Большая часть гибкости достигается благодаря обширным метаданным, автоматически записываемым в журнал, и централизованному характеру журнала. Команда journalctl позволяет легко воспользоваться расширенными возможностями журнала и провести обширный анализ и реляционную отладку различных компонентов приложения.