• База знаний
  • /
  • Блог
  • /
  • Wiki
  • /
  • ONLINE CHAT
+380 (44) 364 05 71

Статья также доступна на украинском (перейти к просмотру).

Как разбирать логи в Linux: journalctl, grep, awk и sed

Содержание:

Одной из лучших возможностей systemd в Linux есть централизованное журналирование всех процессов и событий, возникающих при работе системы. При этом объем журналов может быть достаточно значительным, что требует умения правильно ими пользоваться. Системная утилита journalctl для доступа к данным журнальной службы systemd дает возможность реализовать любой запрос на выборку данных с помощью набора параметров для ее запуска. Рассмотрим способы ее использования на практических примерах, реализуемых на VPS-сервере Debian 12.

Как работает журнальная служба в systemd

Журналирование в systemd является альтернативным или дополнительным средством фиксации событий по сравнению со стандартом syslog. Одной из главных его задач является централизованный сбор данных независимо от типа источника поступления сообщения. Журналирование реализовано в виде даемона journald. Он принимает уведомления от всех служб, initrd и ядра системы, после чего данные вносятся в соответствующие журналы.

В отличие от syslog, данные журналов systemd хранятся только в двоичном формате. Это позволяет получить их независимость как от источника сообщения, так и от формы вывода, что удобно с точки зрения администрирования. Например, данные могут быть выведены в следующих форматах:

  • Json;

  • Json-sse – Jsonв оболочке, совместимой с операцией add sse(server-sent event);

  • Json-pretty – структурированный Json;

  • Export – движковый формат, может использоваться для экспорта данных;

  • Short – формат syslog, установлен по умолчанию;

  • Verbose – вывод значений всех полей журнальной системы.

Утилита journalctl обеспечивает выполнение запросов на отображение сообщений в одном из указанных форматов и позволяет производить фильтрацию вывода по следующим критериям:

  • По времени;

  • По степени важности сообщений;

  • За счет изменения формата отображения.

Ниже будет рассмотрена работа утилиты для каждого из указанных критериев.

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

В случае, если утилита используется без параметров, все записи журналов выводятся в многостраничном списке. По умолчанию записи сортируются сверху вниз, то есть самые старые находятся сверху, а новые снизу.

Продемонстрируем это. Введем в терминале:

$ journalctl

Если же нужно учесть время работы системы, то здесь можно опираться на следующие временные ориентиры или указатели:

  • Период работы системы при текущем сеансе загрузки;

  • Временные периоды предварительных загрузок;

  • Определены промежутки времени.

Рассмотрим каждый из вариантов.

Период текущего сеанса

В этом случае весь вывод из журналов будет касаться только текущего сеанса работы с системой или загрузки. Для этого используется параметр -b.

Выведем в терминале записи текущей загрузки:

$ journalctl -b

Предыдущие сеансы загрузки

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

Включим его. Для этого отредактируем файл конфигурации:

$ sudo nano /etc/systemd/journald.conf

Введем следующее значение параметра Storage::

[Journal]
Storage=persistent

Сохраним внесенные изменения и выйдем из редактора (Ctrl+X).

После этого станет возможным работать с данными сеансов предварительных загрузок, как с отдельными единицами. Для этого предусмотрен ряд команд.

К примеру, просмотрим список всех доступных journald сеансов предварительных загрузок. Для этого введем в терминале:

$ journalctl --list-boots

Здесь каждая запись соответствует отдельному сеансу загрузки. В первом столбце указаны относительные идентификаторы сеансов, во втором – абсолютные.

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

$ journalctl -b -3

Также мы могли бы указать и абсолютный идентификатор того же сеанса:

$ journalctl -b c141d403dd4d4d59b5c8d20f76cd5d75

Результат был бы прежним.

Определены промежутки времени

Мы можем указать любой промежуток времени, за который нас интересуют записи журналов. Только необходимо учитывать временные форматы.

Да, для абсолютных значений времени следует использовать следующий формат:

YYYY-MM-DD HH:MM:SS

Для примера, просмотрим все записи, начиная с 1 февраля 2025 г. 16:12 и по настоящее время:

$ Journalctl --since "2025-02-01 16:12:00"

В качестве еще одного временного формата можно использовать англоязычные названия временных единиц. Их можно указать вместе с опцией --с. К примеру, просмотрим сегодняшние записи:

$ journalctl --since today

Воспользуемся рассматриваемыми возможностями для разрешения более сложной ситуации. Например, мы получили отчеты о сбоях в работе службы, которые начались в 10:00 и закончились 3 часа назад. В этом случае нам поможет следующая команда:

$ journalctl --since 10:00 --until "3 hour ago"

Так же можно решить любую задачу, связанную с определенным временным промежутком.

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

В этом случае можно выделить несколько основных указателей, по которым можно производить выборку данных:

  • По идентификатору процесса/группы/пользователя;

  • По программным единицам;

  • По приоритету.Рассмотрим процесс использования каждого критерия.

По идентификатору

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

Продемонстрируем это. Но перед этим просмотрим идентификаторы имеющихся в системе процессов с помощью следующей команды:

$ ps -a

Предположим, нас интересует процесс proxmox-datacen (PID=32966).

Просмотрим соответствующие записи журналов:

$ journalctl _PID=32966

Мы также можем просмотреть все доступные поля журнала для использования их в качестве фильтрующих. Для этого введем в терминале:

$ man systemd.journal-fields

Для того чтобы вывести записи того или иного поля журнальной системы, необходимо воспользоваться опцией -F.

Для примера, рассмотрим для каких идентификаторов групп существуют записи в журнальной системе systemd. Для этого воспользуемся следующей командой:

$ journalctl -F _GID

Итак, именно для выведенных номеров групп ведутся записи в журнальной системе systemd.

По программным единицам

Это один из самых полезных вариантов фильтрации сообщений. Для его «включения» следует указать опцию -u в команде.

К примеру, просмотрим все журналы программной единицы exim4 в нашей системе. Exim4 является агентом пересылки почтовых сообщений, или SMTP-сервером.

Введем в терминале:

$ journalctl -u exim4.service

Также можно просмотреть информацию о любой запущенной программе или службе.

По приоритету

Очень часто возникает необходимость вывести записи с учетом уровня приоритетности. Это позволяет избавиться от излишней информации и сконцентрироваться только на главном вопросе. Для этого предусмотрено наличие опции -p. При ее применении будут выведены сообщения с указанным или более высоким приоритетом.

Например, выведем только те сообщения, которые имеют уровень critical (критическая ошибка) или выше. Введем в терминале:

$ journalctl -p crit -b

В журнальной системе systemd реализованы стандартные уровни ошибок, равно как и в syslog. В команде можно указывать как числовое значение ошибки, так и текстовое.

  • 0 - аварийный

  • 1 - оповещение

  • 2 - крит

  • 3 - ошибка

  • 4 - предупреждение

  • 5 - уведомление

  • 6 - информация

  • 7 - отладка

Да, вместо слова critical мы могли бы указать значение 3. Результат был бы тот же.

Изменение формата отображения или вывода данных

За счет изменения форматов отображения и/или вывода записей журналов можно получить удобный инструмент для манипулирования данными. Можно выделить три основных направления:

  • Урезание/расширение данных;

  • Смена вывода на «стандартный»;

  • Изменение формата вывода.

Урезание/расширение данных. К примеру, если мы хотим получить усеченный вывод, при котором на месте сокращенной информации будут проставлены точки, то необходимо использовать опцию --нет-полный:

$ journalctl --no-full

И наоборот, если нам нужно вывести все данные, не скрывая их, нужно воспользоваться опцией –a:

$ journalctl -a

В таком случае будут выведены абсолютно все символы, включая и непечатаемые.

Смена вывода на «стандартный». По умолчанию утилита выводит данные на многостраничной панели. Однако мы можем отразить их все вместе, то есть обеспечить их «стандартный» вывод. Это можно сделать с помощью опции --no-pager:

$ journalctl --no-pager

Выведенные записи можно сразу передать в текстовый редактор или сохранить в виде файла на диске.

Изменение формата вывода. Как уже отмечалось ранее, система журналирования systemd использует двоичный формат для хранения данных, что позволяет выводить их в разных форматах без дополнительных преобразований. Для изменения формата следует указать опцию - в команде.

Например, выведем записи службы exim4 в формате Json:

$ journalctl -b -u exim4 -o json

Можно убедиться, что данные выводятся в нужном формате. Однако если мы планируем в дальнейшем использовать их для проведения синтаксического анализа, то целесообразно сделать структуру данных проще. Сделаем это, изменив формат на json-pretty:

$ journalctl -b -u exim4 -o json-pretty

Теперь мы получили то, что хотели – данные приведены в порядок и готовы к дальнейшей обработке любой утилитой для проведения синтаксического анализа.

Использование grep и awk для фильтрации записей

Попробуем отфильтровать сообщения для службы exim4, имеющие статус ошибки. Это можно сделать с помощью следующей команды:

$ journalctl -u exim4.service | grep -i "error"

Опция -i здесь использована для того, чтобы включить принудительное игнорирование регистра символов при написании слова ошибка.

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

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

$ journalctl -u exim4.service | awk '{print $3, $6}'

Можно убедиться, что мы получили то, что хотели.

Если нам нужно собрать записи об ошибках за последние 10 часов в отдельном файле с именем exim4_errors.log, то команда будет выглядеть следующим образом:

$ journalctl -u exim4.service --since "10 hour ago" | grep -i "error" | awk '{print $3, $6}' > /var/log/exim4_errors.log

Уборка журналов

Содержимое журналов можно оптимизировать за счет уборки ненужных нам символов или тегов. Например, удалим информацию, которая находится в скобках []. Это можно сделать с помощью потокового редактора sed:

$ journalctl -u exim4.service | sed 's/\[.*\]//g'

Можно убедиться, что излишняя информация удалена.

Подписывайтесь на наш телеграмм-канал https://t.me/freehostua, чтобы быть в курсе новых полезных материалов

Смотрите наш канал Youtube на https://www.youtube.com/freehostua.

Мы в чем ошиблись, или что-то пропустили?

Напишите об этом в комментариях, мы с удовольствием ответим и обсуждаем Ваши замечания и предложения.

Быстрый и доступный vps хостинг от дата-центра FREEhost.UA это удобная панель управления, выгодные цены и круглосуточная техническая поддержка, а также большой выбор шаблонов, по которым можно автоматически создать сервер, бесплатную панель управления и 60 GB на сервере резервных копий.

Дата: 18.02.2025
Автор: Александр Ровник
Голосование

Авторам статьи важно Ваше мнение. Будем рады его обсудить с Вами:

comments powered by Disqus
navigate
go
exit
Спасибо, что выбираете FREEhost.UA