хранилище переехало с PocketBase на SQLite со своим каталогом файлов
- база своя: два пула, захват одним UPDATE ... RETURNING, шаги схемы на goose под файловым замком, одна миграция начальной схемы вместо семи прежних - транспорт переписан на net/http: свои слои, свой ограничитель частоты, отдача файла с проверкой владельца; панель /_/ и пространство /api/ исчезли - по находкам ревью: журнал не пишет путь под корнем приложения, ключ бюджета читается справа налево, узнавание известного идёт читающим пулом
This commit is contained in:
@@ -105,12 +105,12 @@ stdlib-логом в поток ошибок. Это выбор, а не дол
|
||||
|
||||
| Когда добавляем | Поля |
|
||||
| --- | --- |
|
||||
| на входящий HTTP-запрос | `transport` (`http`), `http.method`, `http.route`, `http.status_code`, `duration_ms` |
|
||||
| на входящий HTTP-запрос | `transport` (`http`), `http.method`, `http.route`, `http.status_code`, `duration_ms`, `http.path_length`. **Запрошенного пути в строке нет ни под каким корнем**: его выбирает спрашивающий, и дословная запись сделала бы журнал местом, куда аноним пишет свой текст. В `http.route` идёт маршрут из закрытого перечня — точный адрес наблюдения либо образец адреса приложения, — а всё прочее обозначается одним общим значением |
|
||||
| на узнавание пришедшего | `http.peer_addr` — адрес того, кто открыл соединение; плюс `account_id` на заведении учётной записи. **Значения заголовка в строке нет**: им довольно назваться, чтобы стать этим человеком, а с недоверенного адреса его пишет аноним |
|
||||
| на задачу | `capability` (значения — по именам заведённых capability в `openspec/specs/`), `record_id`, `file_id`, `source` |
|
||||
| на запись об ошибке | `error` |
|
||||
| на вызов внешнего сервиса | `ext.service`, `ext.operation`, `ext.status_code`, `duration_ms`, `retry` |
|
||||
| на запрос, отданный приложению | `webapp.outcome` (`markup`, `asset`, `failure` — перечень закрыт), `http.path_length`. Самого пути в строке нет: его выбирает спрашивающий, и дословная запись сделала бы журнал местом, куда аноним пишет свой текст. Вместо пути в `http.route` стоит `<приложение>` |
|
||||
| на запрос, отданный приложению | `webapp.outcome` (`markup`, `asset`, `failure` — перечень закрыт). Правило о пути — строкой выше, общее: вместо пути в `http.route` стоит `<приложение>` |
|
||||
| на подъёме сервиса | `webapp.build` — отпечаток вшитой сборки; им «не та сборка» отличается от «той» |
|
||||
|
||||
Не заводим `service.*` и `host.*` — для одного бинарника на одном хосте это шум.
|
||||
@@ -205,7 +205,7 @@ Object Storage и опрос операции не логируются ника
|
||||
## HTTP и проверка здоровья
|
||||
|
||||
- Входящие HTTP-запросы логируем с полями `http.method`, `http.route`,
|
||||
`http.status_code`, `duration_ms`, `transport`.
|
||||
`http.status_code`, `duration_ms`, `http.path_length`, `transport`.
|
||||
- **Поле, которое уже даёт логгер с подставленным ключом, руками не
|
||||
доклеиваем.** Иначе в JSON получается дублирующийся ключ, и строгий
|
||||
потребитель молча оставит одно из значений. Правило проверяется чтением,
|
||||
@@ -214,13 +214,12 @@ Object Storage и опрос операции не логируются ника
|
||||
периодически, на `INFO` они забивают разбор шумом. В продакшене при базовом
|
||||
`INFO` они не пишутся.
|
||||
|
||||
Расхождения здесь больше нет: слой журналирования запросов свой,
|
||||
`cmd/transcriber`, хук `OnServe` — вместе с gin ушёл и `sloggin`. `/health` и `/metrics`
|
||||
идут на `DEBUG`, то есть при боевом `INFO` не пишутся вовсе.
|
||||
Расхождения здесь больше нет: слой журналирования запросов свой —
|
||||
`internal/controller/http`, `journal.go`. `/health` и `/metrics` идут на `DEBUG`,
|
||||
то есть при боевом `INFO` не пишутся вовсе.
|
||||
|
||||
Хранилище ведёт **свой** журнал запросов в собственной таблице, и он виден
|
||||
владельцу в панели. Заменой потоку процесса он не служит: в журнал контейнера,
|
||||
по которому разбирают отказы, эта таблица не попадает.
|
||||
**Журнал у сервиса один.** Второй, куда встроенное хранилище клало путь целиком
|
||||
вместе с адресом отправителя, ушёл вместе с самим хранилищем 2026-08-22.
|
||||
|
||||
## Безопасность: что не логируем
|
||||
|
||||
@@ -257,7 +256,7 @@ Object Storage и опрос операции не логируются ника
|
||||
(`filepath.Ext`), поэтому имя `запись.тайное-слово` отдаёт приватный хвост
|
||||
расширением. В журнал оно идёт **собственным полем** строки приёма — это
|
||||
объявленное изъятие инварианта приватности ([CLAUDE.md](../../CLAUDE.md),
|
||||
«Инварианты»); ни имени файла в хранилище, ни пути к нему в журнале нет вовсе
|
||||
«Инварианты»); ни имени файла на диске, ни пути к нему в журнале нет вовсе
|
||||
(норма — `openspec/specs/intake`). Наружу — в метку метрики — хвост не выходит:
|
||||
там расширение приводится к перечню известных форматов. Остаток описан в
|
||||
[../security.md](../security.md).
|
||||
|
||||
Reference in New Issue
Block a user