request-analytics

Аналітика запитів (Request Logs)

src/golden/clickhouse/ (RequestLogMiddleware, RequestLogRepository, RequestLogController, UserNameResolver) — лог усіх HTTP-запитів сервісу в ClickHouse + ендпоінти аналітики для сторінки технічного відділу.

Суть

Кожен HTTP-запит до golden пишеться в ClickHouse-таблицю golden_request_logs (хто, яку роуту, з яким результатом і за скільки мс). Поверх цього — чотири ендпоінти аналітики: дерево роль → юзер → роут, гнучка агрегація за обраним виміром, дістінкти для динамічних фільтрів і сирі запити по одному роуту (дрілл-даун). Споживач — сторінка «Request Analytics» у stack-client (технічний відділ).

Use cases

Технічний відділ або директор дивиться картину використання сервісу: рейтинг юзерів по кліках (з фільтром по ролях і конкретних роутах — наприклад, тільки «важливі для оцінки роботи» запити), динаміку навантаження по днях, найнавантаженіші ендпоінти.

Числа

ЩоЗначення
Буфер записуфлаш кожні 60 с або при 500 рядках; максимум 10 000 рядків у памʼяті (далі скидаються)
ЗберіганняTTL 2 місяці (місячні партиції)
Кеш імен юзерів10 хв у памʼяті (включно з негативними результатами)
Ліміт відповіді агрегації1000 рядків
Ліміт списків роутів/юзерів у фільтрахтоп-500 за викликами
Ліміт дрілл-дауну сирих запитівдефолт 100, максимум 500

Логіка

  1. Запис. Middleware (після auth) перехоплює відповідь, бере роль/id юзера з токена, нормалізує URL (числові id / ObjectId / UUID → :id, без query) і кладе рядок у буфер. Реальний результат береться з тіла відповіді (success/statusCode/context — бо HTTP-статус у проєктній конвенції завжди 200). Запис fire-and-forget — на латентність відповіді не впливає; якщо ClickHouse лежить, рядки дропаються, запити юзерів не страждають.
  2. Агрегація (/stats). Один запит з виміром групування: рейтинг юзерів / топ роутів / динаміка по днях / зріз по ролях. Опційні фільтри: ролі, роути (пара METHOD /route), юзери. Для виміру «юзер» відповіді збагачуються іменами.
  3. Імена з RMQ. У таблиці лише stack-id. Резолвер батчить промахи кешу по ролях і питає stack-сервіс (StackOperatorFindMany, StackSupervisorFindMany, StackTopManagerFindMany, StackClientManagerFindMany). Ролі без такого RPC — director, technical_department, hr, recruiter — лишаються з сирим id; анонімні запити підписуються Anonymous. Фейл RMQ не валить відповідь — просто сирі id без кешування.
  4. Фільтри (/filters). Дістінкти за період: ролі, пари method+route і юзери (з іменами, як у п.3) — фронт будує мультиселекти з реальних даних, а не хардкоду. Опційний фільтр за ролями каскадно звужує списки юзерів і роутів («обрав роль → бачиш її юзерів»); список ролей завжди повний.
  5. Дрілл-даун (/requests). Сирі рядки логу по одному роуту: час, юзер (з іменем), статус, текст помилки, тривалість. Сортування — найновіші або найдовші, опційно тільки помилки; дефолт 100 рядків, максимум 500. На сторінці відкривається кліком по рядку «Top routes» і успадковує застосовані фільтри періоду/ролей/юзерів.

Доступ до всіх трьох ендпоінтів: director, technical_department.

Перелік ендпоінтів — у Swagger, тег Request Logs.

Нюанси

  • Анонімні запити (без токена або з невалідним токеном) логуються з порожніми роллю/id — у дереві /usage і зрізі по ролях вони видимі як окрема «порожня» роль. Порожній рядок — валідне значення фільтрів ролей/юзерів (опція «anonymous» на фронті): можна відібрати тільки анонімний трафік і подивитись його роути. Розрізнити окремих анонімів неможливо — IP не логується, всі злипаються в одного «Anonymous».
  • Нормалізація роутів захищає ClickHouse від вибуху кардинальності, але означає, що в аналітиці не видно конкретних id у URL — тільки шаблон роуту.
  • Період понад 2 місяці мовчки віддасть порожній хвіст — старі партиції зрізані TTL.
  • Негативний кеш імен: юзер, якого stack-сервіс не знає, не передзапитується 10 хв. Тимчасовий фейл RMQ навмисно не кешується.

Зв’язки

  • Читає: golden_request_logs (див. index)
  • Викликає: stack-сервіс через RMQ (Stack*FindMany) для імен
  • Оновлює: сторінку «Request Analytics» технічного відділу в stack-client