Sa kasalukuyan, halos lahat ng kumpanya sa mundo ay nangongolekta ng mga istatistika tungkol sa mga aksyon ng user sa isang web resource. Malinaw ang motibasyon - gustong malaman ng mga kumpanya kung paano ginagamit ang kanilang produkto/website at mas maunawaan ang kanilang mga user. Siyempre, mayroong isang malaking bilang ng mga tool sa merkado upang malutas ang problemang ito - mula sa mga sistema ng analytics na nagbibigay ng data sa anyo ng mga dashboard at graph (halimbawa
Ngunit nakakita kami ng isang problema na hindi pa nalulutas. Kaya ipinanganak
Bakit tayo dapat bumuo ng sarili nating serbisyo?
Noong dekada nobenta, nakaligtas kami sa abot ng aming makakaya. 2019, binuo namin ang API First Customer Data Platform kSense, na naging posible na pagsama-samahin ang data mula sa iba't ibang pinagmulan (mga ad sa Facebook, Stripe, Salesforce, Google play, Google Analytics, atbp.) para sa mas maginhawang pagsusuri ng data, pagtukoy ng mga dependency, atbp. Napansin namin na maraming user ang gumagamit ng aming platform para sa pagsusuri ng data partikular sa Google Analytics (simula dito sa GA). Nakipag-usap kami sa ilang user at nalaman namin na kailangan nila ang data ng analytics para sa kanilang produkto na natatanggap nila gamit ang GA, ngunit
Nag-install sila ng Segment javascript pixel sa kanilang web resource at ang data tungkol sa gawi ng kanilang mga user ay na-load sa tinukoy na database (halimbawa Postgres). Ngunit mayroon ding downside ang Segment - ang presyo. Halimbawa, kung ang isang web resource ay may 90,000 MTU (buwanang sinusubaybayang mga user), kailangan mong magbayad ng ~1,000 $ bawat buwan sa cashier. Nagkaroon din ng pangatlong problema - hinarangan ng ilang extension ng browser (gaya ng AdBlock) ang koleksyon ng analytics dahil... Ang mga kahilingan sa http mula sa browser ay ipinadala sa mga domain ng GA at Segment. Batay sa kagustuhan ng aming mga kliyente, gumawa kami ng serbisyo ng analytics na nangongolekta ng kumpletong hanay ng data (nang walang sampling), libre at maaaring gumana sa sarili naming imprastraktura.
Paano gumagana ang serbisyo
Binubuo ang serbisyo ng tatlong bahagi: isang javascript pixel (na sa kalaunan ay isinulat naming muli sa typescript), ang bahagi ng server ay ipinatupad sa wikang GO, at binalak itong gamitin ang Redshift at BigQuery bilang isang in-house na database (sa kalaunan ay nagdagdag sila ng suporta para sa Postgres, ClickHouse at Snowflake).
Napagpasyahan na iwanan ang istruktura ng mga kaganapan sa GA at Segment na hindi nagbabago. Ang kailangan lang ay i-duplicate ang lahat ng event mula sa web resource kung saan naka-install ang pixel sa aming backend. Sa lumalabas, hindi ito mahirap gawin. Na-override ng Javascript pixel ang orihinal na pamamaraan ng library ng GA gamit ang bago, na nag-duplicate ng kaganapan sa aming system.
//'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);
});
});
}
Sa Segment pixel, mas simple ang lahat; mayroon itong mga middleware na pamamaraan, isa sa mga ginamit namin.
//'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.');
}
Bilang karagdagan sa pagkopya ng mga kaganapan, nagdagdag kami ng kakayahang magpadala ng arbitrary na 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'
});
Susunod, pag-usapan natin ang bahagi ng server. Dapat tanggapin ng backend ang mga kahilingan sa http, punan ang mga ito ng karagdagang impormasyon, halimbawa, geo data (salamat
//Π²Ρ
ΠΎΠ΄ΡΡΠΈΠΉ 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"
}
Gayunpaman, ang mga array ay kasalukuyang na-convert sa mga string dahil Hindi lahat ng relational database ay sumusuporta sa mga paulit-ulit na field. Posible ring baguhin ang mga pangalan ng field o tanggalin ang mga ito gamit ang mga opsyonal na panuntunan sa pagmamapa. Pinapayagan ka nitong baguhin ang schema ng data kung kinakailangan o i-convert ang isang uri ng data sa isa pa. Halimbawa, kung ang isang json field ay naglalaman ng isang string na may timestamp (field_3_sub_field_1_sub_sub_field_1 mula sa halimbawa sa itaas), pagkatapos ay upang lumikha ng isang patlang sa database na may uri ng timestamp, kailangan mong magsulat ng isang panuntunan sa pagmamapa sa pagsasaayos. Sa madaling salita, ang uri ng data ng field ay tinutukoy muna ng json value, at pagkatapos ay ilalapat ang uri ng casting rule (kung naka-configure). Natukoy namin ang 4 na pangunahing uri ng data: STRING, FLOAT64, INT64 at TIMESTAMP. Ang mga panuntunan sa pagmamapa at uri ng casting ay ganito:
rules:
- "/field_1/subfield_1 -> " #ΠΏΡΠ°Π²ΠΈΠ»ΠΎ ΡΠ΄Π°Π»Π΅Π½ΠΈΡ ΠΏΠΎΠ»Ρ
- "/field_2/subfield_1 -> /field_10/subfield_1" #ΠΏΡΠ°Π²ΠΈΠ»ΠΎ ΠΏΠ΅ΡΠ΅Π½ΠΎΡΠ° ΠΏΠΎΠ»Ρ
- "/field_3/subfield_1/subsubfield_1 -> (timestamp) /field_20" #ΠΏΡΠ°Π²ΠΈΠ»ΠΎ ΠΏΠ΅ΡΠ΅Π½ΠΎΡΠ° ΠΏΠΎΠ»Ρ ΠΈ ΠΏΡΠΈΠ²Π΅Π΄Π΅Π½ΠΈΡ ΡΠΈΠΏΠ°
Algorithm para sa pagtukoy ng uri ng data:
- i-convert ang json structure sa flat structure
- pagtukoy sa uri ng data ng mga patlang sa pamamagitan ng mga halaga
- paglalapat ng mapping at type casting rules
Pagkatapos mula sa papasok na istraktura ng 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"
}
}
ang data schema ay makukuha:
"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
Naisip din namin na ang user ay dapat na mai-configure ang partitioning o hatiin ang data sa database ayon sa iba pang pamantayan at ipinatupad ang kakayahang itakda ang pangalan ng talahanayan na may pare-pareho o
tableName: '{{.product_type}}_{{._timestamp.Format "2006_01"}}'
Gayunpaman, ang istraktura ng mga papasok na kaganapan ay maaaring magbago sa runtime. Nagpatupad kami ng algorithm upang suriin ang pagkakaiba sa pagitan ng istraktura ng isang umiiral na talahanayan at ng istraktura ng isang papasok na kaganapan. Kung may nakitang pagkakaiba, ia-update ang talahanayan gamit ang mga bagong field. Upang gawin ito, gamitin ang patch SQL query:
#ΠΡΠΈΠΌΠ΅Ρ Π΄Π»Ρ Postgres
ALTER TABLE "schema"."table" ADD COLUMN new_column character varying
arkitektura
Bakit kailangan mong magsulat ng mga kaganapan sa file system, at hindi lamang isulat ang mga ito nang direkta sa database? Ang mga database ay hindi palaging gumaganap nang maayos kapag nakikitungo sa malaking bilang ng mga pagsingit (
Open Source at mga plano para sa hinaharap
Sa ilang mga punto, ang serbisyo ay nagsimulang magmukhang isang ganap na produkto at nagpasya kaming ilabas ito sa Open Source. Sa kasalukuyan, ipinatupad ang mga pagsasama sa Postgres, ClickHouse, BigQuery, Redshift, S3, Snowflake. Sinusuportahan ng lahat ng integration ang parehong batch at streaming mode ng paglo-load ng data. Nagdagdag ng suporta para sa mga kahilingan sa pamamagitan ng API.
Ang kasalukuyang scheme ng pagsasama ay ganito ang hitsura:
Kahit na ang serbisyo ay maaaring gamitin nang nakapag-iisa (halimbawa gamit ang Docker), mayroon din kami
β
β
β
Matutuwa kami kung tutulong ang EventNative na malutas ang iyong mga problema!
Ang mga rehistradong user lamang ang maaaring lumahok sa survey.
Anong sistema ng pangongolekta ng istatistika ang ginagamit sa iyong kumpanya?
-
48,0%Google Analytics12
-
4,0%Segment1
-
16,0%Isa pa (isulat sa mga komento)4
-
32,0%Ipinatupad ang iyong serbisyo8
25 user ang bumoto. 6 na user ang umiwas.
Pinagmulan: www.habr.com