目前,世界上幾乎每家公司都會收集有關網路資源上的使用者操作的統計資料。 動機很明確——公司想知道他們的產品/網站是如何使用的,並且更了解他們的用戶。 當然,市場上有大量工具可以解決這個問題 - 來自以儀表板和圖表形式提供數據的分析系統(例如
但我們發現一個問題還沒解決。 就這樣誕生了
我們為什麼要開發自己的服務?
那是九十年代,我們盡力生存。 2019年,我們開發了API First客戶資料平台 科感,這使得聚合來自不同來源(Facebook 廣告、Stripe、Salesforce、Google play、Google Analytics 等)的資料成為可能,以便更方便地進行資料分析、識別依賴關係等。 我們注意到許多用戶使用我們的平台進行數據分析,特別是 Google Analytics(以下簡稱 GA)。 我們與一些用戶交談,發現他們需要使用 GA 收到的產品分析數據,但是
他們在其 Web 資源上安裝了 Segment javascript 像素,並將有關使用者行為的資料載入到指定的資料庫(例如 Postgres)中。 但 Segment 也有其缺點——價格。 例如,如果某個 Web 資源有 90,000 MTU(每月追蹤使用者),那麼您每月需要向收銀員支付約 1,000 美元。 還有第三個問題 - 某些瀏覽器擴充功能(例如 AdBlock)阻止了分析收集,因為... 來自瀏覽器的 http 請求被傳送到 GA 和 Segment 網域。 根據客戶的意願,我們創建了一項分析服務,可以收集完整的資料集(無需採樣),並且是免費的,並且可以在我們自己的基礎設施上運行。
服務如何運作
這項服務由三個部分組成:javascript Pixel(我們後來用 typescript 重寫了),伺服器部分用 GO 語言實現,計劃使用 Redshift 和 BigQuery 作為內部資料庫(後來他們添加了對Postgres、ClickHouse 和 Snowflake)。
決定保持 GA 和 Segment 活動的結構不變。 所需要做的就是將安裝像素的網路資源中的所有事件複製到我們的後端。 事實證明,這並不難做到。 Javascript 像素以新方法覆寫了原始 GA 庫方法,從而將事件複製到我們的系統中。
//'ga' - стандартное название переменной Google Analytics
if (window.ga) {
ga(tracker => {
var originalSendHitTask = tracker.get('sendHitTask');
tracker.set('sendHitTask', (model) => {
var payLoad = model.get('hitPayload');
//отправка оригинального события в GA
originalSendHitTask(model);
let jsonPayload = this.parseQuery(payLoad);
//отправка события в наш сервис
this.send3p('ga', jsonPayload);
});
});
}
使用 Segment Pixel,一切都變得更簡單;它具有中間件方法,我們使用了其中之一。
//'analytics' - стандартное название переменной Segment
if (window.analytics) {
if (window.analytics.addSourceMiddleware) {
window.analytics.addSourceMiddleware(chain => {
try {
//дублирование события в наш сервис
this.send3p('ajs', chain.payload);
} catch (e) {
LOG.warn('Failed to send an event', e)
}
//отправка оригинального события в Segment
chain.next(chain.payload);
});
} else {
LOG.warn("Invalid interceptor state. Analytics js initialized, but not completely");
}
} else {
LOG.warn('Analytics.js listener is not set.');
}
除了複製事件之外,我們還添加了發送任意 json 的功能:
//Отправка событий с произвольным json объектом
eventN.track('product_page_view', {
product_id: '1e48fb70-ef12-4ea9-ab10-fd0b910c49ce',
product_price: 399.99,
price_currency: 'USD'
product_release_start: '2020-09-25T12:38:27.763000Z'
});
接下來我們來談談伺服器部分。 後端應該接受http請求,並用附加資訊填充它們,例如地理資料(感謝
//входящий json
{
"field_1": {
"sub_field_1": "text1",
"sub_field_2": 100
},
"field_2": "text2",
"field_3": {
"sub_field_1": {
"sub_sub_field_1": "2020-09-25T12:38:27.763000Z"
}
}
}
//результат
{
"field_1_sub_field_1": "text1",
"field_1_sub_field_2": 100,
"field_2": "text2",
"field_3_sub_field_1_sub_sub_field_1": "2020-09-25T12:38:27.763000Z"
}
然而,數組目前只是簡單地轉換為字串,因為並非所有關聯式資料庫都支援重複欄位。 也可以使用可選的對應規則來變更欄位名稱或刪除它們。 它們允許您在必要時更改資料模式或將一種資料類型轉換為另一種資料類型。 例如,如果 json 欄位包含帶有時間戳記的字串 (field_3_sub_field_1_sub_sub_field_1 從上面的例子),那麼為了在資料庫中建立時間戳類型的字段,需要在配置中編寫映射規則。 換句話說,欄位的資料類型首先由 json 值決定,然後套用類型轉換規則(如果配置)。 我們確定了 4 種主要資料類型:STRING、FLOAT64、INT64 和 TIMESTAMP。 映射和類型轉換規則如下所示:
rules:
- "/field_1/subfield_1 -> " #правило удаления поля
- "/field_2/subfield_1 -> /field_10/subfield_1" #правило переноса поля
- "/field_3/subfield_1/subsubfield_1 -> (timestamp) /field_20" #правило переноса поля и приведения типа
確定資料類型的演算法:
- 將 json 結構轉換為平面結構
- 透過值確定欄位的資料類型
- 應用程式映射和類型轉換規則
然後從傳入的json結構中:
{
"product_id": "1e48fb70-ef12-4ea9-ab10-fd0b910c49ce",
"product_price": 399.99,
"price_currency": "USD",
"product_type": "supplies",
"product_release_start": "2020-09-25T12:38:27.763000Z",
"images": {
"main": "picture1",
"sub": "picture2"
}
}
將獲得數據模式:
"product_id" character varying,
"product_price" numeric (38,18),
"price_currency" character varying,
"product_type" character varying,
"product_release_start" timestamp,
"images_main" character varying,
"images_sub" character varying
我們也認為使用者應該能夠根據其他標準配置分區或劃分資料庫中的數據,並實現使用常數或設定表名的功能
tableName: '{{.product_type}}_{{._timestamp.Format "2006_01"}}'
但是,傳入事件的結構可能會在運作時發生變化。 我們實作了一種演算法來檢查現有表的結構與傳入事件的結構之間的差異。 如果發現差異,表將使用新欄位進行更新。 為此,請使用修補 SQL 查詢:
#Пример для Postgres
ALTER TABLE "schema"."table" ADD COLUMN new_column character varying
架構
為什麼需要將事件寫入檔案系統,而不是直接寫入資料庫? 在處理大量插入時,資料庫並不總是表現良好(
開源和未來計劃
在某種程度上,該服務開始看起來像一個成熟的產品,我們決定將其發佈為開源。 目前,已實現與 Postgres、ClickHouse、BigQuery、Redshift、S3、Snowflake 的整合。 所有整合都支援資料載入的批次和流模式。 新增了對透過 API 請求的支援。
目前的整合方案如下所示:
雖然服務可以獨立使用(例如使用Docker),但我們也有
→
→
→
如果 EventNative 能幫助您解決問題,我們將非常高興!
只有註冊用戶才能參與調查。
貴公司使用什麼統計收集系統?
-
企業排放佔全球 48,0%Google分析12
-
企業排放佔全球 4,0%段1
-
企業排放佔全球 16,0%另一種(寫在評論裡)4
-
企業排放佔全球 32,0%實施您的服務8
25 位用戶投票。 6 名用戶棄權。
來源: www.habr.com