Всем привет! Существует достаточно много решений для локального и удаленного сбора и чтения логов с различных систем. В разные периоды времени как для рабочих задач, так и для домашнего стенда мне приходилось настраивать разные системы, и хочу заметить, что некоторые из них достаточно сложны в своей конфигурации. Одини из самых популярных систем управления логами являются ELK стек, Graylog и Loki, это отличные решения, когда нужно обрабатывать журналы с большого количества машин, но достаточно тяжеловесные для мониторинга одного или двух микросервисов (например, запущенных в контейнерах), особенно, если не стоит вопрос удаленного хранения логов. По мимо этого, для полноценного использования требуется установка и конфигурация агентов на конечных машинах, и хотя данный процесс несложно автоматизировать, это также требует времени и дополнительную систему (например, Ansible или Jenkins, хотя это опционально, и можно обойтись руками или скриптами).
У меня есть небольшой проект (Telegram бот, а также на базе него канал), о котором я уже писал пару статей на Хабр (тут и тут), и который в процессе своей работы пишет логи, по этому на примере него расскажу, какие решения для их чтения использовал (аналогично, как и для других проектов), и к чему в итоге пришел, а если точнее, написал самостоятельно, что бы упростить данный процесс в дальнейшем.
Файловая система
Самый типовой способ, особенно на этапе разработки, это запись и чтение логов из файла, например, с помощью стандартной утилиты tail
в консоли. Что бы визуально сделать содержимое более наглядным, можно добавить покраску вывода с помощью tailspin, а для фильтрации вывода использовать grep
.
Так как моя основная система является Windows, для разработки под Linux чаще всего использую Debian производные системы без графического интерфейса. Для удаленного взаимодействия с файловой системой существует очень много файловых менеджеров, например, WinSCP, в котором можно читать и редактировать файл в любом привычном текстовом редакторе. Если для таких задач уже используете VSCode, то куда удобнее использовать пакет Remote Development для прямого подключения к удаленной машине. При использовании данного расширения, работа с удаленной системой ничем не отличается от того, если бы VSCode
был запущен локального в графическом интерфейсе Linux (поддерживается установка плагинов напрямую в удаленную систему, доступ к консоли, а также любым файлам, в том числе их загрузка, аналогично WinSCP
). Изменения в файлах обновляются автоматически (по умолчанию, что удобно для чтения логов), а для покраски вывода можно воспользоваться расширением TXT Syntax. Из минусов такого подхода, VSCode
устанавливает в удаленную машину серверный процесс, что не всегда допустимо а также значительно увеличивает нагрузку (особенно на ОЗУ, которая может забиться в потолок при использовании динамической памяти), что также может быть критично на системах с низкой производительностью. Как альтернатива, можно воспользоваться расширением sshfs, которое интегрирует (монтирует) удаленную файловую систему и терминал напрямую в VSCode
, при этом никак не нагружая удаленную систему.
Юниты systemd
Любое приложение для удобства управления можно запустить как системную или пользовательскую службу, что бы передать управление в подсистему systemd. Это позволяет автоматизировать процесс запуска любого пользовательского скрипта или микросервиса при перезагрузке системы, а логи становятся доступны для просмотра через утилиту journalctl
с поддержкой ротации. Для этого достаточно создать простой unit
файл (пример для бота тут), который обрабатывает запуск и остановку приложения. Важно, чтобы при запуске приложения логи поступали в стандартный поток вывода (stdout
), то есть выводились в консоль, а не записывались в файл (или настроить отдельный поток для чтения из файла).
Такие логи можно удаленно передавать в систему мониторинга без использования агентов, с помощью встроенной в большинство операционных систем утилиты Rsyslog. Для этого достаточно создать файл конфигурации (например, all.conf
) в директории /etc/rsyslog.d/
и указать используемый протокол для передачи (UDP
или TCP
), тип сообщений для отправки и адрес сервера (пример для TCP: *.* @@192.168.31.211:514
), после чего перезапустить сервис.
Например, для приема таких сообщений в Graylog, достаточно создать входящий поток (inputs
) для syslog на порту 514 по указанному протоколу. Также существуют специализированные решения, например, Visual Syslog Сервер - это десктопное приложение Windows для получения, хранения, просмотра и фильтрации сообщений syslog
. Хотя такой сервер куда медленнее (т.к. не использует полноценную СУБД), но при этом и ресурсоемкость меньше в несколько раз, а для его запуска настройка не требуется, что делает его очень простым и быстрым решением.
Для мониторинга одного сервиса (или нескольких на одной машине) куда удобнее использовать специализированные консольные приложения. Одним из таких является lnav - это терминальный интерфейс для просмотра лог-файлов, написанный на C++
. Он принимает текст из стандартного вывода, а также поддерживает навигацию и покраску. Например, можно вывести сообщения конкретного сервиса по его имени из системы journald
, и передать их на вход lnav
:
journalctl -fu kinozal-bot.service | lnav
Контейнеры
Если следовать современным подходам, быстрее и удобнее запускать приложение в контейнере (хотя к такому выводу я пришел только с опытом), особенно, если оно уже способно работать как служба. На сегодняшний день существует очень много решений для доступа к логам контейнеров, и пожалуй самым удобным из них является Dozzle - это легковесное приложение с веб-интерфейсом для мониторинга журналов Docker (без их хранения). Для работы не требует никакой настройки, достаточно запустить образ одной командой из Docker Hub, но, если необходимо также просматривать логи с других машин, достаточно настроить TCP-сокет или установить агент, а при запуске контейнера указать данные для подключения.
При этом, куда больше существует терминальных приложений для полноценного управления системой контейнеризации Docker (с Podman все куда хуже), например, ctop, dockly или lazydocker. Единственный минус всех терминальных интерфейсов, это отсутствие полноценного доступа к журналам контейнеров, а именно, вывод всей истории логов (а не последних сообщений) и его фильтрация.
Универсальный интерфейс
Так как по профессии являюсь системным администратором, мне часто приходится искать и читать логи различных сервисов, по этой причине долгое время я пытался найти такой инструмент, который позволил бы получить доступ ко всем возможным логам в системе на текущей машине, без необходимости устанавливать и использовать различные инструменты или запоминать команды и их параметры. Например, было бы удобно сразу узнать какие существуют журналы в системе и по ключевому слову найти нужный, не зависимо, хранится он файловой системе или обрабатываются с помощью journald
. Хотя такой запрос возможно слишком специфичный, у меня все-таки получилось найти решение.
lazyjournal - это пользовательский интерфейс терминала для journalctl
, логов файловой системы, а также контейнеров Docker и Podman для быстрого просмотра и фильтрации журналов. Данный инструмент вдохновлен проектами Jesse Duffield (создатель lazygit и lazydocker), по этому следуя первоисточнику, написан на языке Go
с использованием библиотеки gocui. Выглядит интерфейс следующим образом:
Слева отображается поле ввода для фильтрации списков и три панели самих журналов - список доступных сервисов из systemd
(если поддерживается в системе), всех лог-файлов из директории /var/log
(в том числе архивных и усеченных в процессе ротации) а также контейнеров Docker
. При этом, все списки возможно отфильтровать, для быстрого поиска нужного журнала по его названию. По мимо этого, каждое окно позволяет переключаться между другими списками журналов.
В первом окне доступны все системные и пользовательские журналы из
journald
, а также список всех загрузок системы для вывода логов ядра.Во втором, можно вывести список всех найденных журналов с расширением
*.log
и*.pcap
(Packet Capture) в домашних директориях пользовтелей с сортировкой по дате изменения, а также список лог-файлов, которые в текущий момент используются процессами (файловые дескрипторы).Для третьего окна, поддерживается доступ к журналам системы контейнеризации Podman.
При чтение журнала присутствует 3 режима фильтрации: по умолчанию (с учетом регистра), нечеткий поиск (поиск всех указанных словосочетаний в любом месте строки без учета регистра) и с поддержкой регулярных выражений в стиле grep
(на базе библиотеки regexp). После загрузки журнала, если данные будут изменены, они автоматически отображаются в окне вывода после разделительной черты с отметкой времени. При этом реализована базовая покраска ключевых слов, а также url
, ip-адресов
и т.п.
Пример поиска сообщений об ошибках, связанных с отправкой через curl
:
Для установки, достаточно загрузить один исполняемый файл в систему без зависимостей, например, используя следующую команду:
curl -sS https://raw.githubusercontent.com/Lifailon/lazyjournal/main/install.sh | bash
Эта команда запустит скрипт, который загрузит последнюю версию бинарного файла из репозитория GitHub в домашний каталог текущего пользователя вместе с другими исполняемыми файлами (по пути
~/.local/bin
, или создаст его) и предоставит права на выполнение.
На текущий момент по мимо Linux, реализована поддержка macOS, OpenBSD, FreeBSD и Windows для доступа к файловым журналам и контейнерам.
Итог
Цель lazyjournal
- получить доступ практически к любым возможным журналам в локальной системе из одного интерфейса, а также упростить процесс их поиска, чтения и фильтрации. В случае, если у вас возникнут проблемы в процессе работы, а также рекомендации по внедрению нового функционала (например, другие источники для сбора логов), вы можете оставить запрос в разделе Issues. Вы также можете подтвердить работоспособность в других системах или архитектурах, это будет полезно для развития проекта.
Комментарии (3)
s00d
21.01.2025 06:15Я когда-то для себя писал консольную утилиту: https://github.com/s00d/logutil Она нужна для парсинга логов nginx (в теории можно настроить на другие логи через регулярку), группирует по запросам и прочее. Иногда помогает.
evgeniy_kudinov
21.01.2025 06:15curl -sS https://raw.githubusercontent.com/Lifailon/lazyjournal/main/install.sh | bash
/paranoid mode on/ Наверное лучше собрать из исходников, после изучения зависимостей в локальной копии. /paranoid mode off/
А утилитка полезная.
crawlingroof
Век живи, век учись. Даже не знал про такие, все больше по старинке, спасибо, пригодится.