# Миграция klog/zap → slog

## Контекст

`tools/klog` — тонкая обёртка над `go.uber.org/zap`, которая является точкой входа для логирования во всех сервисах.
Модуль: `gitlab.adsw.io/platform/tools/v3`, потребляется 15+ репозиториями через vendor.

## Текущий формат логов (сохраняется)

```json
{"level":"info","caller":"main.go:42","msg":"starting service","source":"accounting","date":"2026-05-08T12:34:56.789+03:00"}
{"level":"error","caller":"auth.go:28","msg":"fetching user profile","source":"accounting","date":"2026-05-08T12:34:56.789+03:00","error":"context deadline exceeded"}
```

Поля: `level` (строчными), `caller`, `msg`, `source` (при init), `date` (ISO 8601 в каждом вызове через `cookFields()`).

Формат воспроизводится через `log/slog` с кастомным JSON handler'ом + `ReplaceAttr` для приведения уровней к нижнему регистру.

---

## Шаг 3 — api-gateway (отдельно, не блокирует остальное)

`api-gateway` держит `*zap.Logger` как поле структуры `Application` и передаёт его
в `log.NewZapLogger()` из библиотеки `jensneuse/abstractlogger`. Это **независимо от klog**
и не блокирует миграцию остальных сервисов.

| # | Файл | Проблема | Сложность |
|---|------|----------|-----------|
| 35 | `api-gateway/pkg/application/application.go` | Поле `ZapLogger *zap.Logger` — `abstractlogger` требует zap. Нужно либо оставить zap только здесь, либо заменить `abstractlogger` на slog-совместимый аналог | Высокая |
| 36 | `api-gateway/cmd/http/main.go` | `klog.InitLogger()` возвращает `*zap.Logger` сейчас, после миграции вернёт `*slog.Logger` — нужно отвязать инициализацию zap от klog | Средняя |

---


| Сервис      | Готовность | Пролит |
| ----------- | :--------: | :----: |
| async       |            |        |
| document    |            |        |
| mailer      |            |        |
| private     |            |        |
| public      |            |        |
| unisender   |            |        |
| api-gateway |            |        |
| mq-tools    |            |        |


