Привет всем! Меня зовут Антон Галич, я фронтенд-инженер в департаменте разработки Analytics Platform в Авито. Команда занимается разработкой и поддержкой платформы для сбора и доставки аналитики в Авито – Clickstream. В этой статье я рассказываю историю о том, как мы перевели аналитику для внутренних сервисов компании на нашу собственную платформу, отказавшись от стороннего решения Amplitude.

Дисклеймер: сущности, относящиеся к нашей платформе, далее в тексте называю, используя префикс cs-.
Что внутри статьи:
Почему нам понадобилось свое решение?
На какие аналоги мы ориентировались?
Реализация внутренней аналитики
Библиотека Clickstream-insights
Почему нам понадобилось свое решение?
Для аналитики фронтендов внутренних сервисов в Авито долгое время использовали Amplitude — мощный инструмент, который хорошо подходил владельцам внутренних сервисов. Его привлекательность – в простоте внедрения: достаточно подключить SDK, чтобы сервис начал отправлять дефолтные события (сессии, клики, просмотры страниц и так далее). Еще один плюс – возможность быстро строить визуализации и готовые дашборды в интерфейсе Amplitude без необходимости привлекать аналитиков и писать запросы. Это особенно удобно для команд, которым нужно оперативно получать выводы из данных.
Однако, несмотря на эту простоту, Amplitude имеет и свои существенные недостатки:
риски безопасности. Все аналитические данные уходили на внешние серверы, что создавало потенциальную угрозу конфиденциальности;
зависимость от стороннего вендора. Любые сбои в работе Amplitude могли негативно повлиять на аналитику сервисов, при этом не оставляя компании простого пути к исправлению ситуации;
уход Amplitude с российского рынка. С августа 2024 года инструмент стал доступен только через VPN и есть реальный риск полной блокировки сервиса.
Именно в августе 2024 года к нам пришли стейкхолдеры с вопросом: можно ли сделать свой инструмент, который сочетал бы простоту Amplitude, но оставался полностью под контролем Авито? Мы взялись за эту задачу.
Основные вызовы
Наш инструмент должен был отвечать трём ключевым требованиям:
быть простым в интеграции, чтобы различные команды без проблем могли переключиться с Amplitude на новое решение;
иметь удобный интерфейс для визуализации данных, чтобы команды могли анализировать результаты без привлечения аналитиков;
не зависеть от сторонних поставщиков, обеспечивая контроль над данными и минимизируя риск блокировок или утечек.
На какие аналоги мы ориентировались?
Перед тем как писать своё решение, мы рассмотрели альтернативы. Среди них:
Open Source-решения: Matomo, Posthog, Countly.
плюсы: бесплатные, безопасные (развёртывание на своих серверах), предоставляют доступ к исходному коду.
минусы: требуют настройки под наши нужды.
еще одна система логирования, незачем плодить одинаковые инструменты в рамках одной компании.
Российские коммерческие аналоги: Яндекс.Метрика, Roistat.
плюсы: простые в использовании и безопасные с точки зрения локализации;
минусы: данные уходят конкурентам (например, Яндекс.Метрика), зависимость от стороннего вендора.
Что такое Clickstream?
Clickstream — это масштабная система сбора и обработки аналитических событий в Авито. Она обеспечивает:
надежную доставку 20 миллионов cs-событий в минуту;
централизованное управление описанием событий;
клиентскую валидацию данных;
единый формат событий, что важно для сквозной аналитики.
Платформа построена на событийно-ориентированной архитектуре с единой семантикой полей. Она поддерживает более 500 источников данных и обеспечивает гарантии доставки (at least once).
Подробнее о платформе, ее концепциях и возможностях можно узнать в этой статье.
Реализация внутренней аналитики
После ряда встреч со стейкхолдерами и анализа данных, отправляемых Amplitude, мы определили 5 базовых аналитических событий с необходимыми полями:
Таблица 1 — общие поля для каждого события:
Slug | Тип | Описание |
browser_id | string | Id браузера |
session_id | string | Id сессии сотрудника |
cdtm | float | Клиентское время в микросекундах, целая часть - количество секунд от 1970 года |
eid | int | Id события |
language | string | Язык браузера |
ip | string | Ip сотрудника |
uuid | string | Уникальный ключ события |
software_version | string | Человекочитаемое название сервиса отправляющего событие |
ua | string | User agent |
string | Название события | |
event_name | string | Email авторизованного сотрудника |
Дефолтные события:
1) session_start (при загрузке приложения): только общие поля;
2) session_end (при закрытии приложения): только общие поля;
3) page_open (при открытии/переходе на страницу).
Таблица 2 — поля события page_open:
Slug | Тип | Описание |
url_domain | string | Домен страницы |
page_path | string | Путь на странице |
page_location | string | Полный адрес страницы |
page_title | string | Заголовок страницы |
page_counter | int | Счетчик просмотренных страниц |
ref | string | HTTP Referer (URL источника запроса) |
4) element_clicked (при клике по интерактивному элементу).
Таблица 3 — поля события element_clicked:
Slug | Тип | Описание |
css_classes | string | CSS Классы элемента |
css_selector | string | CSS селектор HTML-элемента |
dom_hierarchy | object | Иерархия DOM-элемента |
element_position_left | float | Позиция HTML-элемента слева (абсолютная) |
element_position_top | float | Позиция HTML-элемента сверху (абсолютная) |
element_text | string | Текст HTML-элемента |
viewport_height | integer | Высота вьюпорта |
viewport_width | integer | Ширина вьюпорта |
aria_label | string | Aria label элемента |
element_attributes | object | Атрибуты HTML элемента |
element_id | string | Id HTML элемента |
relative_x | float | Относительная координата клика по Х |
relative_y | float | Относительная координата клика по Y |
track_attribute_value | string | Значение отслеживаемого атрибута. Для не интерактивных элементов есть возможность также собирать клики разметив их определенных атрибутом |
5) element_changed (при вводе в инпут, кликах на radiobutton, checkbox).
Slug | Тип | Описание |
input_value | string | Значение инпута |
те же поля что у element_clicked |
Библиотека Clickstream-insights
Для сбора этих полей мы разработали библиотеку Clickstream-insights, которая добавляет соответствующие слушатели событий на фронте сервиса и формирует объекты cs-событий для отправки.
Библиотека экспортирует класс, который агрегирует и инициализирует, в зависимости от настроек, переданных в конструктор, другие классы для сбора каждого типа событий: ClickTracker, InputChangeTracker, RouteChangeTracker.
Поскольку админки в Авито обычно представляют собой SPA (одностраничные приложения), интересным аспектом стал RouteChangeTracker. Для отслеживания изменения роутера нам потребовалось переопределить нативное History API:

Визуализация данных в Redash
В качестве инструмента для визуализации был выбран Redash, а именно redash-charts, который разработали в Авито, позволяющий строить визуализации в формате no-code, выбирая поля датасетов в качестве разрезов.
Redash — это инструмент бизнес-аналитики и визуализации данных с открытым исходным кодом, предназначенный для анализа, визуализации и совместной работы с данными.
В Авито есть команда, которая занимается развитием данного инструмента. Ребята сделали доработки, позволяющие использовать в качестве источника для датасетов топик Kafka, в который попадают события аналитики.


Визуализации из чартов можно собирать в информативные дашборды, которые дают всестороннее представление о работе внутренних сервисов.

Интеграция в сервисы
Процесс подключения нового фронтенд-сервиса к нашей аналитической платформе максимально упрощен:
в админке нашей платформы создается cs-окружение;
в него подоокружением добавляется cs-окружение библиотеки Clickstream-insights;
бэкенд платформы при добавлении подокружения отправляет событие в асинхронную очередь, которое обрабатывается воркером, создающим датасеты и дефолтные дашборды в Redash;
в коде фронтенд-сервиса инициализируется инстанс Clickstream-insights, в конструктор которого передается клиент платформы из SDK;
cs-события проходят по нашему пайплайну и роутятся в отдельный топик Kafka;
датасеты redash наполняются данными из топика.
На этом настройка завершена — дефолтные cs-события начинают отправляться, а в Redash уже готовы стандартные дашборды для анализа.

Возможности кастомных событий
Помимо стандартного набора cs-событий многим пользователям критично отправлять кастомные. Мы реализовали это требование, что значительно расширило гибкость внутренней аналитики для всех команд Авито.
Реализация
При добавлении нового cs-события в cs-окружение, где уже подключена Clickstream-insights, в асинхронную очередь отправляется событие. На него подписан воркер, который добавляет поля cs-события в датасет, соответствующий cs-окружению.
Теперь команды могут добавлять уникальные события для сбора информации о специфических действиях пользователей, которые важны именно для их сервиса и сразу становятся доступны для визуализаций в Redash.
Heatmaps (Тепловые карты)
От стейкхолдеров поступил запрос о возможности построения тепловых карт на основе собранных данных. Тепловые карты используются для наглядного отображения зон активности пользователей на страницах административных интерфейсов.
Для решения этой задачи мы разработали браузерное расширение, накладывающее оверлей с тепловой картой поверх страницы.
Это расширение считывает:
ID источника данных (проставляемый библиотекой в пиксель);
URL страницы (либо задаваемое пользователем регулярное выражение);
ширину/высоту экрана пользователя;
временной отрезок (выбирается пользователем).


Эти данные отправляются в бэкенд-сервис. Он ходит за данными о кликах в датасет соответствующий cs-окружению. Далее сервис преобразует результаты в формат, пригодный для построения тепловой карты (массив точек с координатами и весами).
Браузерное расширение получает эти данные и создает оверлей с тепловой картой поверх интерфейса. Для визуализации используется библиотека heatmap.js, которая преобразует точки в градиентную карту, где цвет указывает на интенсивность кликов.

Заключение
В результате мы получили собственный мощный инструмент, не зависящий от внешних вендоров, который можно использовать для постоянного улучшения внутренних процессов и сервисов, что в конечном итоге положительно повлияет на эффективность работы всей компании.
Спасибо вам за уделенное статье время! Если у вас есть опыт создания подобных сервисов — расскажите о нем в комментариях.
Вообще мы в Авито создаем десятки сервисов для ускорения разработки и блага инженеров. Некоторые из этих сервисов уже вышли на внешний рынок, например платформа для А/B-тестирования Trisigma и self-service-решение для ускорения разработки AvitoPlato.
Больше о наших решениях и команде можно узнать здесь. И подпишитесь на канал AvitoTech в Telegram, там мы каждый день выкладываем интересные штуки.