company_banner

Использование journalctl для просмотра и анализа логов: подробный гайд

  • Tutorial


Journalctl — отличный инструмент для анализа логов, обычно один из первых с которым знакомятся начинающие администраторы linux систем. Встроенные возможности ротации, богатые возможности фильтрации и возможность просматривать логи всех systemd unit-сервисов одним инструментом очень удобны и заметно облегчают работу системным администраторам.

Эта статья рассматривает основные возможности утилиты journalctl и различные варианты ее применения. С помощью journalctl можно просматривать логи системы, чтобы решить возникшие проблемы на рабочей станции или сервере использующие дистрибутив linux с демоном инициализации systemd, де-факто уже ставшим стандартом в современных Linux-системах, например: RHEL, CentOS, Fedora, Debian и многих других.

Существует мнение, что systemd не так уж и хорош — он нагружает систему и это все еще предмет для споров на сегодняшний день, но нельзя отрицать, что он предоставляет прекрасный набор инструментов для управления системой и поиска проблем. Представьте, что вам приходится иметь дело с проблемным сервером, который даже не загружается — в таком случае можно загрузиться с live-дистрибутива, смонтировать системный раздел и просмотреть логи systemd, чтобы понять, в чем проблема.

Systemd


Systemd состоит из трех основных компонентов:

  • systemd — менеджер системы и сервисов
  • systemctl — утилита для просмотра и управление статусом сервисов
  • systemd-analyze — предоставляет статистику по процессу загрузки системы, проверяет корректность unit-файлов и так же имеет возможности отладки systemd

Journald


Journald — системный демон журналов systemd. Systemd спроектирован так, чтобы централизованно управлять системными логами от процессов, приложений и т.д. Все такие события обрабатываются демоном journald, он собирает логи со всей системы и сохраняет их в бинарных файлах.

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

Файлы логов journald могут собирать тысячи событий и они обновляются с каждым новым событием, поэтому если ваша Linux-система работает достаточно долго — размер файлов с логами может достигать несколько гигабайт и более. Поэтому анализ таких логов может происходить с задержками, в таком случае, при анализе логов можно фильтровать вывод, чтобы ускорить работу.

Файл конфигурации journald


Файл конфигурации можно найти по следующему пути: /etc/systemd/journald.conf, он содержит различные настройки journald, я бы не рекомендовал изменять этот файл, если вы точно не уверены в том, что делаете.

Каталог с журналом journald располагается /run/log/journal (в том случае, если не настроено постоянное хранение журналов, но об этом позже).

Файлы хранятся в бинарном формате, поэтому нормально их просмотреть с помощью cat или nano, как привыкли многие администраторы — не получится.

Использование journalctl для просмотра и анализа логов


Основная команда для просмотра:

# journalctl



Она выведет все записи из всех журналов, включая ошибки и предупреждения, начиная с того момента, когда система начала загружаться. Старые записи событий будут наверху, более новые — внизу, вы можете использовать PageUp и PageDown чтобы перемещаться по списку, Enter — чтобы пролистывать журнал построчно и Q — чтобы выйти.

По умолчанию journalctl выводит время событий согласно настроенного в вашей системе часового пояса, также journalctl позволяет просмотреть логи с временем UTC (в этом стандарте времени сохраняются события внутри файлов journald), для этого можно использовать команду:

# journalctl --utc

Фильтрация событий по важности


Система записывает события с различными уровнями важности, какие-то события могут быть предупреждением, которое можно проигнорировать, какие-то могут быть критическими ошибками. Если мы хотим просмотреть только ошибки, игнорируя другие сообщения, введем команду с указанием кода важности:
# journalctl -p 0

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

  • 0: emergency (неработоспособность системы)
  • 1: alerts (предупреждения, требующие немедленного вмешательства)
  • 2: critical (критическое состояние)
  • 3: errors (ошибки)
  • 4: warning (предупреждения)
  • 5: notice (уведомления)
  • 6: info (информационные сообщения)
  • 7: debug (отладочные сообщения)

Когда вы указываете код важности, journalctl выведет все сообщения с этим кодом и выше. Например если мы укажем опцию -p 2, journalctl покажет все сообщения с уровнями 2, 1 и 0.

Настройка хранения журналов


По умолчанию journald перезаписывает свои журналы логов при каждой перезагрузке, и вызов journalctl выведет журнал логов начиная с текущей загрузки системы.

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

Когда в конфигурационном файле /etc/systemd/journald.conf параметру Storage= задано значение auto) и каталога /var/log/journal/ не существует, журнал будет записываться в /run/log/journal без сохранения между перезагрузками, если /var/log/journal/ существует, журналы будут сохраняться в нем, на постоянной основе, но если каталог будет удален, systemd не пересоздаст его автоматически и вместо этого будет вести журнал снова в /run/systemd/journal без сохранения. Каталог может быть пересоздан в таком случае, если добавить Storage=persistent в journald.conf и перезапустить systemd-journald.service (или перезагрузиться).

Создадим каталог для хранения журналов, установим необходимые атрибуты и перезапустим службу:

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

Просмотр журналов загрузки


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

# journalctl --list-boots



Первый номер показывает номер журнала, который можно использовать для просмотра журнала определенной сессии. Второй номер boot ID так же можно использовать для просмотра отдельного журнала.

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

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

# journalctl -b 0

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

# journalctl -b -1

Просмотр журнала за определенный период времени


Journalctl позволяет использовать такие служебные слова как “yesterday” (вчера), “today” (сегодня), “tomorrow” (завтра), или “now” (сейчас).

Поэтому мы можем использовать опцию "--since" (с начала какого периода выводить журнал).

С определенной даты и времени:

# journalctl --since "2020-12-18 06:00:00"

С определенной даты и по определенное дату и время:

# journalctl --since "2020-12-17" --until "2020-12-18 10:00:00

Со вчерашнего дня:

# journalctl --since yesterday

С 9 утра и до момента, час назад:

# journalctl --since 09:00 --until "1 hour ago"

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


Чтобы просмотреть сообщения от ядра Linux за текущую загрузку, используйте команду с ключом -k:

# journalctl -k



Просмотр журнала логов для определенного сервиса systemd или приложения


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



# journalctl -u NetworkManager.service

Если нужно найти название сервиса, используйте команду:

# systemctl list-units --type=service

Так же можно просмотреть лог приложения, указав его исполняемый файл, например чтобы просмотреть все сообщения от nginx за сегодня, мы можем использовать команду:

# journalctl /usr/sbin/nginx --since today

Или указав конкретный PID:

# journalctl _PID=1

Дополнительные опции просмотра


Следить за появлением новых сообщений (аналог tail -f):

# journalctl -f

Открыть журнал «перемотав» его к последней записи:

# journalctl -e

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

journalctl --file /var/log/journal/e02689e50bc240f0bb545dd5940ac213/system.journal -f

По умолчанию journalctl отсекает части строк, которые не вписываются в экран по ширине, хотя иногда перенос строк может оказаться более предпочтительным. Управление этой возможностью производится посредством переменной окружения SYSTEMD_LESS, в которой содержатся опции, передаваемые в less (программу постраничного просмотра, используемую по умолчанию). По умолчанию переменная имеет значение FRSXMK, если убрать опцию S, строки не будут обрезаться.

Например:

SYSTEMD_LESS=FRXMK journalctl

Ограничение размера журнала


Если journald настроен что бы сохранять журналы после перезагрузки, то по умолчанию размер журнала ограничен 10% от объема файлового раздела и максимально может занять 4 Гб дискового пространства.

Максимальный объем журнала можно скорректировать, раскомментировав и отредактировав следующий параметр в файле конфигурации journald:

SystemMaxUse=50M

Удаление журналов


Удалить файлы архивных журналов, можно вручную с помощью rm или использовав journalctl.

Удалить журналы, оставив только последние 100 Мб:

# journalctl --vacuum-size=100M

Удалить журналы, оставив журналы только за последние 7 дней:

# journalctl --vacuum-time=7d

Заключение


Служба журналирования логов journald очень мощный и гибкий инструмент, и если вы знаете как его использовать, он может сделать вашу жизнь намного проще во время поиска причин проблем с системой или ее сервисами.



RUVDS.com
VDS/VPS-хостинг. Скидка 10% по коду HABR

Комментарии 24

    0
    Век живи — век учись.
    Статья отличная, автору респектище.
    PS. внезапно в RUVDS есть нормальные авторы (один шт.), а не только «кунг-фу...» чтецы манов вслух.
      0
      Справедливости ради, всё это есть в манах по journald
        0
        Я больше скажу — в манах вообще практически всё есть.
        Надо просто их почитать.
        Все 14694 штуки например (только-что на своей машине посчитал).
      +1
      Он до сих пор не умеет чистить логи отдельных юнитов? А поиск?
        +2

        Не отношусь к хейтерам systemd, но journald получился у них не очень. Конкретные предъявы такие: 1) структурированные данные дело полезное, но плата за это — оверхед места = 2 порядка (x100) по сравнению с обычными текстовыми логами. Поэтому если у вас много логов, то готовьте или много места или подключайте старый-добрый ( r ) syslog.
        2) Нет возможности хранить логи раздельно по службам. Т.е нжинкс в один файл, мускуль — в другой и тп. Т.е имеем вариант только, когда все селёдки в одной бочке. Опять же, на десктопе мне без разницы, а на прод серверах это неудобно, особенно, с учетом п.1, когда какой-нибудь говорливый сервис вымывает другие логи. И это эпик фейл.


        А logrotate как бы и до journald работает уже 100 лет в обед и есть не просит.

          0
          По поводу первого пункта. Удобство часто требует оверхэд. Это нормально. К счастью живём в мире где дисковое пространство достаточно дешёвое.
            +1
            Не у всех компьютеров есть физический диск.
              0

              Удобство требует, но понятие "достаточно" не имеет смысла без уточнения для чего именно. Если у вас сервер в облаке, то оверхед за удобство может превратиться в круглую сумму в конвертируемой валюте. Если у вас VPS с диском 50-100 гб, то какая-нибудь внезапная ошибка, приводящая к спаму в логи может уложить весь раздел с логами. И хорошо, если они раздел сделан отдельно от общего.
              А конкретно у нас была необходимость хранить несколько недель относительно говорливых сервисов. На сервере были диски на несколько Тб, но их хватало для хранения менее, чем 1 неделя. А нужно было больше. Переход на 10тб диски несет в себе не только финансовые затраты, это совсем другие затраты на ребилд, например, и в разы другая надежность.

              0

              Вот с службами, это, да, очень неудобно. Особенно когда логи nginx и mysql — это по сути логи целевого приложения сервера, а не общесистемные.

              +2
              Экспериментируя с Linux, заметил такой эффект — если вручную удалить все файлы журналов, то компьютер потом работает быстрее (вернее, открытие директорий). Это заметно на слабом пк с hdd. Потом, после нескольких дней активного использования linux производительность падает (но это незаметно до очистки директории).
                0
                Можно настроить правила, чтобы журналы чистились автоматически.
                +3
                Представьте, что вам приходится иметь дело с проблемным сервером, который даже не загружается — в таком случае можно загрузиться с live-дистрибутива, смонтировать системный раздел и просмотреть логи systemd, чтобы понять, в чем проблема.

                И чем это отличается от варианта с syslog? :)
                  +1

                  На всякий случай у journald лучше включать ForwardToSyslog, если на машине есть достаточный запас IO на диск с логами. Обычно в случае падений текстовые логи намного более восстановимы, чем бинарные

                    0
                    С помощью этой тулзы можно ответить на вопрос: «кто и когда удалил файлы из %этого% каталога»? «Что и откуда именно удалил %пользователь%»?
                    Просто посмотреть «логи за конкретную дату» малоинформативно.
                      +1
                      С помощью этой тулзы можно ответить на вопрос: «кто и когда удалил файлы из %этого% каталога»? «Что и откуда именно удалил %пользователь%»?

                      Я тоже не сторонник сабжа, но это уже скорее аудит файловой системы, и для этого есть другие средства. Все зависит от конкретной задачи. Например, если у вас файлопомоечка на samba, то там есть встроенные модули аудита и даже «Корзина» для удаленных файлов. Если нужно мониторить всю файловую систему или каталоги, то есть несколько утилит и библиотек для inotify, например inotify-utils, iwatch. Или можно написать свой кастом на fsnotify.
                        0

                        Тут вопрос, наверное, больше про то, что аудит есть, в логи пишется кто-что сделал, но хотелось бы фильтровать по конкретным полям, а не тупо грепать

                          +1
                          Не знаю как в systemd(не сторонник), но в rsyslog поля настраиваемые + можно выводить логи в отдельные файлы. И почему grep тупо?
                            0

                            Например, дат у вас в записи лога 10, а вам нужна конкретная типа created_at

                              +1
                              Вы формат даты в логе видите? Вы думаю можете grep отсортировать даты с глубиной до 10 секунд. Там где не справится grep помогут sed и awk. Но даже grep может делать выборку по нескольким условиям объединяя их AND/OR/NOT. Производительность этого метода конечно будет сильно зависеть от того, как вы построите сортировку, но всяко в сотни раз быстрее, чем фильтр в журнале сообщений windows, который миллион событий может несколько секунд сортировать.
                                0

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

                      0

                      Какой-нибудь встроенный grep по тексту сообщений, желательно с pcre, уже подвезли ?

                        0

                        пайпы работают )

                          0
                          syslog-ng работает
                          0
                          -g, --grep=
                          Filter output to entries where the MESSAGE= field matches the specified regular expression. PERL-compatible
                          regular expressions are used, see pcre2pattern(3) for a detailed description of the syntax.

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

                        Самое читаемое