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