diff --git a/apps/system-log/.env.example b/apps/system-log/.env.example new file mode 100644 index 0000000..86e8001 --- /dev/null +++ b/apps/system-log/.env.example @@ -0,0 +1,58 @@ +# ============================================================================ +# system-log — пример переменных окружения (api + worker) +# +# Скопируйте нужный блок в config.env / .env соответствующего сервиса. +# Переменные, помеченные (обяз.), обязательны — без них процесс не стартует. +# bool принимает 1/0, true/false. +# ============================================================================ + +# --- Общие: приложение и логирование (api + worker) ------------------------- +APP_NAME=SYSTEM_LOG # (обяз.) имя приложения +APP_VERSION=0.0.1 # (обяз.) версия приложения +LOG_LEVEL=info # (обяз.) уровень логирования: info/debug/... + +# --- HTTP-сервер (только api; worker не читает) ----------------------------- +HTTP_HOST=127.0.0.1 # (обяз. для api) хост HTTP-сервера +HTTP_PORT=8888 # (обяз. для api) порт HTTP-сервера (/ping) + +# --- PostgreSQL (api + worker) ---------------------------------------------- +POSTGRES_ADDRESS=127.0.0.1 # (обяз.) хост PostgreSQL +POSTGRES_PORT=6432 # (обяз.) порт PostgreSQL +POSTGRES_DB=systemlog # (обяз.) имя базы данных +POSTGRES_USER=user # (обяз.) пользователь БД +POSTGRES_PASSWORD=password # (обяз.) пароль пользователя БД +ENABLE_SQL_QUERY=1 # логировать SQL-запросы (по умолчанию 0) +ENABLE_SSL=0 # TLS к PostgreSQL с проверкой по YC-PG-CERTIFICATE (по умолчанию 0) +# YC-PG-CERTIFICATE= # содержимое (PEM) CA-сертификата PostgreSQL; нужно при ENABLE_SSL=1 + +# --- Kafka (только api) ----------------------------------------------------- +# KAFKA_ENABLE обязательна. Если 0 — остальные KAFKA_* можно не задавать. +KAFKA_ENABLE=0 +# KAFKA_BROKERS=localhost:9091,localhost:9092 # список брокеров через запятую +# KAFKA_GROUP=system-log-local # имя consumer-группы +# KAFKA_CLIENT_ID=system-log-local # client id (в логах брокера) +# KAFKA_USERNAME=username # пользователь Kafka +# KAFKA_PASSWORD=password # пароль пользователя Kafka +# KAFKA_USE_SSL=0 # TLS для Kafka +# KAFKA_ENABLE_LOGGING=0 # отладочное логирование клиента +# KAFKA_PEM_PATH= # СОДЕРЖИМОЕ (PEM) сертификата (не путь!), при KAFKA_USE_SSL=1 +# KAFKA_TOPIC=system-log-local # топик для продюсера + +# --- Трейсинг OpenTelemetry (только api; необязательно) --------------------- +# TRACER_USE=true # включить трейсинг (по умолчанию true) +# TRACER_HOST=localhost:4317 # адрес OTLP-коллектора +# TRACER_USE_INSECURE=true # подключение без TLS +# SERVICE_NAME=system-log # имя сервиса в трейсах +# TRACER_LOGGER_NAME=tracer_logger # имя otel-логгера + +# --- Внешние сервисы (только worker) ---------------------------------------- +DOCUMENTATIONS_URL=http://localhost:6666 # (обяз. для worker) URL сервиса documentations +DJANGO_HOST=http://localhost:8000 # (обяз. для worker) URL Django/ЛК +SUPER_USERNAME=superuser # (обяз. для worker) логин суперпользователя Django +SUPER_PASSWORD=password # (обяз. для worker) пароль суперпользователя Django + +# --- Вспомогательные (не читаются кодом приложений) ------------------------- +PG_URL=postgres://user:password@localhost:6432/systemlog # строка подключения для CLI migrate (Makefile) +EXTERNAL_POSTGRES_PORT=6432 # внешний порт проброса Postgres в docker-compose +# NAMESPACE=system-log # задаётся в манифестах, кодом не читается +# POSTGRES_POOL_SIZE=3 # задаётся в манифестах, кодом не читается diff --git a/apps/system-log/CONFIGURATION.md b/apps/system-log/CONFIGURATION.md new file mode 100644 index 0000000..1892aa5 --- /dev/null +++ b/apps/system-log/CONFIGURATION.md @@ -0,0 +1,163 @@ +# Конфигурация system-log (api + worker) + +Документ описывает все переменные окружения и способы конфигурирования сервисов репозитория `system-log`: + +- **api** — HTTP-сервис (`platform/system-log`), пишет события в PostgreSQL и (опционально) в Kafka; +- **worker** — фоновый воркер (`platform/system-log-worker`), обогащает события данными из сервисов documentations и Django (ЛК). + +## Способы конфигурирования + +Оба сервиса настраиваются **только через переменные окружения**. Разбор выполняется в `config/config.go` через библиотеку [`cleanenv`](https://github.com/ilyakaznacheev/cleanenv) (функция `config.NewConfig()` → `cleanenv.ReadEnv`). Отдельного конфиг-файла (yaml/toml) у приложений нет. + +Обязательные переменные помечены тегом `env-required:"true"` — при их отсутствии `NewConfig()` вернёт ошибку и процесс завершится (`log.Fatalf`). + +Источники переменных по способам запуска: + +| Способ запуска | Откуда берутся переменные | +| --- | --- | +| Локально (docker-compose + бинарник) | Файл `config.env` в корне репозитория. `docker-compose.yml` (`env_file: ./config.env`) поднимает только контейнер Postgres (`timescale/timescaledb-ha`); сам сервис запускается бинарником. `Makefile` через `include config.env` использует `PG_URL` для миграций | +| Kubernetes — собственный Helm-чарт репозитория | `.helm/values-.yaml`: блок `envs` (обычные значения) и `secrets` (значения из k8s-секретов). Деплой запускается пайплайнами `generic/common-ci` | +| Kubernetes — этот infra-репозиторий (`iac/apps/system-log`) | `base/` — kustomize-манифесты с инъекцией секретов через **HashiCorp Vault** (annotations `vault.hashicorp.com/*`), обычные переменные заданы инлайн в `env:`. Оверлеи: `yc-k8s-test` (base + postgresql), `brusnika-stage` (Flux `HelmRelease` на `universal-chart`, блоки `envs`/`secretEnvs`) | +| CI/CD (GitLab) | `.gitlab-ci.yml` подключает шаблоны `generic/common-ci`; в `workflow.rules` задаются переменные пайплайна (`RELEASE_NAME`, `*_NAMESPACE`, `CHART_NAME`, `CHART_VERSION`, `STAND`, `IMAGE_PATH`, `HELM_SET_ARGS` и т.п.) | + +**Миграции БД (api).** Отдельного шага миграций в entrypoint нет: миграции выполняются **в процессе при старте api** — сборка идёт с тегом `-tags migrate`, и `init()` в `internal/app/http/migrate.go` применяет `migrate up` из каталога `/migrations` перед запуском HTTP-сервера. Локально миграции можно прогнать через `make migrate-up-local` (использует `PG_URL` из `config.env`). Воркер миграций не выполняет. + +--- + +## api (`system-log`) + +Переменные читаются структурой `config.Config` (`config/config.go`): `App`, `Log`, `HTTP`, `POSTGRES`, `KAFKA`, `TRACER`. + +### Приложение и логирование + +| Переменная | Тип | Обяз. | По умолчанию | Назначение | +| --- | --- | --- | --- | --- | +| `APP_NAME` | string | да | — | Имя приложения | +| `APP_VERSION` | string | да | — | Версия приложения | +| `LOG_LEVEL` | string | да | — | Уровень логирования (`info`/`INFO`, `debug` и т.п.) | +| `HTTP_HOST` | string | да | — | Хост прослушивания HTTP-сервера | +| `HTTP_PORT` | uint | да | — | Порт HTTP-сервера (эндпоинт `/ping` — liveness/readiness) | + +### PostgreSQL + +| Переменная | Тип | Обяз. | По умолчанию | Назначение | +| --- | --- | --- | --- | --- | +| `POSTGRES_ADDRESS` | string | да | — | Хост PostgreSQL | +| `POSTGRES_PORT` | string | да | — | Порт PostgreSQL | +| `POSTGRES_DB` | string | да | — | Имя базы данных | +| `POSTGRES_USER` | string | да | — | Пользователь БД | +| `POSTGRES_PASSWORD` | string | да | — | Пароль пользователя БД | +| `ENABLE_SQL_QUERY` | bool | нет | `false` | Логировать SQL-запросы | +| `ENABLE_SSL` | bool | нет | `false` | Подключаться к PostgreSQL по TLS с проверкой по `YC-PG-CERTIFICATE`; иначе к строке подключения добавляется `?sslmode=disable` | +| `YC-PG-CERTIFICATE` | string | нет | — | Содержимое (PEM) CA-сертификата PostgreSQL; используется при `ENABLE_SSL=1` | + +### Kafka + +`KAFKA_ENABLE` обязателен всегда. Если `KAFKA_ENABLE=0`, продюсер не создаётся и остальные `KAFKA_*` можно не задавать. Если `KAFKA_ENABLE=1`, для корректной работы нужны брокеры/креды/топик (в самом коде они помечены как необязательные, но без них подключение к Kafka не поднимется). + +| Переменная | Тип | Обяз. | Назначение | +| --- | --- | --- | --- | +| `KAFKA_ENABLE` | bool | да | Включает отправку сообщений в Kafka | +| `KAFKA_BROKERS` | string | нет | Список адресов брокеров через запятую (напр. `host:9091,host:9092`) | +| `KAFKA_GROUP` | string | нет | Имя consumer-группы (отображается в логах брокера) | +| `KAFKA_CLIENT_ID` | string | нет | Client ID (отображается в логах брокера) | +| `KAFKA_USERNAME` | string | нет | Пользователь Kafka | +| `KAFKA_PASSWORD` | string | нет | Пароль пользователя Kafka | +| `KAFKA_USE_SSL` | bool | нет | Включить TLS для подключения к Kafka | +| `KAFKA_ENABLE_LOGGING` | bool | нет | Включить отладочное логирование клиента Kafka | +| `KAFKA_PEM_PATH` | string | нет | **Содержимое** (PEM) сертификата для Kafka при `KAFKA_USE_SSL=1`. Несмотря на имя `..._PATH`, значение трактуется как сам сертификат, а не путь к файлу (`pkg/sarex-kafka-connector/kafkasrx.go`) | +| `KAFKA_TOPIC` | string | нет | Топик, в который продюсер шлёт события | + +### Трейсинг (OpenTelemetry) + +| Переменная | Тип | По умолчанию | Назначение | +| --- | --- | --- | --- | +| `TRACER_USE` | bool | `true` | Включает OpenTelemetry-трейсинг и otel-логгер | +| `TRACER_HOST` | string | `localhost:4317` | Адрес OTLP-коллектора | +| `TRACER_USE_INSECURE` | bool | `true` | Небезопасное (без TLS) подключение к коллектору | +| `SERVICE_NAME` | string | `system-log` | Имя сервиса в трейсах | +| `TRACER_LOGGER_NAME` | string | `tracer_logger` | Имя otel-логгера | + +> Тип `bool` в cleanenv принимает `1`/`0`, `true`/`false` и т.п. + +--- + +## worker (`system-log-worker`) + +Переменные читаются структурой `config.Config` (`config/config.go`): `App`, `Log`, `POSTGRES`, `DOCUMENTATIONS`, `DJANGO`. **Kafka и трейсинг воркер не использует.** HTTP-сервера у воркера нет (структура `HTTP` в конфиге отсутствует), поэтому `HTTP_HOST`/`HTTP_PORT` кодом не читаются, хотя и задаются в манифестах. + +### Приложение, логирование, PostgreSQL + +Совпадают с api: `APP_NAME`, `APP_VERSION`, `LOG_LEVEL` (все обязательны) и блок PostgreSQL — `POSTGRES_ADDRESS`, `POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD` (обязательны), `ENABLE_SQL_QUERY`, `ENABLE_SSL`, `YC-PG-CERTIFICATE` (необязательны). См. таблицы выше. + +### Внешние сервисы (обогащение событий) + +| Переменная | Тип | Обяз. | Назначение | +| --- | --- | --- | --- | +| `DOCUMENTATIONS_URL` | string | да | Базовый URL сервиса documentations (клиент `documentations.New`) | +| `DJANGO_HOST` | string | да | Базовый URL Django/ЛК (клиент `projecttask.New`) | +| `SUPER_USERNAME` | string | да | Логин суперпользователя для авторизации в Django | +| `SUPER_PASSWORD` | string | да | Пароль суперпользователя для авторизации в Django | + +> Воркер работает циклически (внутренний интервал опроса — фиксированные `20s` в коде `internal/app/worker/worker.go`, не настраивается переменной окружения). + +--- + +## Инфраструктурные и вспомогательные переменные + +Не читаются кодом приложений, но участвуют в запуске/сборке/деплое. + +| Переменная | Где используется | Назначение | +| --- | --- | --- | +| `PG_URL` | `config.env`, `Makefile` (`make migrate-*`) | Строка подключения для CLI `migrate` при локальных миграциях | +| `EXTERNAL_POSTGRES_PORT` | `config.env`, `docker-compose.yml` | Внешний порт проброса контейнера Postgres | +| `NAMESPACE` | Helm-чарты, `base/*.yaml`, brusnika-оверлеи | Задаётся в манифестах, но **кодом приложений не читается** | +| `POSTGRES_POOL_SIZE` | Helm-чарты, `base/*.yaml`, brusnika-оверлеи | Задаётся в манифестах, но **кодом приложений не читается** (в `config.Config` поля пула соединений нет) | +| `RELEASE_NAME`, `CHART_NAME`, `CHART_VERSION`, `STAND`, `*_NAMESPACE`, `IMAGE_PATH`, `HELM_SET_ARGS`, `DOCKERFILE_PATH`, `ENABLE_*` | `.gitlab-ci.yml` (`workflow.rules`) | Параметры пайплайна `generic/common-ci` (сборка чарта/образа, деплой) | + +--- + +## Деплой из этого репозитория (`iac/apps/system-log`) + +Здесь используется **kustomize** (не собственный Helm-чарт сервиса). Секреты БД, Kafka и Django инъектируются агентом **Vault** и подгружаются в окружение процесса до старта (`set -a; . /vault/secrets/...; exec /app`). + +### `base/` + +- `backend-deployment.yaml` (api) — обычные переменные заданы инлайн в `env:`; Vault-шаблоны формируют `POSTGRES_ADDRESS/PORT/DB/USER/PASSWORD` (из `secrets/data/postgresql/apps/system-log`) и `KAFKA_USERNAME/PASSWORD/BROKERS/TOPIC` (из `secrets/data/kafka/apps/system-log`). Прочие Kafka-параметры и `KAFKA_PEM_PATH=/tmp` — инлайн. +- `worker-deployment.yaml` (worker) — Vault формирует `POSTGRES_*` и `SUPER_USERNAME/SUPER_PASSWORD` (из `secrets/data/vault/common/django_auth`); `DOCUMENTATIONS_URL`, `DJANGO_HOST` и прочее — инлайн. +- `kustomization.yaml` собирает `namespace`, `serviceaccount`, api/worker deployments и service. + +### Оверлеи + +- **`yc-k8s-test`** — `../base` + `postgresql.yaml` (HelmRelease `postgresql-contour`, создаёт БД `system_log_db`, пользователя `system_log`, расширения `ltree`/`pg_stat_statements`/`timescaledb`, восстановление из дампа). +- **`brusnika-stage`** — Flux `HelmRelease` на `universal-chart` (per-env значения `_default`/`stage`/`preprod`/`production`). Переменные — в `envs`, секреты — в `secretEnvs` (`postgres-secret`, `ya-kafka-secret`, `yc-kafka-certificate`, `superuser`). + +--- + +## Замечания и потенциальные проблемы + +- **`config.env` для локального запуска неполон.** Для api не заданы `KAFKA_ENABLE` (обязательна) и `APP_NAME`/`APP_VERSION`/`LOG_LEVEL`/`HTTP_*` присутствуют, а вот блок `TRACER_*` возьмётся из дефолтов. Для worker в `config.env` **нет обязательных** `DJANGO_HOST`, `SUPER_USERNAME`, `SUPER_PASSWORD` (и `DOCUMENTATIONS_URL` есть) — без них воркер не стартует. Также `config.env` содержит `HTTP_HOST`/`HTTP_PORT`, которые воркер не использует. +- **Имя `KAFKA_PEM_PATH` вводит в заблуждение:** код кладёт значение переменной как содержимое PEM-сертификата, а не путь к файлу. При этом в `README.md` фигурирует `KAFKA_PEM_CERT`, а brusnika-оверлей задаёт **обе** переменные (`KAFKA_PEM_CERT` и `KAFKA_PEM_PATH`) с одним значением — кодом читается только `KAFKA_PEM_PATH`. +- **`NAMESPACE` и `POSTGRES_POOL_SIZE`** задаются во всех манифестах, но кодом не читаются (размер пула соединений в конфиге не предусмотрен). +- Имя переменной `YC-PG-CERTIFICATE` содержит дефисы — cleanenv сопоставляет её по точному совпадению тега `env`. +- Значения `POSTGRES_DB`/`APP_NAME` расходятся между окружениями (`system_log` vs `system-log`, `system_log_db` в Vault) — при подключении важно использовать значение конкретного окружения. + +--- + +## Минимальный набор для локального запуска + +**api** (Postgres — через docker-compose, api — бинарником с миграциями при старте): + +- `APP_NAME`, `APP_VERSION`, `LOG_LEVEL` +- `HTTP_HOST`, `HTTP_PORT` +- `POSTGRES_ADDRESS`, `POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD` +- `KAFKA_ENABLE=0` (иначе — весь блок `KAFKA_*`) +- при необходимости — `ENABLE_SQL_QUERY`, `ENABLE_SSL` (+ `YC-PG-CERTIFICATE`), `TRACER_*` + +**worker**: + +- `APP_NAME`, `APP_VERSION`, `LOG_LEVEL` +- `POSTGRES_ADDRESS`, `POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD` +- `DOCUMENTATIONS_URL`, `DJANGO_HOST`, `SUPER_USERNAME`, `SUPER_PASSWORD` + +См. пример значений в `config.env` каждого репозитория.