Мониторинг Яндекс.Метрики в Grafana через Docker Compose: Создание кэширующего API-прокси
Практическое руководство по развертыванию инфраструктуры сбора данных с помощью Flask, Infinity Datasource и автоматического провижнинга.
Современная веб-аналитика требует не просто сбора данных, но и их удобной визуализации в единых корпоративных интерфейсах. Популярный сервис Яндекс.Метрика предоставляет мощное API для извлечения сырых данных и агрегированных показателей. Однако прямая интеграция Grafana с API Яндекс.Метрики сопряжена с рядом трудностей: жесткие лимиты на количество запросов (rate limits), задержки сети и необходимость безопасного хранения токенов авторизации.
Решением этой проблемы является создание промежуточного кэширующего прокси-сервера. В данной статье мы подробно разберем готовую архитектуру на базе Docker Compose, которая автоматически разворачивает стек из веб-интерфейса Portainer для управления контейнерами, легковесного прокси на Python (Flask) и преднастроенной Grafana с плагином Infinity.
Архитектура и компоненты системы
Представленный файл конфигурации docker-compose.yml объединяет три изолированных сервиса, взаимодействующих внутри внутренней сети Docker:
- Portainer (portainer/portainer-ce): Графическая панель для управления контейнерами, томами и сетями. Позволяет быстро отслеживать состояние системы без использования CLI.
- Metrika-proxy (python:3.11-slim): Сердце системы. Самостоятельное микроприложение на Flask, которое запрашивает данные у Яндекса, фильтрует их, обрабатывает цели и сохраняет в оперативной памяти на заданное время (TTL).
- Grafana (grafana/grafana-oss): Платформа визуализации, в которую автоматически внедряются настройки источника данных и дашборда при старте контейнера.
Глубокий разбор кэширующего прокси-сервера
Компонент metrika-proxy решает критически важную задачу оптимизации запросов. API Яндекс.Метрики накладывает квоты на количество обращений в сутки и в секунду. Если дашборд Grafana будут одновременно просматривать несколько сотрудников, или если настроить слишком частое обновление панелей, токен быстро заблокируется.
Внутри контейнера через директиву entrypoint динамически создается скрипт app.py. При обращении к эндпоинту /metrics приложение проверяет время, прошедшее с момента последнего успешного запроса:
if not cached_data or (current_time - last_fetch_time) > CACHE_TTL:
data = fetch_from_yandex()
if data:
cached_data = data
last_fetch_time = current_time
Параметр CACHE_TTL передается через переменные окружения и по умолчанию равен 300 секундам (5 минут). Это означает, что как бы часто Grafana ни опрашивала прокси, реальные запросы к API Яндекса будут уходить не чаще одного раза в 5 минут.
Прокси-сервер выполняет три параллельных запроса к API:
- Источники трафика (пресет
sources_summary) — для анализа переходов из поисковых систем, рекламы или соцсетей [1]. - Технические платформы (метрика
ym:s:visitsс группировкой по девайсам) — для понимания распределения аудитории между mobile и desktop [1]. - Достижение целей (динамический парсинг
GOALS_LIST) — прокси разбивает строку с ID целей, формирует кастомные метрики видаym:s:goal[ID]reachesи возвращает их в структурированном виде [1].
Автоматизация Grafana: Provisioning без ручной настройки
Одной из главных проблем при развертывании мониторинга является рутина: создание источника данных, копирование URL, импорт JSON-схем дашбордов. В данном Compose-файле этот процесс полностью автоматизирован с помощью механизма Provisioning в Grafana.
В блоке grafana скрипт инициализации создает конфигурационные файлы прямо перед запуском основного бинарного файла сервера. Во-первых, объявляется плагин Infinity Datasource. Этот плагин является универсальным парсером JSON, CSV и XML, позволяя превратить любой HTTP-ответ в структурированные таблицы Grafana без использования тяжелых баз данных (InfluxDB, Prometheus). Конфиг infinity.yaml жестко прописывает адрес нашего прокси:
isDefault: true
Во-вторых, создается провайдер дашбордов provider.yaml, который указывает Grafana непрерывно сканировать директорию /var/lib/grafana/dashboards. С помощью монтирования томов (volumes) готовый файл dashboard.json с локального хоста прокидывается внутрь контейнера. Пользователю достаточно запустить сборку, открыть браузер и перед ним сразу появится готовый рабочий дашборд. Дополнительно включен анонимный доступ с ролью Viewer, что позволяет просматривать графики внутри локальной сети без ввода логина и пароля.
Инструкция по развертыванию стека
Для запуска системы выполните следующие шаги:
-
Создайте в одной директории файл
docker-compose.ymlс предоставленным кодом и пустой (или преднастроенный) файлdashboard.json. -
Рядом создайте файл переменных окружения
.envи заполните его вашими данными:YANDEX_TOKEN=AgAAAAA... (ваш OAuth-токен)
COUNTER_ID=12345678 (номер счетчика)
CACHE_TTL=300
METRICS=ym:s:visits,ym:s:pageviews,ym:s:users
GOALS_LIST=334455,667788 (ID целей через запятую)-
Выполните команду для запуска всех контейнеров в фоновом режиме:
docker compose up -d
После запуска команды Docker Compose автоматически скачает необходимые образы, создаст изолированную внутреннюю сеть и инициализирует три микросервиса. Скрипты авто-провижнинга внутри контейнера Grafana сразу же подготовят конфигурационные файлы, избавляя вас от необходимости настраивать подключение к источнику данных вручную через графический интерфейс.
Доступные интерфейсы и проверка статуса
После успешной инициализации окружения в вашей локальной сети разворачивается полноценная инфраструктура мониторинга. Вы можете проверить работоспособность каждого компонента, обратившись к соответствующим портам:
Сервис Порт Назначение для администратора Grafana 3000 Просмотр аналитических дашбордов (вход настроен без пароля в режиме Viewer) Portainer 9000 / 9443 Администрирование контейнеров, перезапуск сервисов, мониторинг логов Flask Flask Proxy 5000 Отладка и проверка сырого JSON-ответа на технической странице /metricsПринцип работы плагина Infinity Datasource
Ключевое преимущество связки нашего прокси и Grafana заключается в использовании плагина Infinity (
yesoreyeram-infinity-datasource). В отличие от классических источников данных (таких как Prometheus, InfluxDB или PostgreSQL), Infinity не требует развертывания полноценной базы данных и написания сложных SQL/PromQL-запросов.Когда пользователь открывает дашборд, Grafana отправляет HTTP-запрос к нашему контейнеру
metrika-proxy:5000/metrics. Плагин Infinity получает структурированный JSON-ответ, содержащий блокиtotals,sources,devicesиgoals. Прямо в интерфейсе Grafana, используя синтаксис JSON Path, вы можете на лету трансформировать эти узлы в плоские таблицы и графики. Например, для построения круговой диаграммы по типам устройств достаточно указать корень парсинга как$.devicesи выбрать нужные ключи для метрик и подписей.Безопасность данных и изоляция окружения
Развертывание аналитического стека по предложенной схеме отвечает базовым требованиям корпоративной безопасности и гигиены разработки:
-
Изоляция секретов: Ваш приватный OAuth-токен Яндекса и идентификаторы счетчиков не зашиты в код и не прописываются в конфигурационных файлах Grafana. Они хранятся исключительно в локальном файле
.env, который должен быть добавлен в.gitignore. -
Защита от компрометации API: Контейнер
metrika-proxyвыступает в роли единственной точки контакта с внешним миром. Grafana и Portainer общаются с ним внутри изолированной сети Docker. Внешний доступ к порту 5000 на боевых серверах можно полностью закрыть с помощью файрвола, оставив открытым только порт Grafana (3000). -
Контроль доступа: Включение анонимного просмотра (
GF_AUTH_ANONYMOUS_ENABLED=true) с рольюViewerбезопасно внутри локальной сети или VPN. Пользователи могут видеть графики, но не имеют технической возможности изменить логику запросов, сломать панели или извлечь исходный токен авторизации.
Перспективы масштабирования и кастомизации
Архитектура на базе Flask-прокси является расширяемой. Если в будущем вашей компании потребуется объединить отчеты из Яндекс.Метрики с данными из других систем (например, AmoCRM, Яндекс.Директ, VK Реклама или внутренней базы данных), вам не придется менять конфигурацию Grafana или искать новые плагины.
Достаточно дописать несколько функций в скрипт
app.pyвнутри контейнера прокси, чтобы он параллельно опрашивал другие API, агрегировал данные в один общий JSON-объект и отдавал его по требованию. Кэширование (TTL) защитит все сопутствующие сервисы от перегрузки, обеспечивая моментальный рендеринг графиков в Grafana.Заключение
Использование Docker Compose для развертывания систем мониторинга позволяет за несколько минут развернуть отказоустойчивую, преднастроенную среду. Создание промежуточного кэширующего слоя на Python решает главную проблему веб-аналитики — обход лимитов API сторонних сервисов. Автоматический provisioning превращает Grafana из сложного в настройке инструмента в легковесный и переносимый компонент вашей IT-инфраструктуры, готовый к работе сразу после запуска контейнеров.
-
Выполните команду для запуска всех контейнеров в фоновом режиме: