feat(observability): configurable logging, request ids and error logs

- internal/logging: LOG_LEVEL/LOG_FORMAT parsing and slog handler
- request_id middleware (X-Request-ID or generated, echoed) + debug access log
- httpx registers errors; middleware logs internal causes with request_id
- health excluded, objects/sse debug-only, no query/body/secrets in logs
- new observability capability spec; README/.env.example docs
This commit is contained in:
iu
2026-10-11 13:40:11 +03:00
parent a5d0cee0eb
commit 6361e48b20
18 changed files with 998 additions and 5 deletions
@@ -0,0 +1,40 @@
# Proposal
## Why
Диагностика инцидентов идёт вслепую: логов операций нет ни на каком уровне,
access-логов нет, а внутренние ошибки (не-`AppError`) отдаются клиенту как
generic `500` и **нигде не логируются** — таких мест 82. Уровень логов зашит
(`slog.LevelInfo`, `main.go:34`), переключателя нет. Нужны управляемая детализация,
след каждого запроса и регистрация причин внутренних ошибок.
## What Changes
- Конфигурация логирования: `LOG_LEVEL` (`debug|info|warn|error`, по умолчанию `info`)
и `LOG_FORMAT` (`json|text`, по умолчанию `json`); `main.go` строит `slog`-handler
из конфига вместо жёсткого `LevelInfo`.
- Gin-middleware: `request_id` (из заголовка `X-Request-ID` либо сгенерированный)
кладётся в контекст запроса; access-лог уровня `debug` с полями method, route,
status, latency, bytes, client_ip, user_id, request_id.
- Регистрация внутренних ошибок: не-`AppError` из `httpx.RespondError`/`Abort`
становятся регистрируемыми и пишутся на уровне `error` с `request_id` и причиной;
отказы 4xx — на уровне `debug`.
- Приватность: не логируются query-строка (`?token=`), подписанные URL и тела
запросов; `/api/health` исключён всегда, `/api/objects/*` и `/api/sse/*` — только `debug`.
- CLI-команды (`migrate`, `reconcile`, `backfill-exif`) не меняются.
## Capabilities
### New Capabilities
- `observability`: конфигурируемое структурированное логирование сервера — уровень и формат вывода, access-лог запросов с корреляцией и регистрация причин внутренних ошибок.
### Modified Capabilities
<!-- Нет: формат и поведение API для клиента не меняются. -->
## Impact
- `backend/internal/config` (секция `Log` + env), `backend/cmd/server/main.go` (сборка handler из конфига).
- `backend/internal/app` (middleware логирования), `backend/internal/httpx` (регистрация внутренних ошибок).
- `.env.example`, `README.md`.
- API, схема БД и хранилище не меняются. При дефолтном `LOG_LEVEL=info` объём обычных
логов почти не растёт: access-строки и 4xx остаются на уровне `debug`.