Web Analytics
Privacy-first отслеживание pageview и Web Vitals для ваших доменов, хранящееся в ClickHouse и отображаемое в dashboard Skitflow.
Web Analytics требует плана Expert или Enterprise в Skitflow Cloud
или лицензионного feature observability в self-hosted установках.
Используется тот же ClickHouse кластер и те же настройки retention, что и
в Observability.
Web Analytics собирает pageviews и Web Vitals для каждого домена, для которого он включён. Данные хранятся в вашем ClickHouse — в self-hosted они не покидают вашу инфраструктуру, в cloud деплойментах хранятся в control plane Skitflow Cloud.
Включение аналитики для домена
- Откройте Web Analytics в сайдбаре dashboard и выберите приложение или Compose стек в селекторе.
- Карточка Domains покажет домены этого ресурса, у каждого свой переключатель.
- Включите переключатель для нужного домена. Skitflow создаст
siteIdдля него и перерендерит конфигурацию Traefik, подключив inject middleware для аналитики.
Отключение домена запускает тот же рендер Traefik и отсоединяет middleware.
siteId сохраняется, поэтому повторное включение того же домена не ломает
уже настроенные сниппеты.
Auto-inject работает только при SKITFLOW_WEB_ANALYTICS_AUTOINJECT=true и
никогда не применяется к доменам compose или приложениям на Kubernetes —
для них рендер конфига полностью пропускается. Для всего, кроме обычных
приложений на Traefik с включённым auto-inject, нужно вставить сниппет
вручную (см. ниже).
Сниппет beacon вручную
После включения домена карточка Domains показывает копируемый сниппет,
построенный из его siteId:
<script defer src="<skitflow-url>/va.js" data-site="<siteId>"></script>Вставьте это в <head> страницы отслеживаемого сайта. Это обязательно — не
опционально — для доменов Compose и приложений Kubernetes, поскольку
auto-inject для них никогда не запускается; для обычных приложений на
Traefik это запасной вариант на случай, если флаг auto-inject выключен.
Необходимое разрешение: observability.manage
API endpoints:
POST /api/trpc/webAnalytics.enable { "domainId": "<id>" }
POST /api/trpc/webAnalytics.disable { "domainId": "<id>" }
GET /api/trpc/webAnalytics.status?input={"domainId":"<id>"}status возвращает { enabled: boolean, siteId: string | null }.
Retention
Web Analytics использует тот же период retention, что настроен в Observability
Settings (по умолчанию: 30 дней). Параметр from в каждом запросе
автоматически ограничивается значением now − retentionDays — запросы за
данными старше окна retention возвращают пустой результат, а не ошибку.
Сырые события pageview и Web Vitals хранятся в ClickHouse с TTL 90 дней. Часовые pre-aggregated rollups обеспечивают эффективные app-wide запросы в пределах окна retention.
Данные dashboard
getAnalytics получает все одиннадцать карточек dashboard в одном запросе:
| Карточка | Описание |
|---|---|
viewsOverTime | Почасовое количество pageview за период |
topPaths | Топ 500 paths по количеству просмотров |
topReferrers | Топ 50 referring host (прямые / без referrer исключены) |
countries | Топ 50 стран по количеству pageview |
regions | Топ 50 регионов по количеству pageview |
cities | Топ 50 городов по количеству pageview |
devices | Топ 50 типов устройств (desktop, mobile, tablet, …) |
browsers | Топ 50 браузеров |
operatingSystems | Топ 50 операционных систем |
vitals | p75 Web Vitals по каждой метрике за период |
vitalsRatings | Количество good / needs-improvement / poor по каждой метрике |
API endpoint: GET /api/trpc/webAnalytics.getAnalytics
Обязательный input: { appId, from, to } — строки ISO 8601 datetime для from/to.
Опционально: serviceName (см. Per-service scope).
Необходимое разрешение: observability.read
Сводка метрик
getMetrics возвращает список top paths и сводку p75 Web Vitals в одном запросе
— более лёгкая альтернатива getAnalytics, когда нужны только эти две карточки.
API endpoint: GET /api/trpc/webAnalytics.getMetrics
Timeseries просмотров
getViewsTimeseries возвращает почасовой ряд views-over-time для одного сервиса.
Вид «Compare» разворачивает это в несколько запросов — по одному на каждый
compose сервис — и накладывает ряды как цветные линии.
API endpoint: GET /api/trpc/webAnalytics.getViewsTimeseries
Timeseries Web Vitals
getVitalsTimeseries возвращает p75 Web Vitals с разбивкой по времени.
Ширина bucket настраивается в целых часах (1–24); по умолчанию 1 ч —
нативная гранулярность rollup.
| Input | Тип | Описание |
|---|---|---|
appId | string | ID приложения или Compose стека |
from | datetime | Начало периода ISO 8601 |
to | datetime | Конец периода ISO 8601 |
bucketHours | int (1–24) | Ширина bucket rollup (по умолчанию: 1) |
serviceName | string | Опциональный фильтр по сервису |
API endpoint: GET /api/trpc/webAnalytics.getVitalsTimeseries
Оценки Web Vitals классифицируются как good, needs-improvement или poor по стандартным порогам Core Web Vitals.
Per-service scope
Все read endpoints принимают опциональный параметр serviceName, который
ограничивает результаты одним compose сервисом. Compose сервис может владеть
несколькими доменами, поэтому фильтр резолвится в набор значений siteId
для аналитически включённых доменов этого сервиса.
- Без
serviceNameвозвращаются app-wide данные по всем доменам из pre-aggregated 1 ч rollup. - Если у сервиса нет доменов с включённой аналитикой, возвращается пустой результат — не происходит fall back к app-wide данным.
Per-service запросы обращаются к сырым таблицам pageview_events /
web_vitals_events (rollup не хранит site_id), но всё равно ограничены тем
же окном retention, что и любой другой запрос. TTL 90 дней сырых данных —
это лишь физический потолок: в self-hosted он уменьшается до настроенного
значения retention, если оно меньше 90 дней.
Собираемые данные
Каждое событие pageview записывает:
| Поле | Примечания |
|---|---|
path | URL path (без query string) |
referrer_host | Хост referrer; пусто для прямых переходов |
country, region, city | GeoIP-резолв по IP клиента |
device_type | Определяется из user-agent |
browser | Определяется из user-agent |
os | Определяется из user-agent |
client_ip_hash | SHA-256 от IP клиента, обрезанный до 16 hex-символов — сохраняется только хеш, сырой IP никогда |
Каждое событие Web Vitals записывает имя метрики, значение, рейтинг, path и тип устройства. Сырой IP клиента не сохраняется.
Privacy
IP-адреса клиентов хешируются (SHA-256, обрезка до 16 hex-символов) перед сохранением — в ClickHouse записывается только хеш, сырой IP никогда. Cookies и fingerprinting не используются. В self-hosted установках все данные остаются на вашей инфраструктуре.