Hazırda dünyada demək olar ki, hər bir şirkət veb resursda istifadəçi hərəkətləri haqqında statistik məlumat toplayır. Motivasiya aydındır - şirkətlər məhsullarının/veb-saytlarının necə istifadə olunduğunu bilmək və istifadəçilərini daha yaxşı başa düşmək istəyirlər. Əlbəttə ki, bazarda bu problemi həll etmək üçün çoxlu sayda alətlər var - tablolar və qrafiklər şəklində məlumatları təmin edən analitik sistemlərdən (məsələn,
Ancaq hələ də həllini tapmayan bir problem tapdıq. Beləcə doğuldu
Niyə biz öz xidmətimizi inkişaf etdirməliyik?
2019-cı illər idi, bacardıqca sağ qaldıq. XNUMX, biz API İlk Müştəri Məlumat Platformasını inkişaf etdirdik kSense, bu, müxtəlif mənbələrdən (Facebook reklamları, Stripe, Salesforce, Google play, Google Analytics və s.) məlumatların daha rahat təhlili, asılılıqların müəyyən edilməsi və s. Bir çox istifadəçinin məlumatların təhlili üçün platformamızdan xüsusilə Google Analytics (bundan sonra GA) istifadə etdiyini müşahidə etdik. Bəzi istifadəçilərlə danışdıq və öyrəndik ki, onlar GA istifadə edərək aldıqları məhsul üçün analitik məlumatlara ehtiyac duyurlar, lakin
Onlar veb resursunda Seqment javascript pikselini quraşdırdılar və istifadəçilərinin davranışı haqqında məlumatlar müəyyən edilmiş verilənlər bazasına (məsələn, Postgres) yükləndi. Lakin Seqmentin mənfi tərəfi də var - qiymət. Məsələn, bir veb resursda 90,000 MTU (aylıq izlənən istifadəçilər) varsa, o zaman kassirə ayda ~ 1,000 dollar ödəməlisiniz. Üçüncü problem də var idi - bəzi brauzer genişləndirmələri (məsələn, AdBlock) analitiklərin toplanmasına mane oldu, çünki... Brauzerdən http sorğuları GA və Seqment domenlərinə göndərildi. Müştərilərimizin istəklərinə əsasən, biz tam məlumat toplusunu (nümunə götürmədən) toplayan, pulsuz olan və öz infrastrukturumuzda işləyə bilən analitik xidmət yaratdıq.
Xidmət necə işləyir
Xidmət üç hissədən ibarətdir: javascript pikseli (biz onu sonradan şriftlə yenidən yazdıq), server hissəsi GO dilində həyata keçirilir və daxili verilənlər bazası kimi Redshift və BigQuery-dən istifadə edilməsi planlaşdırılırdı (sonralar onlar üçün dəstək əlavə etdilər. Postgres, ClickHouse və Snowflake).
GA və Seqment hadisələrinin strukturunun dəyişməz qalması qərara alınıb. Lazım olan tək şey, pikselin quraşdırıldığı veb resursdakı bütün hadisələri backendimizə təkrarlamaq idi. Göründüyü kimi, bunu etmək çətin deyil. Javascript pikseli orijinal GA kitabxana metodunu yenisi ilə ləğv etdi, bu da sistemimizdəki hadisəni təkrarladı.
//'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);
});
});
}
Seqment pikseli ilə hər şey daha sadədir, ara proqram metodlarına malikdir, onlardan birini istifadə edirik.
//'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.');
}
Hadisələri kopyalamaqdan əlavə, biz ixtiyari json göndərmək imkanı əlavə etdik:
//Отправка событий с произвольным 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'
});
Sonra server hissəsi haqqında danışaq. Backend http sorğularını qəbul etməli, onları əlavə məlumatla doldurmalıdır, məsələn, geo data (təşəkkürlər
//входящий 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"
}
Bununla belə, massivlər hazırda sadəcə olaraq sətirlərə çevrilir, çünki Bütün əlaqəli verilənlər bazaları təkrarlanan sahələri dəstəkləmir. Sahə adlarını dəyişdirmək və ya əlavə xəritəçəkmə qaydalarından istifadə edərək silmək də mümkündür. Onlar sizə lazım olduqda məlumat sxemini dəyişməyə və ya bir məlumat növünü digərinə çevirməyə imkan verir. Məsələn, json sahəsində zaman damğası olan sətir (sahə_3_alt_sahə_1_alt_alt_sahə_1 yuxarıdakı nümunədən), sonra verilənlər bazasında vaxt damğası növü ilə bir sahə yaratmaq üçün konfiqurasiyada xəritəçəkmə qaydası yazmalısınız. Başqa sözlə, sahənin məlumat tipi ilk olaraq json dəyəri ilə müəyyən edilir, sonra isə tip tökmə qaydası (konfiqurasiya olunubsa) tətbiq edilir. Biz 4 əsas məlumat növünü müəyyən etdik: STRING, FLOAT64, INT64 və TIMESTAMP. Xəritəçəkmə və tip tökmə qaydaları belə görünür:
rules:
- "/field_1/subfield_1 -> " #правило удаления поля
- "/field_2/subfield_1 -> /field_10/subfield_1" #правило переноса поля
- "/field_3/subfield_1/subsubfield_1 -> (timestamp) /field_20" #правило переноса поля и приведения типа
Verilənlərin növünü təyin etmək üçün alqoritm:
- json strukturunu düz quruluşa çevirin
- dəyərlərlə sahələrin məlumat növünün müəyyən edilməsi
- Xəritəçəkmə və tip tökmə qaydalarının tətbiqi
Sonra gələn json strukturundan:
{
"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"
}
}
məlumat sxemi əldə ediləcək:
"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
Biz həmçinin hesab etdik ki, istifadəçi digər meyarlara uyğun olaraq verilənlər bazasında məlumatların bölmələrini və ya bölmələrini konfiqurasiya edə bilməlidir və cədvəlin adını sabit və ya
tableName: '{{.product_type}}_{{._timestamp.Format "2006_01"}}'
Bununla belə, daxil olan hadisələrin strukturu icra zamanı dəyişə bilər. Mövcud cədvəlin strukturu ilə daxil olan hadisənin strukturu arasındakı fərqi yoxlamaq üçün alqoritm tətbiq etdik. Fərq aşkar edilərsə, cədvəl yeni sahələrlə yenilənəcək. Bunu etmək üçün patch SQL sorğusundan istifadə edin:
#Пример для Postgres
ALTER TABLE "schema"."table" ADD COLUMN new_column character varying
memarlıq
Nə üçün hadisələri birbaşa verilənlər bazasına yazmaq yox, fayl sisteminə yazmaq lazımdır? Verilənlər bazaları çoxlu sayda əlavələrlə işləyərkən həmişə yaxşı işləmir (
Açıq Mənbə və gələcək üçün planlar
Bir anda xidmət tam hüquqlu bir məhsul kimi görünməyə başladı və biz onu Open Source-a buraxmaq qərarına gəldik. Hazırda Postgres, ClickHouse, BigQuery, Redshift, S3, Snowflake ilə inteqrasiyalar həyata keçirilib. Bütün inteqrasiyalar verilənlərin yüklənməsinin həm toplu, həm də axın rejimlərini dəstəkləyir. API vasitəsilə sorğular üçün əlavə dəstək.
Mövcud inteqrasiya sxemi belə görünür:
Baxmayaraq ki, xidmət müstəqil olaraq istifadə edilə bilər (məsələn, Docker istifadə edərək), bizdə də var
→
→
→
EventNative problemlərinizi həll etməyə kömək etsə, şad olarıq!
Sorğuda yalnız qeydiyyatdan keçmiş istifadəçilər iştirak edə bilər.
Şirkətinizdə hansı statistika toplama sistemindən istifadə olunur?
-
48,0%Google Analytics12
-
4,0%Seqment 1
-
16,0%Digəri (şərhlərdə yazın)4
-
32,0%Xidmətinizi həyata keçirdiniz8
25 istifadəçi səs verib. 6 istifadəçi bitərəf qalıb.
Mənbə: www.habr.com