[observability][follow-up #355] route-лейбл содержит сырые имена ассетов с билд-хэшами (/assets/chunk-*.js) — неограниченная кардинальность #362
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?
Суть
Приёмка метрик (#355) выявила нарушение собственного требования «route — только темплейты, bounded cardinality»: в
http_request_duration_secondsлейблrouteсодержит сырые имена статических файлов с билд-хэшами:Каждый деплой генерирует новый набор хэшированных имён → серия лейблов растёт с каждым билдом навсегда (retention VM — 90 дней, деплоев в день бывает много). Это классическая утечка кардинальности, от которой защищались в API-роутах.
API-роуты при этом корректные (темплейты/статические пути), SSE исключён — проблема только со статикой, которую Fastify отдаёт как wildcard-роут: похоже, для static-хендлера
req.routeOptions.urlпуст и в лейбл попадает сырой URL (при том что для 404 уже есть схлопывание вunknown).Что нужно
Схлопывать статику в один темплейт: всё, что отдаёт static-модуль (нет
routeOptions.urlили путь начинается с/assets/,/brand/,/locales/и т.п.) →route="/assets/*"(илиstatic). Либо вовсе не наблюдать статику в гистограмме — edge-латентность статики уже измеряет Traefik (traefik_router_request_duration_*).Прочее из приёмки (не дефекты, для сведения)
bullmq_job_duration_secondsрегистрируется лениво — серии появляются после первой завершённой джобы. ОК.bullmq_queue_depth{queue="search"}был 1893 после рестартов — разгребается; выражение алерта queue-growing переоценим по живому поведению.{events:[...]}→ строка вclient_metrics).Проверил по коду — диагноз по эффекту верный, но механизм другой, и это важно для фикса.
Корень:
req.routeOptions.urlдля ассетов НЕ пуст.@fastify/staticзарегистрирован сwildcard: false(static.module.ts#L74), а в этом режиме плагин регистрирует каждый файл из dist как отдельный Fastify-роут при старте. То есть/assets/chunk-3OPIFGDE-CJOt9nr5.js— это и есть «темплейт роута», просто роутов столько, сколько файлов, и их имена меняются каждым билдом. Схлопывание 404→unknownв http-metrics.hook.ts#L13-L16 сюда не срабатывает, потому что роут честно матчится.Фикс — одна функция (
resolveRouteLabel): весь API живёт под/api/, всё остальное (ассеты, локали, иконки, wildcard-рендер*) — статика, чью edge-латентность и так меряет Traefik (traefik_router_request_duration_*):Плюс дописать кейс в существующий route-label юнит: ассетный путь →
static,/api/pages/:id→ без изменений, 404 →unknown. Существующие ~25 мусорных серий сами уйдут за retention (90 дней) — чистить VM руками не нужно.