Praegu kogub peaaegu iga ettevõte maailmas statistikat kasutajate tegevuste kohta veebiressursil. Motivatsioon on selge – ettevõtted tahavad teada, kuidas nende toodet/veebi kasutatakse ning mõistavad paremini oma kasutajaid. Loomulikult on selle probleemi lahendamiseks turul suur hulk tööriistu – alates analüüsisüsteemidest, mis pakuvad andmeid armatuurlaudade ja graafikute kujul (näiteks
Kuid leidsime probleemi, mida pole veel lahendatud. Nii sündis
Miks peaksime oma teenust ise arendama?
Olid üheksakümnendad, elasime nii hästi kui suutsime. 2019. aastal töötasime välja API First Customer Data Platformi kSense, mis võimaldas koondada andmeid erinevatest allikatest (Facebooki reklaamid, Stripe, Salesforce, Google play, Google Analytics jne) mugavamaks andmeanalüüsiks, sõltuvuste tuvastamiseks jne. Oleme märganud, et paljud kasutajad kasutavad meie platvormi andmeanalüüsiks just Google Analyticsit (edaspidi GA). Rääkisime mõne kasutajaga ja saime teada, et nad vajavad oma toote kohta GA kaudu saadavaid analüütilisi andmeid, kuid
Nad installisid oma veebiressurssi JavaScripti segmenti piksli ja andmed nende kasutajate käitumise kohta laaditi määratud andmebaasi (näiteks Postgres). Kuid Segmendil on ka oma varjukülg – hind. Näiteks kui veebiressursil on 90,000 1,000 MTU (igakuised jälgitavad kasutajad), siis tuleb kassasse maksta ~XNUMX $ kuus. Tekkis ka kolmas probleem – mõned brauseri laiendused (nt AdBlock) blokeerisid analüütika kogumise, kuna... Brauseri http-päringud saadeti GA ja Segmendi domeenidele. Klientide soovidest lähtuvalt oleme loonud analüütikateenuse, mis kogub (ilma proovivõtuta) täielikku andmekomplekti, on tasuta ja saab töötada meie enda taristul.
Kuidas teenus töötab
Teenus koosneb kolmest osast: javascripti piksel (mille hiljem masinakirjas ümber kirjutasime), serveriosa on realiseeritud GO keeles ning ettevõttesisese andmebaasina plaaniti kasutada Redshifti ja BigQueryt (hiljem lisati tugi ka Postgres, ClickHouse ja Snowflake).
Otsustati jätta GA ja segmendi sündmuste struktuur muutmata. Kõik, mida oli vaja, oli kopeerida kõik sündmused veebiressursist, kuhu piksel on installitud, meie taustaprogrammi. Nagu selgub, pole seda raske teha. Javascripti piksel alistas algse GA teegi meetodi uuega, mis dubleeris sündmuse meie süsteemi.
//'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);
});
});
}
Segmendi piksliga on kõik lihtsam, sellel on vahevara meetodid, millest ühte kasutasime.
//'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.');
}
Lisaks sündmuste kopeerimisele oleme lisanud võimaluse saata suvaline 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'
});
Järgmisena räägime serveri osast. Taustaprogramm peaks vastu võtma http-päringuid, täitma need lisateabega, näiteks geoandmetega (aitäh
//входящий 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"
}
Kuid massiivid teisendatakse praegu lihtsalt stringideks, sest Kõik relatsiooniandmebaasid ei toeta korduvaid välju. Samuti on võimalik väljade nimesid muuta või kustutada valikuliste vastendusreeglite abil. Need võimaldavad vajadusel muuta andmeskeemi või teisendada üht andmetüüpi teiseks. Näiteks kui json-väli sisaldab stringi ajatempliga (field_3_sub_field_1_sub_sub_field_1 ülaltoodud näitest), siis selleks, et luua andmebaasis ajatempli tüübiga väli, tuleb konfiguratsioonis kirjutada vastendusreegel. Teisisõnu määrab välja andmetüübi esmalt json-väärtus ja seejärel rakendatakse tüübi ülekandmise reegel (kui see on konfigureeritud). Oleme tuvastanud 4 peamist andmetüüpi: STRING, FLOAT64, INT64 ja TIMESTAMP. Kaardistamise ja tüübi ülekandmise reeglid näevad välja järgmised:
rules:
- "/field_1/subfield_1 -> " #правило удаления поля
- "/field_2/subfield_1 -> /field_10/subfield_1" #правило переноса поля
- "/field_3/subfield_1/subsubfield_1 -> (timestamp) /field_20" #правило переноса поля и приведения типа
Andmetüübi määramise algoritm:
- teisendada json-struktuur tasaseks struktuuriks
- väljade andmetüübi määramine väärtuste järgi
- kaardistamise ja tüübi valamise reeglite rakendamine
Seejärel sissetulevast json-struktuurist:
{
"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"
}
}
saadakse andmeskeem:
"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
Samuti arvasime, et kasutajal peaks olema võimalus seadistada andmebaasis partitsioonide jagamist või jagada andmeid muude kriteeriumide järgi ning rakendasime võimaluse määrata tabeli nimi konstandiga või
tableName: '{{.product_type}}_{{._timestamp.Format "2006_01"}}'
Sissetulevate sündmuste struktuur võib aga käitusajal muutuda. Oleme rakendanud algoritmi, et kontrollida erinevust olemasoleva tabeli struktuuri ja sissetuleva sündmuse struktuuri vahel. Kui leitakse erinevus, täiendatakse tabelit uute väljadega. Selleks kasutage SQL-i paigapäringut:
#Пример для Postgres
ALTER TABLE "schema"."table" ADD COLUMN new_column character varying
arhitektuur
Miks on vaja sündmused failisüsteemi kirjutada, mitte lihtsalt otse andmebaasi kirjutada? Andmebaasid ei tööta alati hästi, kui käsitletakse suurt hulka lisasid (
Avatud lähtekood ja tulevikuplaanid
Mingil hetkel hakkas teenus välja nägema täisväärtusliku tootena ja otsustasime selle avatud lähtekoodiga välja anda. Hetkel on juurutatud integratsioonid Postgresi, ClickHouse'i, BigQuery, Redshift, S3, Snowflake'iga. Kõik integratsioonid toetavad nii andmete pakett- kui ka voogesituse režiimi. Lisatud on API kaudu päringute tugi.
Praegune integratsiooniskeem näeb välja selline:
Kuigi teenust saab kasutada iseseisvalt (näiteks Dockeri abil), on meil ka
→
→
→
Meil on hea meel, kui EventNative aitab teie probleeme lahendada!
Küsitluses saavad osaleda ainult registreerunud kasutajad.
Millist statistika kogumise süsteemi teie ettevõttes kasutatakse?
-
48,0%Google Analytics 12
-
4,0%Segment 1
-
16,0%Teine (kirjuta kommentaaridesse)4
-
32,0%Rakendasin teie teenust8
25 kasutajat hääletas. 6 kasutajat jäi erapooletuks.
Allikas: www.habr.com