Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/exitfound/lologen

Утилита для генерации искусственных журнальных сообщений для их последующей отправки в Loki.
https://github.com/exitfound/lologen

grafana logs loki promtail python3 tools

Last synced: 2 months ago
JSON representation

Утилита для генерации искусственных журнальных сообщений для их последующей отправки в Loki.

Awesome Lists containing this project

README

        

# **Loki Log Generator**

**Lologen** – это консольная утилита, написанная на Python и предназначенная для непрерывной генерации искусственных журнальных сообщений (они же logs). Основная цель заключается во взаимодействии с Loki (в рамках ознакомления с ним), а также тестировании его работоспособности путем отправки этих самых сгенерированных журнальных сообщений с помощью используемого вами агента, такого как Promtail и т.п. На текущий момент поддерживает некоторое колличество различных опций, которые позволят отправить ваши данные в Loki в том виде и формате, в каком вы пожелаете (в рамках доступной функциональности самого инструмента). Ниже представлено краткое содержание:

- [Содержание:](loki-log-generator)
- [Мотивация](#мотивация)
- [Установка](#установка)
- [Из исходного кода](#из-исходного-кода)
- [С помощью Docker](#с-помощью-docker)
- [Бинарная версия](#бинарная-версия)
- [Подключение к Loki](#подключение-к-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
```

### **С помощью Docker:**

Образ основан на базе Distroless от [GoogleContainerTools](https://github.com/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
```

## **Подключение к Loki:**

По-хорошему то, как именно вы будете настраивать метод отправки информации о журнальных сообщениях зависит от используемого вами стэка технологий. В конце концов, во всяком случае в теории, данной утилите нет до этого дела. Она просто пишет журнальные сообщения в том виде и туда, как вы ей скажете в рамках той среды, в которой она была запущена. Однако на примере используемого мною 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\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 – [тык](https://t.me/opengrad/117). Вы также можете обратиться к официальной документации 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). Чтобы указать желаемый режим используйте флаг `-t` при работе с утилитой:

```
python3 lologen.py -t [console|file|journald]
```

Если вы выбрали `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
```

И, как и в случае с форматом, вне зависимости от используемого типа отправки данных, у всех журнальных сообщений, так или иначе, присутствует уровень логирования. В нашем случае мы можем указать минимальный уровень журнального сообщения, который хотим видеть при отправке, например, в `std`. По умолчанию отправляются журнальные сообщения всех уровней, вплоть до `DEBUG`, но изменить это можно с помощью флага `-l`:

```
python3 lologen.py -t console -s stdout -f json -l warning
```

Помимо всего прочего можно также указать желаемый интервал времени, после которого будет отправлено новое журнальное сообщение. По умолчанию следующее сообщение отправляется спустя две секунды после того, как было отправлено предыдущее. Параметр поддерживает десятичные значения, так что можно даже задать интервал в 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
```