Это первая часть серии руководств по созданию аналитического веб-приложения с помощью Cube.js. Ожидается, что читатель знаком с Javascript, Node.js, React и имеет базовые знания SQL. Окончательный исходный код доступен здесь и живая демонстрация здесь. Пример приложения является бессерверным и работает на AWS Lambda. Он отображает данные о собственном использовании.

Есть категория инструментов аналитики, таких как Mixpanel или Amplitude, которые хорошо работают с данными событий. Они идеально подходят для измерения показателей продукта или взаимодействия, таких как последовательности активации или удержание. Они также очень полезны для измерения A / B-тестов.

Хотя все эти инструменты работают, они проприетарные и облачные. Это может быть проблемой, когда важна конфиденциальность. Или если кто-то хочет настроить, как воронки или удержание работают под капотом. Хотя традиционные инструменты бизнес-аналитики, такие как Tableau или Power BI, потенциально могут использоваться для выполнения того же анализа, они не могут предложить такой же уровень взаимодействия с пользователем. Проблема в том, что они предназначены для использования в качестве общих инструментов бизнес-аналитики, а не только для воронок, удержания, A / B-тестов и т. Д.

Благодаря недавним достижениям в разработке внешнего интерфейса стало возможным быстро разрабатывать сложные пользовательские интерфейсы. То, что пять лет назад строили за неделю, сегодня можно построить за полдень. Что касается серверной части и инфраструктуры, облачные базы данных MPP, такие как BigQuery и Athena, кардинально меняют ситуацию. Подход ELT, когда данные преобразуются внутри базы данных, становится все более популярным, заменяя традиционный ETL. Бессерверная архитектура позволяет легко развертывать и масштабировать приложения.

Все это позволило создать внутренние альтернативы устоявшимся сервисам, таким как Mixpanel, Amplitude или Kissmetrics. В этой серии руководств мы собираемся создать полнофункциональную систему аналитики событий с открытым исходным кодом.

Он будет включать в себя следующие функции:

  • Сбор данных;
  • Дашбординг;
  • Специальный анализ с помощью конструктора запросов;
  • Анализ воронки;
  • Анализ удержания;
  • Бессерверное развертывание;
  • A / B тесты;
  • Мониторинг событий в реальном времени;

На схеме ниже показана архитектура нашего приложения:

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

Сбор событий

Мы собираемся использовать Snowplow Cloudfront Collector и Javascript Tracker. Нам нужно загрузить пиксель отслеживания в CDN Amazon CloudFront. Snowplow Tracker отправляет данные сборщику, выполняя запрос GET для пикселя и передавая данные в качестве параметра строки запроса. CloudFront Collector использует ведение журнала CloudFront для записи запроса (включая строку запроса) в корзину S3.

Далее нам нужно установить Javascript Tracker. Вот полное руководство.

Но короче говоря, он похож на код отслеживания Google Analytics или Mixpanel, поэтому нам нужно просто встроить его в нашу HTML-страницу.

<script type="text/javascript">      
  ;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[];
   p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments)
   };p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1;
   n.src=w;g.parentNode.insertBefore(n,g)}} .  (window,document,"script","//d1fc8wv8zag5ca.cloudfront.net/2.10.2/sp.js","snowplow"));
  window.snowplow('newTracker', 'cf', '<YOUR_CLOUDFRONT_DISTRIBUTION_URL>’, { post: false });
</script>

Здесь вы можете узнать, как это встроено в наш пример приложения.

Когда у нас есть данные, которые представляют собой журналы CloudFront, в корзине S3, мы можем запросить их с помощью Athena. Все, что нам нужно сделать, это создать таблицу для журналов CloudFront.

Скопируйте и вставьте следующий оператор DDL в консоль Athena. Измените МЕСТО для корзины S3, в которой хранятся ваши журналы.

CREATE EXTERNAL TABLE IF NOT EXISTS default.cloudfront_logs (
  `date` DATE,
  time STRING,
  location STRING,
  bytes BIGINT,
  requestip STRING,
  method STRING,
  host STRING,
  uri STRING,
  status INT,
  referrer STRING,
  useragent STRING,
  querystring STRING,
  cookie STRING,
  resulttype STRING,
  requestid STRING,
  hostheader STRING,
  requestprotocol STRING,
  requestbytes BIGINT,
  timetaken FLOAT,
  xforwardedfor STRING,
  sslprotocol STRING,
  sslcipher STRING,
  responseresulttype STRING,
  httpversion STRING,
  filestatus STRING,
  encryptedfields INT
)
ROW FORMAT DELIMITED 
FIELDS TERMINATED BY '\t'
LOCATION 's3://CloudFront_bucket_name/AWSLogs/Account_ID/'
TBLPROPERTIES ( 'skip.header.line.count'='2' )

Теперь мы готовы подключить Cube.js к Athena и приступить к созданию нашей первой панели инструментов.

Создание нашей первой диаграммы

Сначала установите Cube.js CLI. Он используется для различных рабочих процессов Cube.js.

$ npm install -g cubejs-cli

Затем создайте новую службу Cube.js, выполнив следующую команду. Обратите внимание, что здесь мы указываем Athena в качестве базы данных (-d athena), а шаблон - как не обслуживаемую (-t serverless). Cube.js поддерживает разные конфигурации, но в этом руководстве мы будем использовать бессерверную.

$ cubejs create event-analytics-backend -d athena -t serverless

После запуска команда create создаст новый каталог проекта, содержащий каркас для вашего нового проекта Cube.js. Сюда входят все файлы, необходимые для запуска серверной части Cube.js, пример кода внешнего интерфейса для отображения результатов запросов Cube.js в приложении React и несколько примеров файлов схемы для выделения формата слоя схемы данных Cube.js.

Файл .env в этом каталоге проекта содержит заполнители для соответствующих учетных данных базы данных. Для Athena вам необходимо указать доступ к AWS и секретные ключи с доступом, необходимым для выполнения запросов Athena, а также целевой регион AWS и местоположение вывода S3, где хранятся результаты запроса.

CUBEJS_DB_TYPE=athena
CUBEJS_AWS_KEY=<YOUR ATHENA AWS KEY HERE>
CUBEJS_AWS_SECRET=<YOUR ATHENA SECRET KEY HERE>
CUBEJS_AWS_REGION=<AWS REGION STRING, e.g. us-east-1>
# You can find the Athena S3 Output location here: https://docs.aws.amazon.com/athena/latest/ug/querying.html
CUBEJS_AWS_S3_OUTPUT_LOCATION=<S3 OUTPUT LOCATION>

Теперь давайте создадим базовую схему Cube.js для нашей модели событий. Cube.js использует схему данных для генерации и выполнения SQL; "Вы можете прочитать больше об этом здесь."

Создайте schema/Events.js файл со следующим содержимым.

const regexp = (key) => `&${key}=([^&]+)`;
const parameters = {
  event: regexp('e'),
  event_id: regexp('eid'),
  page_title: regexp('page')
}
cube(`Events`, {
  sql:
    `SELECT
      from_iso8601_timestamp(to_iso8601(date) || 'T' || "time") as time,
      ${Object.keys(parameters).map((key) => ( `url_decode(url_decode(regexp_extract(querystring, '${parameters[key]}', 1))) as ${key}` )).join(", ")}
    FROM cloudfront_logs
    WHERE length(querystring) > 1
    `,
  measures: {
    pageView: {
      type: `count`,
      filters: [
        { sql: `${CUBE}.event = 'pv'` }
      ]
    },
  },
  dimensions: {
    pageTitle: {
      sql: `page_title`,
      type: `string`
    }
  }
});

В файле схемы мы создаем куб событий. Он будет содержать всю информацию о наших мероприятиях. В базовом операторе SQL мы извлекаем значения из строки запроса, отправляемой трекером, с помощью функции regexp. Cube.js хорош для выполнения таких преобразований, а также может материализовать некоторые из них для оптимизации производительности. Мы поговорим об этом в следующих частях нашего руководства.

Имея эту схему, мы можем запустить наш сервер разработки и построить первую диаграмму.

Раскрутите сервер разработки, выполнив следующую команду.

$ npm dev

Посетите http: // localhost: 4000, откроется CodeSandbox с примером. Измените функцию renderChart и переменную query на следующие.

const renderChart = resultSet => (
  <Chart height={400} data={resultSet.chartPivot()} forceFit>
    <Coord type="theta" radius={0.75} />
    <Axis name="Events.pageView" />
    <Legend position="right" name="category" />
    <Tooltip showTitle={false} />
    <Geom type="intervalStack" position="Events.pageView" color="x" />
  </Chart>
);
const query = {
  measures: ["Events.pageView"],
  dimensions: ["Events.pageTitle"]
};

Теперь вы должны увидеть круговую диаграмму в зависимости от того, какие данные у вас есть в вашем S3.

В следующей части мы рассмотрим, как создавать последовательности конверсии. В третьей части мы создадим дашборд и конструктор динамических запросов, как в Mixpanel или Amplitude. Часть 3 будет посвящена анализу удержания. В заключительной части мы обсудим, как развернуть все приложение в бессерверном режиме в AWS Lambda.

Вы можете ознакомиться с полным исходным кодом приложения здесь.

А живую демонстрацию можно посмотреть здесь.