Jelenleg a világon szinte minden vállalat gyűjt statisztikát a webes erőforrásokon végzett felhasználói műveletekről. A motiváció egyértelmű – a cégek tudni akarják, hogyan használják termékeiket/webhelyüket, és jobban meg akarják érteni felhasználóikat. Természetesen számos eszköz létezik a piacon a probléma megoldására – az elemző rendszerektől kezdve, amelyek műszerfalak és grafikonok formájában szolgáltatnak adatokat (pl.
De találtunk egy problémát, amelyet még nem sikerült megoldani. Így született
Miért érdemes saját szolgáltatásunkat fejlesztenünk?
A kilencvenes évek voltak, túléltük, ahogy tudtuk. 2019-ben kifejlesztettük az API First Customer Data Platformot kSense, amely lehetővé tette a különböző forrásokból (Facebook hirdetések, Stripe, Salesforce, Google play, Google Analytics stb.) származó adatok összesítését a kényelmesebb adatelemzés, függőségek azonosítása stb. Észrevettük, hogy sok felhasználó adatelemzésre használja platformunkat, kifejezetten a Google Analytics-et (a továbbiakban GA). Néhány felhasználóval beszélgettünk, és rájöttünk, hogy szükségük van a termékükhöz kapcsolódó analitikai adatokra, amelyeket a GA használatával kapnak, de
Telepítettek egy Segment javascript pixelt a webes erőforrásukra, és a felhasználók viselkedésére vonatkozó adatok betöltésre kerültek a megadott adatbázisba (például Postgres). De a szegmensnek megvan a hátránya is – az ár. Például, ha egy webes erőforrás 90,000 1,000 MTU-val rendelkezik (havi nyomon követett felhasználók), akkor havonta ~XNUMX XNUMX USD-t kell fizetnie a pénztárosnak. Volt egy harmadik probléma is – egyes böngészőbővítmények (például az AdBlock) blokkolták az elemzések gyűjtését, mert... A böngésző http-kérelmei elküldésre kerültek a GA és a Segment tartományokba. Ügyfeleink kívánságai alapján olyan elemző szolgáltatást hoztunk létre, amely teljes adathalmazt gyűjt (mintavétel nélkül), ingyenes és saját infrastruktúránkon is működik.
Hogyan működik a szolgáltatás
A szolgáltatás három részből áll: egy javascript pixelből (amit később gépírással átírtunk), a szerver rész GO nyelven van implementálva, valamint a Redshift és a BigQuery házon belüli adatbázisként való felhasználását tervezték (később kiegészítették a Postgres, ClickHouse és Snowflake).
Úgy döntöttek, hogy a GA és a szegmens események szerkezetét változatlanul hagyják. Mindössze annyi kellett, hogy a webes erőforrásból, ahol a pixel telepítve van, minden eseményt lemásoljunk a háttérrendszerünkre. Mint kiderült, ezt nem nehéz megtenni. A Javascript pixel felülírta az eredeti GA-könyvtár metódust egy újjal, ami megkettőzte az eseményt a rendszerünkbe.
//'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);
});
});
}
A Segment pixellel minden egyszerűbb, köztes szoftveres módszerek vannak, amelyek közül az egyiket használtuk.
//'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.');
}
Az események másolása mellett tetszőleges json küldésének lehetőségét is hozzáadtuk:
//Отправка событий с произвольным 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'
});
Ezután beszéljünk a szerver részről. A háttérprogramnak el kell fogadnia a http kéréseket, és ki kell töltenie azokat további információkkal, például földrajzi adatokkal (köszönöm
//входящий 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"
}
A tömböket azonban jelenleg egyszerűen karakterláncokká alakítják, mert Nem minden relációs adatbázis támogatja az ismételt mezőket. Lehetőség van a mezőnevek megváltoztatására vagy törlésére is az opcionális leképezési szabályok segítségével. Lehetővé teszik az adatséma módosítását, ha szükséges, vagy az egyik adattípust egy másikra konvertálják. Például, ha egy json mező tartalmaz egy karakterláncot időbélyeggel (field_3_sub_field_1_sub_sub_field_1 a fenti példából), akkor egy időbélyeg típusú mező létrehozásához az adatbázisban egy leképezési szabályt kell írni a konfigurációban. Más szavakkal, a mező adattípusát először a json-érték határozza meg, majd a típus-casting szabályt (ha be van állítva) alkalmazza a rendszer. Négy fő adattípust azonosítottunk: STRING, FLOAT4, INT64 és TIMESTAMP. A leképezési és típusöntési szabályok így néznek ki:
rules:
- "/field_1/subfield_1 -> " #правило удаления поля
- "/field_2/subfield_1 -> /field_10/subfield_1" #правило переноса поля
- "/field_3/subfield_1/subsubfield_1 -> (timestamp) /field_20" #правило переноса поля и приведения типа
Algoritmus az adattípus meghatározásához:
- konvertálja a json-struktúrát lapos struktúrává
- a mezők adattípusának meghatározása értékek alapján
- leképezési és típusöntési szabályok alkalmazása
Ezután a bejövő json szerkezetből:
{
"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"
}
}
az adatsémát megkapjuk:
"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
Arra is gondoltunk, hogy a felhasználónak képesnek kell lennie az adatbázisban lévő particionálás konfigurálására vagy adatok felosztására más kritériumok szerint, és megvalósítottuk azt a lehetőséget, hogy a tábla nevét konstans ill.
tableName: '{{.product_type}}_{{._timestamp.Format "2006_01"}}'
A bejövő események szerkezete azonban futás közben változhat. Megvalósítottunk egy algoritmust, amellyel ellenőrizhetjük a különbséget egy meglévő tábla és egy bejövő esemény szerkezete között. Ha eltérést talál, a táblázat új mezőkkel frissül. Ehhez használja a patch SQL lekérdezést:
#Пример для Postgres
ALTER TABLE "schema"."table" ADD COLUMN new_column character varying
építészet
Miért kell az eseményeket a fájlrendszerbe írni, és nem csak közvetlenül az adatbázisba írni? Az adatbázisok nem mindig teljesítenek jól, ha nagyszámú beszúrással (
Nyílt forráskód és a jövőre vonatkozó tervek
Egy bizonyos ponton a szolgáltatás kezdett teljes értékű terméknek tűnni, és úgy döntöttünk, hogy kiadjuk nyílt forráskódúnak. Jelenleg a Postgres, ClickHouse, BigQuery, Redshift, S3, Snowflake integrációkat hajtották végre. Minden integráció támogatja az adatbetöltés kötegelt és streaming módját egyaránt. Támogatás hozzáadva az API-n keresztüli kérésekhez.
A jelenlegi integrációs séma így néz ki:
Bár a szolgáltatás önállóan is használható (például Docker segítségével), nálunk is van
→
→
→
Örülünk, ha az EventNative segít megoldani problémáit!
A felmérésben csak regisztrált felhasználók vehetnek részt.
Milyen statisztikai adatgyűjtési rendszert használnak az Ön cégében?
-
48,0%Google Analytics 12
-
4,0%1. szegmens
-
16,0%Egy másik (írd meg kommentben)4
-
32,0%Megvalósította szolgáltatását8
25 felhasználó szavazott. 6 felhasználó tartózkodott.
Forrás: will.com