Pašlaik gandrīz katrs uzņēmums pasaulē apkopo statistiku par lietotāja darbībām tīmekļa resursā. Motivācija ir skaidra – uzņēmumi vēlas uzzināt, kā tiek izmantots viņu produkts/vietne, un labāk izprast savus lietotājus. Protams, tirgū ir pieejams liels skaits rīku šīs problēmas risināšanai — no analītikas sistēmām, kas nodrošina datus informācijas paneļu un grafiku veidā (piemēram,
Bet mēs atradām problēmu, kas vēl nav atrisināta. Tā piedzima
Kāpēc mums pašiem jāattīsta savs pakalpojums?
Bija deviņdesmitie gadi, mēs izdzīvojām, kā varējām. 2019. gadā mēs izstrādājām API First Customer Data Platform kSense, kas ļāva apkopot datus no dažādiem avotiem (Facebook reklāmas, Stripe, Salesforce, Google play, Google Analytics u.c.) ērtākai datu analīzei, atkarību noteikšanai utt. Esam ievērojuši, ka daudzi lietotāji izmanto mūsu platformu datu analīzei, īpaši Google Analytics (turpmāk GA). Mēs runājām ar dažiem lietotājiem un noskaidrojām, ka viņiem ir nepieciešami sava produkta analītikas dati, ko viņi saņem, izmantojot GA, taču
Viņi savā tīmekļa resursā instalēja segmenta javascript pikseļu, un dati par lietotāju uzvedību tika ielādēti norādītajā datu bāzē (piemēram, Postgres). Taču Segmentam ir arī savs mīnuss – cena. Piemēram, ja tīmekļa resursam ir 90,000 1,000 MTU (ikmēneša izsekotie lietotāji), tad kasierim ir jāmaksā ~XNUMX USD mēnesī. Bija arī trešā problēma – daži pārlūkprogrammas paplašinājumi (piemēram, AdBlock) bloķēja analītikas apkopošanu, jo... http pieprasījumi no pārlūkprogrammas tika nosūtīti uz GA un Segment domēniem. Pamatojoties uz mūsu klientu vēlmēm, esam izveidojuši analītikas pakalpojumu, kas savāc pilnu datu kopumu (bez paraugu ņemšanas), ir bezmaksas un var darboties savā infrastruktūrā.
Kā pakalpojums darbojas
Pakalpojums sastāv no trim daļām: javascript pikseļa (kuru vēlāk pārrakstījām mašīnrakstā), servera daļa ir realizēta GO valodā, kā arī bija plānots izmantot Redshift un BigQuery kā iekšējo datu bāzi (vēlāk pievienoja atbalstu Postgres, ClickHouse un Snowflake).
Tika nolemts GA un segmentu notikumu struktūru atstāt nemainīgu. Viss, kas bija nepieciešams, bija dublēt visus notikumus no tīmekļa resursa, kurā pikselis ir instalēts, uz mūsu aizmugursistēmu. Kā izrādās, to nav grūti izdarīt. Javascript pikselis ignorēja sākotnējo GA bibliotēkas metodi ar jaunu, kas dublēja notikumu mūsu sistēmā.
//'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);
});
});
}
Ar Segment pikseļu viss ir vienkāršāk; tam ir starpprogrammatūras metodes, no kurām vienu mēs izmantojām.
//'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.');
}
Papildus notikumu kopēšanai esam pievienojuši iespēju nosūtīt patvaļīgu 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'
});
Tālāk parunāsim par servera daļu. Aizmugursistēmai vajadzētu pieņemt http pieprasījumus, aizpildīt tos ar papildu informāciju, piemēram, ģeogrāfiskajiem datiem (paldies
//входящий 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"
}
Tomēr pašlaik masīvi tiek vienkārši pārveidoti par virknēm, jo Ne visas relāciju datu bāzes atbalsta atkārtotus laukus. Ir iespējams arī mainīt lauku nosaukumus vai dzēst tos, izmantojot izvēles kartēšanas noteikumus. Tie ļauj mainīt datu shēmu, ja nepieciešams, vai pārveidot vienu datu tipu citā. Piemēram, ja json laukā ir virkne ar laikspiedolu (field_3_sub_field_1_sub_sub_field_1 no iepriekš minētā piemēra), tad, lai datu bāzē izveidotu lauku ar laikspiedola veidu, konfigurācijā ir jāieraksta kartēšanas kārtula. Citiem vārdiem sakot, lauka datu tipu vispirms nosaka json vērtība, un pēc tam tiek lietots tipa apraides kārtula (ja tā ir konfigurēta). Mēs esam identificējuši 4 galvenos datu tipus: STRING, FLOAT64, INT64 un TIMESTAMP. Kartēšanas un veidu izdalīšanas noteikumi izskatās šādi:
rules:
- "/field_1/subfield_1 -> " #правило удаления поля
- "/field_2/subfield_1 -> /field_10/subfield_1" #правило переноса поля
- "/field_3/subfield_1/subsubfield_1 -> (timestamp) /field_20" #правило переноса поля и приведения типа
Algoritms datu veida noteikšanai:
- pārveidot json struktūru plakanā struktūrā
- lauku datu tipa noteikšana pēc vērtībām
- piemērojot kartēšanas un tipu liešanas noteikumus
Pēc tam no ienākošās JSON struktūras:
{
"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"
}
}
tiks iegūta datu shēma:
"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
Mēs arī domājām, ka lietotājam jāspēj konfigurēt sadalīšanu vai sadalīt datus datu bāzē pēc citiem kritērijiem un ieviesām iespēju iestatīt tabulas nosaukumu ar konstantu vai
tableName: '{{.product_type}}_{{._timestamp.Format "2006_01"}}'
Tomēr ienākošo notikumu struktūra izpildes laikā var mainīties. Mēs esam ieviesuši algoritmu, lai pārbaudītu atšķirību starp esošās tabulas struktūru un ienākošā notikuma struktūru. Ja tiek konstatēta atšķirība, tabula tiks atjaunināta ar jauniem laukiem. Lai to izdarītu, izmantojiet ielāpa SQL vaicājumu:
#Пример для Postgres
ALTER TABLE "schema"."table" ADD COLUMN new_column character varying
Arhitektūra
Kāpēc notikumi jāraksta failu sistēmā, nevis tikai tiešā veidā datu bāzē? Datu bāzes ne vienmēr darbojas labi, strādājot ar lielu skaitu ieliktņu (
Open Source un nākotnes plāni
Kādā brīdī pakalpojums sāka izskatīties kā pilnvērtīgs produkts, un mēs nolēmām to izlaist atvērtā koda versijā. Šobrīd ir ieviestas integrācijas ar Postgres, ClickHouse, BigQuery, Redshift, S3, Snowflake. Visas integrācijas atbalsta gan pakešu, gan straumēšanas datu ielādes režīmus. Pievienots atbalsts pieprasījumiem, izmantojot API.
Pašreizējā integrācijas shēma izskatās šādi:
Lai gan pakalpojumu var izmantot neatkarīgi (piemēram, izmantojot Docker), arī mums ir
→
→
→
Mēs priecāsimies, ja EventNative palīdzēs atrisināt jūsu problēmas!
Aptaujā var piedalīties tikai reģistrēti lietotāji.
Kāda statistikas vākšanas sistēma tiek izmantota jūsu uzņēmumā?
-
48,0%Google Analytics12
-
4,0%Segments 1
-
16,0%Vēl viens (raksti komentāros)4
-
32,0%Ieviesa jūsu pakalpojumu8
Nobalsoja 25 lietotāji. 6 lietotāji atturējās.
Avots: www.habr.com