---
title: "Мониторинг и аналитика"
description: "Проверки состояния, собственная аналитика (включая personal_page_view), Web Vitals, структурированные логи и опциональный Docker Prometheus"
locale: "ru"
---
# Мониторинг и аналитика

> **Info**
> Фильтруйте по **Founder** / **Developer** в боковом меню документации. Источники мониторинга: `app/api/health`, `app/api/analytics/*`, `lib/logger.ts`, `public/scripts/analytics.js` + `RingAnalyticsBeacon`, и админ-интерфейс аналитики. Отдельной страницы `features/analytics` нет — эта статья является обзором аналитики во всём Ring.

Ring Platform сохраняет **собственную телеметрию** в PostgreSQL (JSONB), предоставляет **эндпоинт для проверки состояния контейнера**, а также **структурированные серверные логи**. Сторонние APM (Sentry, Vercel Analytics) опциональны через переменные окружения и не обязательны для базовой работы.

## Уровни мониторинга (реализовано)

| Уровень | Механизм | Основной сигнал |
|---------|----------|-----------------|
| **Liveness** | `GET /api/health` (+ `HEAD`) | Процесс активен, предупреждения env, память |
| **UX-производительность** | `WebVitalsProvider` → `POST /api/analytics/web-vitals` | LCP, CLS, INP, TTFB, FCP |
| **События продукта** | `analytics.js` + `RingAnalyticsBeacon` → `POST /api/analytics/app` | Сессии, загрузки страниц, кастомные события (`analytics_events`) |
| **Публичные профили** | `recordPersonalPageView` → `personal_page_view` | Уникальные визиты 24ч/7д по ролям на `/{username}` |
| **Клиентские ошибки** | `POST /api/analytics/errors` | Stacktrace, компонент, уровень важности |
| **Админ-панель** | `/admin/analytics` | `getPlatformAnalytics()`, включая `personalPages` |
| **Realtime connectivity** | `/api/tunnel/ping`, `/api/tunnel/heartbeat` | Задержка туннеля, состояние сессии |
| **Серверные логи** | `lib/logger.ts` | JSON строки в stdout (`LOG_LEVEL`) |
| **Опциональная инфраструктура** | Docker-профиль `monitoring` | Prometheus + Grafana (только локально) |

### For founders

## Зачем операторам нужен мониторинг

Клон Ring сочетает **авторизацию**, **маркетплейс-данные**, **платежи** и **уведомления в реальном времени**. Тихие сбои проявляются как “сайт грузится, но заказы не синхронизируются” — не красная ошибка. Уникальные посещения личных страниц показывают, востребованы ли профили участников без учёта просмотров владельцем.

### На что смотреть оператору (без кода)

  
- **[Эндпоинт проверки здоровья](/docs/deployment/docker.md)** — Проверяйте `GET /api/health` балансёром или сервисом мониторинга: `503` означает Degraded (часто отсутствует `AUTH_SECRET`).

  
- **[Админ-аналитика](/docs/features/admin.md)** — **Admin → Analytics**: количество пользователей, медианы Web Vitals, последние клиентские ошибки и личные страницы (топ-профили и разрез по ролям).

  
- **[Публичные профили](/docs/features/public-profile.md)** — Владельцы видят статистику уникальных визитов за 24ч и 7д в виджете личной страницы.

  
- **[Связка с резервным копированием](/docs/deployment/backup.md)** — Мониторинг сообщает *когда* что-то сломалось, резервные дают понять, *что* можно восстановить.

### Типичные сценарии тревог

- **Health становится `degraded`** — отсутствует критическая переменная окружения после деплоя, проверьте секреты прежде, чем винить Postgres.
- **Рост показателей Web Vitals со значением `poor`** — проблема с CDN, размерами изображений или SSR; сопоставьте с релизом (`BUILD_DATE` / `GIT_COMMIT` внутри health JSON, если выставлено).
- **Всплеск в `analytics_errors`** — поломан клиентский бандл или сторонний скрипт; последние сообщения видны в админке.
- **Массовые обрывы туннелей** — см. [транспорт в реальном времени](/docs/architecture/real-time.md); часто связано с edge/WSS, а не базой данных.

> **Tip**
> Определите **кто реагирует на тревоги** (оператор или разработчик) и **что считается “упавшим”** для вашего клона — Ring OSS не включает интеграцию с PagerDuty, вы подключаете проверки к своему провайдеру.

### For developers

## Архитектура

```mermaid
flowchart LR
  Browser[Браузер / PWA]
  WV[WebVitalsProvider]
  Beacon[RingAnalyticsBeacon]
  Script["/scripts/analytics.js"]
  Profile["recordPersonalPageView"]
  API["/api/analytics/*"]
  ADB[analytics-db.ts]
  PG[(PostgreSQL JSONB)]
  Browser --> WV --> API
  Browser --> Beacon --> Script --> API
  Profile --> ADB
  API --> ADB --> PG
  Admin["/admin/analytics"] --> ADB
```

### Health check — `app/api/health/route.ts`

Возвращает JSON: `status` (`healthy` | `degraded` | `unhealthy`), аптайм, память, определяет `services.database` (`postgresql` или `firebase`), опциональный блок контейнера. Отсутствие `AUTH_SECRET` = `degraded` + HTTP **503**.

{`curl -sS https://your-clone.example/api/health | jq .
curl -I https://your-clone.example/api/health   # HEAD — 200 если работает`}

### Клиентский маяк (верифицируемый)

| Компонент | Путь |
|-----------|------|
| Скрипт | `public/scripts/analytics.js` — батчит в `POST /api/analytics/app` через `sendBeacon` / fetch; API: `window.ringAnalytics` |
| Интеграция в приложении | `components/providers/ring-analytics-beacon.tsx` — подключает скрипт, вызывает `pageView` при изменениях pathname/searchParams |
| Монтирование | `components/providers/app-client-shell.tsx` |

Легаси `public/scripts/app-analytics.js` в репо есть, но **не используется** как рабочий источник — не документируйте его.

### API аналитики

| Роут | Метод | Аутентификация | Хранится в |
|------|-------|----------------|------------|
| `/api/analytics/web-vitals` | POST | Опционально | `web_vitals` |
| `/api/analytics/web-vitals` | GET | Админ | Запрос по `web_vitals` или сводка по `?scope=platform` |
| `/api/analytics/app` | POST | Опционально | `analytics_events` |
| `/api/analytics/errors` | POST | Опционально | `analytics_errors` |
| `/api/analytics/errors` | GET | Админ | Список ошибок |
| `/api/analytics/device` | POST | Сессия | `user_device_telemetry` |
| `/api/analytics/platform-stats` | GET | Админ | Суммарные показатели: users, entities, opportunities |
| `/api/analytics/navigation` | POST | Опционально | Заглушка — возвращает `{ ok: true }`, без сохранения |

Реализация: `features/analytics/lib/analytics-db.ts` (`insertAnalyticsEventBatch`, `insertWebVitalsRecord`, `insertAnalyticsErrors`). Клиент: `components/providers/web-vitals-provider.tsx` (`useReportWebVitals` из `next/web-vitals`), буферизация показателей в один POST раз в ~1.5с (INP заменяет FID).

### События личных страниц

| Компонент | Путь |
|-----------|------|
| Тип события | `personal_page_view` |
| Запись | `features/analytics/lib/personal-page-analytics.ts` → `recordPersonalPageView` |
| Вызов | `app/[locale]/[username]/page.tsx` — владельцы пропускаются |
| Виджет владельца | `getPersonalPageViewStats` (`features/auth/services/personal-page-stats.ts`) |
| Админ | `getPersonalPagePlatformStats` → `PlatformAnalyticsSummary.personalPages` |
| Включение в метрику | `personal_page_view` агрегируется с `page_view`, `app_load`, `docs_page_view` в админке |

Подробнее и расчёт уникальности по ролям: [Публичные профили](/docs/features/public-profile.md).

### Таблицы базы данных

Включены в `data/schema.sql` и миграцию `017_ring_analytics_schema.sql`:

- `analytics_events` — пакетная клиентская телеметрия и серверные строки `personal_page_view`
- `web_vitals` — батчи метрик Web Vitals
- `analytics_errors` — клиентские ошибки

### Отключить хранение данных (privacy / нагрузочное тестирование)

{`ANALYTICS_DISABLE_STORAGE=true`}

Если указано, роуты только подтверждают приём, но не пишут в базу данных (`isAnalyticsStorageDisabled()`). Запись персональных страниц также отключается.

### Структурированные логи

{`import { logger } from '@/lib/logger'

logger.info('Subscription created', { userId })

logger.warn('syncDiscovery: tunnel publish failed', { channel, error })

logger.error('Failed to create subscription', { userId, error })`}

Переменные: `LOG_LEVEL` (`debug` | `info` | `warn` | `error`; по умолчанию `info` в production, `warn` в development), `LOG_SILENT=true` для полного молчания. Логи выходят JSON-строками в stdout; в development скрываются шумные JWT/SSE.

### Внешние APM (опционально)

Добавьте переменные в `.env.local.template` или `docker.env.template`:

- `SENTRY_DSN` — подключите вашу интеграцию с Sentry Next.js (автоматически не включена)
- `NEXT_PUBLIC_ANALYTICS_ID`, `VERCEL_ANALYTICS_ID` — только для Vercel-хостингов

### Realtime-probes

| Роут | Назначение |
|------|------------|
| `POST /api/tunnel/ping` | Аутентифицированный pong c timestamp |
| `POST /api/tunnel/heartbeat` | Поддержание соединения |

Подробнее — [Tunnel protocol](/docs/features/tunnel-protocol.md).

### Мониторинг кронов и пайплайнов

Крон-роуты (`/api/cron/*`) закрыты без `CRON_SECRET`. Например, `GET /api/cron/email-analytics` запускает pipeline `email-analytics`.

### Опциональный Docker Prometheus + Grafana

{`docker compose --profile monitoring up -d`}

Сервисы: `ring-prometheus` (:9090), `ring-grafana` (:3001). Конфиг: `docker/prometheus/prometheus.yml`.

  Встроенное задание Prometheus обращается к `/api/metrics`, которого **нет** в этой версии, и парсит `/api/health` как JSON (не Prometheus-формат). Используйте как основу для своей реализации.

### Вход в админ-панель

Серверная страница: `app/[locale]/admin/analytics/page.tsx` — доступна только при `isPlatformAdmin`, загружает `getPlatformAnalytics('7d')` включая `personalPages`.

## Связанные материалы

  
- [features/public-profile](/docs/features/public-profile.md) — По этому же процессу: уникальные визиты personal_page_view и фильтрация владельцев.

  
- [deployment/backup](/docs/deployment/backup.md) — Далее: восстановление после выявленных инцидентов.

  
- [deployment/performance](/docs/deployment/performance.md) — См. также: оптимизация Web Vitals и performance-операции.

  
- [deployment/environment](/docs/deployment/environment.md) — Зависит от: CRON_SECRET, LOG_LEVEL, ANALYTICS_DISABLE_STORAGE и, при необходимости, Sentry.

  
- [architecture/real-time](/docs/architecture/real-time.md) — Подробности: туннельные транспорты и heartbeat-механизмы.

  
- [features/admin](/docs/features/admin.md) — Далее: вход в админку по адресу /admin/analytics.
