# Конфигурация 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` каждого репозитория.