Lologen – это консольная утилита, написанная на Python и предназначенная для непрерывной генерации искусственных журнальных сообщений (они же logs). Основная цель заключается во взаимодействии с Loki (в рамках ознакомления с ним), а также тестировании его работоспособности путем отправки этих самых сгенерированных журнальных сообщений с помощью используемого вами агента, такого как Promtail и т.п. На текущий момент поддерживает некоторое колличество различных опций, которые позволят отправить ваши данные в Loki в том виде и формате, в каком вы пожелаете (в рамках доступной функциональности самого инструмента). Ниже представлено краткое содержание:
Мотивацией к написанию данной утилиты послужил исключительно образовательный интерес, поэтому я не думаю, что сей инструмент хоть сколько-то можно использовать в производственной среде. Тем не менее когда у нас есть развернутый экземпляр Loki и мы хотим разобраться с какой-то его функциональностью, хотелось бы (во всяком случае мне) иметь что-то большее в лице полезной нагрузки, чем пресловутый контейнер Nginx в качестве примера, который затем мы дернем curl'ом и получим сообщение в одну строку. Такой подход просто покажет, что Loki, в сочетании с используемым агентом и визуализатором, как Grafana, работает и больше ничего. Однако любые чуть более специфические требования, такие как принудительная отправка данных в stderr или запись в файл, а также указание используемого формата журнальных сообщений и т.д. будут недоступны, если только у вас нет своего приложения, которое уже будет содержать в себе нужные вам компоненты для желаемого тестирования. Эту потребность и пытается закрыть данный инструмент. Сильно в Интернете я не искал, так что возможно и существуют более внятные аналоги. Мне же было интересно написать утилиту с нуля, которая подходила бы под мои требования в рамках взаимодействия с Loki.
Для успешного взаимодействия с данной утилитой необходимо обладать минимальным количеством программных коммпонентов и вспомогательных инструментов. В частности, это:
-
Python
версии 3 для запуска непосредственно самой утилиты, а также ряд зависимостей, которые перечислены в файлеrequirements.txt
; -
Git
с помощью которого вами будет загружен репозиторий из Github; -
Wget
,curl
иjq
, которые понадобятся для загрузки бинарной версии из релиза (опциональный вариант использования); -
Grafana Stack
как инструмент агрегации и визуализации журнальных сообщений (опционально, поскольку утилита самодостаточна и ничто не запрещает её использовать просто так);
Чтобы начать работу с исходной версией приложения достаточно выполнить следующую последовательность команд:
git clone https://github.com/exitfound/lologen.git
cd lologen
pip3 install -r requirements.txt
python3 lologen.py -h
Образ основан на базе Distroless от GoogleContainerTools. В примере c тэгом main
используется базовый образ python3-debian12
, который хоть и является легковесным, всё же содержит в себе интепретатор Python. В случае с бинарной версией, с тэгом binary
, используется базовый образ base-debian12
. Благодаря этому удалось получить образ с минимально допустимым размером, что по меркам Python довольно-таки неплохо. Результат представлен в примере ниже:
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mdd13/lologen main 8bb8e746c3e7 1 minutes ago 57.3MB
mdd13/lologen binary 25734e3606f2 1 minutes ago 27.6MB
Итак, в рамках работы с Docker можно прибегнуть к трем вариантам запуска утилиты:
- Забрать готовый образ на базе
python3-debian12
из репозитория Docker Hub:
docker run -d --name lologen mdd13/lologen:main
- Собрать образ на базе
python3-debian12
локально и запустить его в своей системе:
docker build -t "lologen:main" .
docker run -d --name lologen lologen:main
- Собрать образ на базе
python3-debian12
с помощью Docker Compose (предварительно изменив файл Docker Compose под локальную сборку):
docker compose up -d --build
Данный метод основан на упаковке Python-скрипта в бинарный файл с помощью инструмента Pyinstaller
. Сам бинарный файл хранится в релизе. Чтобы начать работу с бинарной версией необходимо выполнить следующую последовательность команд:
wget https://github.com/exitfound/lologen/releases/latest/download/lologen_linux_amd64.zip
unzip lologen_linux_amd64.zip
sudo mv lologen /usr/local/bin/
lologen -h
Примечание: Альтернативный путь, по которому также можно забрать архив с бинарным файлом:
wget $(wget -q -O - https://api.github.com/repos/exitfound/lologen/releases/latest | jq -r '.assets[] | select(.name | contains ("lologen")) | .browser_download_url')
Ко всему прочему бинарная версия утилиты была упакована в Docker образ. Концептуально ничем не отличается в плане своей функциональности от основной версии утилиты (с тэгом main
), за тем лишь исключением, что в качестве базового образа используется более легковесная версия образа Distroless в лице base-debian12
. Поскольку мы используем бинарный формат, нам не нужен интерпретатор Python как такого. За счет этого удалось уменьшить финальный варианта используемого нами образа в два раза. В остальном всё идентично:
docker run -d --name lologen mdd13/lologen:binary
И вы также можете собрать данную версию образа локально, как вручную:
docker build -f ./binary/binary.dockerfile -t "lologen:binary" .
docker run -d --name lologen-binary lologen:binary
Так и с помощью Docker Compose (предварительно изменив файл Docker Compose под локальную сборку):
docker compose -f ./binary/binary.docker-compose.yaml up -d --build
По-хорошему то, как именно вы будете настраивать метод отправки информации о журнальных сообщениях зависит от используемого вами стэка технологий. В конце концов, во всяком случае в теории, данной утилите нет до этого дела. Она просто пишет журнальные сообщения в том виде и туда, как вы ей скажете в рамках той среды, в которой она была запущена. Однако на примере используемого мною Grafana Stack (Loki, Promtail и Grafana) я оставлю краткое руководство по сбору и отправке журнальных сообщений из запущенного контейнера. Вообще существует два способа по настройке контейнеров: Driver Loki
для Docker и Scraping
через Promtail. Я предпочитаю первый вариант и моём файле Docker Compose это уже отражено. Выглядит следующим образом:
# Driver variant
logging:
driver: loki
options:
loki-url: "http://172.17.0.1:3100/loki/api/v1/push"
loki-retries: "3"
- json:
expressions:
level:
- regex:
expression: '(level|levelname|lvl|severity)=(?P<level>\w+)'
- labels:
level:
В данном случае мы указываем конечный URL-адрес запущенного нами Loki, а также делаем преобразование имён для поля level, на тот случай, если имя по умочланию будет отличаться в строке журнальных сообщений. В противном случае Grafana, в паре с Loki, не сможет отрисовать это должным образом. В общем данный пример является полностью рабочим для файла Docker Compose, только предварительно необходимо установить сам Driver Loki
. Но вы также можете использовать Scraping
, указав вместо примера выше вот такую конфигурацию:
# Scrape variant:
labels:
name: "lologen"
Правда просто так это работать не будет. Конфигурационный файл вашего агента Promtail должен содержать информацию о Scraping
для Docker:
scrape_configs:
- job_name: docker_scrape
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
relabel_configs:
- source_labels: ['__meta_docker_container_name']
regex: '/(.*)'
target_label: 'container'
- source_labels: ['__meta_docker_container_log_stream']
target_label: 'stream'
- source_labels: ['__meta_docker_container_label_name']
target_label: 'name'
Если представленная выше информация вам ни о чем не говорит, в таком случае я рекомендую прочитать написанную мною статью по тому, как собирать журнальные сообщения из контейнеров, запущенных в среде Docker – тык. Вы также можете обратиться к официальной документации Loki. Если же вы используете другой стэк технологий, тогда вам нужно знать только то, как работать с данной утилитой.
Используйте следующую команду (в зависимости от применяемого метода запуска), чтобы запустить генерацию журнальных сообщений с параметрами по умолчанию:
python3 lologen.py
docker run -d --name lologen mdd13/lologen:main
docker run -d --name lologen mdd13/lologen:binary
lologen
Ниже будет представлено более подробное руководство по работе с данной утилитой. В первую очередь стоит отметить, что некоторые опции обладают несколькими возможными к использованию параметрами. Походу дела каждый из существующих параметров будет рассмотрен. Итак, как уже было отмечено ранее, чтобы вызвать help
, достаточно запустить утилиту со следующим флагом (в примере будет представлен лишь один из вариантов запуска, но параметры идентично применимы ко всем возможным вариантам, которые были упомянуты выше):
python3 lologen.py -h
По умолчанию утилита использует режим console
(отправка в std
) при работе с хендлером (отвечающий за отправку журнальных сообщений). Вы можете задать желаемый режим самостоятельно. На данный момент поддерживается три режима отправки: console
(std
), file
(запись в произвольный файл в системе), journald
(запись в journalctl systemd) и http
(отправка журнальных сообщений веб-серверу). Чтобы указать желаемый режим используйте флаг -t
при работе с утилитой:
python3 lologen.py -t [console|file|journald|http]
При использовании флага -t
с параметром http
также необходимо использовать флаг -W
, который активирует встроенный Web-сервер, на который, собственно, и будут отправляться журнальные сообщения. Например:
python3 lologen.py -t http -W
Представленный выше пример это работа с Web-сервером по умолчанию, однако вы также можете указать произвольные значения (считай любой другой Web-сервер), использовав для этого такие ключи, как -H
и -P
(хост и порт). По желанию также можно указать один из двух методов – GET
или POST
. Выглядеть будет следующим образом:
python3 lologen.py -t http -H yourdomain_or_ip -P 8080 -M POST
Если вы выбрали console
в качестве режима отправки данных, возможнно, что вы захотите указать тип потока (stream
). Их тоже может быть два: stdout
и stderr
. По умолчанию журнальные сообщения отправляются в stdout
, но это можно изменить с помощью флага -s
:
python3 lologen.py -t console -s [stdout|stderr]
Если же вы выбрали отправку данных в file
, в таком случае вы также можете указать путь к файлу, куда будут отправляться журнальные сообщения. По умолчанию это домашний каталог + имя файла в лице spam_application.log
. Однако с помощью флага -p
вы можете указать любой необходимый вам путь (только для некоторых путей могут понадобится допольнительные права на запись):
python3 lologen.py -t file -p /var/log/lologen.log
Вне зависимости от используемого режима отправки данных каждое журнальное сообщение, так или иначе, выражено в определенном формате. На данный момент консольная утилита поддерживает три формата журнальных сообщений: это logfmt
(по умолчанию), JSON
и unstructured
(простая строка, без каких либо полей, по типу журнального сообщения Nginx). Используйте флаг -f
для указания желаемого формата журнальных сообщений:
python3 lologen.py -t console -s stdout -f [json|logfmt|unstructured]
И, как и в случае с форматом, вне зависимости от используемого типа отправки данных, у всех журнальных сообщений, так или иначе, присутствует уровень логирования. В нашем случае мы можем указать минимальный уровень журнального сообщения, который хотим видеть при отправке, например, в std
. По умолчанию отправляются журнальные сообщения всех уровней, вплоть до DEBUG
, но изменить это можно с помощью флага -l
:
python3 lologen.py -t console -s stdout -f json -l [debug|info|warning|error|critical]
Помимо всего прочего можно также указать желаемый интервал времени, после которого будет отправлено новое журнальное сообщение. По умолчанию следующее сообщение отправляется спустя две секунды после того, как было отправлено предыдущее. Параметр поддерживает десятичные значения, так что можно даже задать интервал в 0,5 секунд, для ускоренной отправки данных. Чтобы сделать это используйте флаг -T
:
python3 lologen.py -t console -s stdout -f json -l warning -T 0.5
Последние две опции по своей природе являются максимально опциональными. Первая позволяет задать произвольное имя для создаваемого логера. По умолчанию это spam_application
. Задать своё имя можно с помощью флага -n
:
python3 lologen.py -t console -s stdout -f json -l warning -T 0.5 -n my_log_output
Тогда как с помощью второй опции, при желании, можно окрасить в определенный цвет содержимое поля msg
в журнальном сообщении. По сути это наша полезная нагрузка, где в зависимости от установленного уровня логирования мы получаем соответствующий текст. Обладает двумя параметрами: always
и never
. По умолчанию окрашивание текста включено всегда. Если вы хотите отключить его используйте флаг -c
:
python3 lologen.py -t console -s stdout -f json -l warning -T 0.5 -n my_log_output -c never
Напоминаю, что все представленные опции также применимы и по отношению к бинарному файлу, и по отношению к запускаемым образам Docker. Кстати говоря, в контексте Docker, в качестве точки входа установлен запуск самой утилиты, так что если вы захотите изменить значения по умолчанию, необходимо после установленного имени образа указать необходимый список опций. Например:
docker run -d --name lologen mdd13/lologen:main -t console -s stdout -f json -l warning -T 0.5 -n my_log_output -c never
docker run -d --name lologen mdd13/lologen:binary -t console -s stderr -f logfmt -l info -T 1 -n my_log_output -c always
Что же касается Docker Compose, то все опции можно передать через command
внутри описываемого файла:
version: '3.7'
services:
lologen:
command: [ "-f", "json", "-l", "info", "-s", "stdout", "-t", "console", "-T", "2", "-c", "always"]
Если у вас возникла потребность в самостоятельной сборке бинарного файла, можете воспользоваться следующей командой:
pip3 install --user -r requirements.txt
python3 -m PyInstaller --onefile --noconfirm --clean --name lologen lologen.py
./dist/lologen -h