[observability] Дев-часть перф-метрик: /metrics на :9464 (prom-client), POST /api/telemetry/vitals + таблица client_metrics, кастомные метрики редактора #355
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Суть
Инфраструктурная половина метрик уже развёрнута (стек gitmost на island: VictoriaMetrics + Grafana + postgres/redis-экспортеры, Traefik-метрики, дашборд «gitmost perf» на 9 панелей, 6 алертов в Telegram). Скрейпер уже ходит на
docmost:9464— таргетgitmost-appкрасный, потому что дев-части не существует. Панели INP/латентности печати/открытия страницы пустые, потому что нет таблицыclient_metricsи телеметрии клиента.Эта ишью — недостающая половина. Контракт зафиксирован развёрнутой инфраструктурой и менять его дороже, чем соблюсти:
METRICS_PORT=9464, отдельный от :3000, не публикуетсяhttp_request_duration_seconds{method,route,status},db_query_duration_seconds,bullmq_queue_depth{queue},bullmq_job_duration_seconds{queue}client_metrics(maintenance-контейнер делает суточныйGRANT SELECT … TO grafana_roиDELETEстарше 90 дней поcreated_at— ретенцию в приложении писать НЕ нужно)POST /api/telemetry/vitalsЗачем: без метрик эффект перф-комплекта (#340, #342–#344, #346, #348) недоказуем, а регрессии невидимы. Это базовая линия «до» для всех этих работ.
Границы изменения
apps/server(prom-client, второй HTTP-листенер, Kysely-хук, BullMQ-инструментация, telemetry-контроллер, одна миграция) +apps/client(web-vitals, кастомные метрики, батч-отправка). Поведение фич 1:1. Одна новая зависимость на сервере (prom-client), одна на клиенте (web-vitals).Решение
1. Сервер: prom-client на отдельном порту
collectDefaultMetrics()(event loop lag, GC, память — дашборд уже ссылается наnodejs_eventloop_lag_p99_seconds).onResponse-хуке:METRICS_PORT; поднять тривиальныйnode:http-сервер, отдающийregister.metrics()— метрики не существуют на основном порту вообще (Traefik-блок/metricsна публичном роутере уже стоит как страховка).logв database.module.ts →db_query_duration_seconds(у события естьqueryDurationMillis; лейбл — первый токен SQL: select/insert/update/delete, НЕ полный запрос).bullmq_queue_depth{queue}(опросgetJobCounts()раз в 15 с) +bullmq_job_duration_seconds{queue}из worker-событийcompleted/failed. Сразу покажет эффект дедупа из #348.onStoreDocumentв persistence.extension.ts →collab_store_duration_seconds(панели пока нет — добавится, имя согласовано).2. Сервер: приём виталов + миграция
POST /api/telemetry/vitals: публичный (шлют браузеры), но@Throttle, лимит тела ~16 КБ, максимум 50 событий в батче, whitelist имён метрик, insert одним батчем. Миграция:3. Клиент: web-vitals + кастомные метрики
web-vitals(attribution-сборка):onINP/onLCP/onCLS/onTTFB→ буфер →navigator.sendBeaconнаvisibilitychange:hiddenи по таймеру.Math.random() < 0.25→ sessionStorage-флаг); роуты — только темплейты (/s/:space/p/:slug), attr — селектор из attribution, обрезанный до 120 символов. Никаких заголовков страниц, слагов, текста.editor_tx_ms: обёрткаdispatchTransactionв page-editor — время синхронной части транзакции, слать только > 8 мс, сdoc_size. Это прямая метрика для #343.page_open_ms:performance.markна клике по строке дерева/ссылке →performance.measureпри первом рендере контента редактора. Метрика для local-first направления.longtask_ms:PerformanceObserver({type:"longtask"}), агрегированная сумма за окно.Крайние случаи
routeOptions.url— схлопывать вunknown), queue-имена — конечный список, никаких id в лейблах.onResponse-хук на стриминге даст длительность соединения, а не ответа — исключить stream-роуты из гистограммы (лейбл или skip), иначе p95 «испортится» долгоживущими соединениями.METRICS_PORTне задан (дефолт для чужих self-hosted) — метрики полностью выключены, ни листенера, ни коллекторов.created_at timestamptz, панели считают в UTC — совпадает с VM.Тесты / проверка
curl docmost:9464/metrics→ все 4 семейства метрик присутствуют; на :3000/metrics→ 404.gitmost-appв VM зеленеет; панели INP/editor_tx/page_open наполняются при семплированной сессии;SELECT count(*) FROM client_metricsрастёт, старше 90 дней — чистится (проверка через maintenance-лог).Вне скоупа
collab_store_duration_seconds— попросить DevOps добавить после выката.План работ
client_metrics+ telemetry-контроллер с лимитами.