Sajarah open source kami: kumaha kami ngadamel jasa analitik di Go sareng nyayogikeun umum

Ayeuna, ampir unggal perusahaan di dunya ngumpulkeun statistik ngeunaan tindakan pangguna dina sumber wéb. Motivasi jelas - perusahaan hoyong terang kumaha produkna / situs wéb dianggo sareng langkung ngartos pangguna. Tangtosna, aya sajumlah ageung alat di pasar pikeun ngabéréskeun masalah ieu - tina sistem analitik anu nyayogikeun data dina bentuk dasbor sareng grafik (contona. Google Analytics) ka Platform Data Palanggan, anu ngamungkinkeun anjeun pikeun ngumpulkeun sareng ngahijikeun data tina sumber anu béda-béda dina gudang mana waé (contona. bagean).

Tapi kami mendakan masalah anu teu acan direngsekeun. Kitu lahirna EventNative - jasa analytics open source. Baca ngeunaan naha urang mutuskeun pikeun ngembangkeun jasa urang sorangan, naon eta masihan kami, sarta naon hasil tungtung éta (kalawan potongan kode).

Sajarah open source kami: kumaha kami ngadamel jasa analitik di Go sareng nyayogikeun umum

Naha urang kedah ngembangkeun jasa sorangan?

Taun nineties, urang salamet sabisa-bisa. 2019, kami ngembangkeun Platform Data Pelanggan Pertama API kSense, anu ngamungkinkeun pikeun ngumpulkeun data tina sumber anu béda (iklan Facebook, Stripe, Salesforce, Google Play, Google Analytics, jsb) pikeun analisis data anu langkung merenah, ngaidentipikasi kagumantungan, jsb. Kami geus noticed nu loba pamaké ngagunakeun platform kami pikeun analisis data husus Google Analytics (hereinafter GA). Urang ngobrol jeung sababaraha pamaké sarta manggihan yén maranéhna butuh data analytics pikeun produk maranéhanana yén maranéhna nampa maké ga, tapi data sampel Google jeung keur loba, panganteur pamaké ga teu standar genah. Kami ngagaduhan cukup paguneman sareng pangguna kami sareng sadar yén seueur ogé anu nganggo platform Segmen (anu, ku jalan kitu, ngan ukur dinten anu sanés. dijual pikeun $ 3.2 milyar).

Aranjeunna masang piksel javascript Bagéan dina sumber wéb sareng data ngeunaan paripolah panggunana dimuat kana pangkalan data anu ditangtukeun (contona Postgres). Tapi Segmen ogé ngagaduhan kalemahan - hargana. Salaku conto, upami sumber wéb ngagaduhan 90,000 MTU (pamaké anu dilacak bulanan), maka anjeun kedah mayar ~1,000 $ per bulan ka kasir. Aya ogé masalah katilu - sababaraha ekstensi browser (sapertos AdBlock) ngablokir kumpulan analytics kusabab ... requests http ti browser anu dikirim ka domain ga jeung Bagéan. Dumasar kana kahoyong klien kami, kami parantos nyiptakeun jasa analitik anu ngumpulkeun sakumpulan data lengkep (tanpa sampling), gratis sareng tiasa dianggo dina infrastruktur urang sorangan.

Kumaha jasa éta jalan

Ladenan ieu diwangun ku tilu bagian: piksel javascript (anu engké urang tuliskeun deui dina typescript), bagian server dilaksanakeun dina basa GO, sareng direncanakeun nganggo Redshift sareng BigQuery salaku database in-house (engké aranjeunna nambihan dukungan pikeun Postgres, ClickHouse sareng Snowflake).

Diputuskeun pikeun ngantepkeun struktur acara GA sareng Bagéan teu robih. Sadaya anu diperyogikeun nyaéta nyalin sadaya kajadian tina sumber wéb dimana piksel dipasang kana backend kami. Salaku tétéla, ieu teu hésé ngalakukeun. Piksel Javascript overridden métode perpustakaan GA aslina ku nu anyar, nu duplicated acara kana sistem kami.

//'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);
        });
    });
}

Kalayan piksel Bagéan sadayana langkung saderhana; éta ngagaduhan metode middleware, salah sahiji anu kami dianggo.


//'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.');
}

Salian nyalin acara, kami parantos nambihan kamampuan pikeun ngirim json sawenang:


//Отправка событий с произвольным 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'
});

Salajengna, hayu urang ngobrol ngeunaan bagian server. Backend kedah nampi pamundut http, eusian inpormasi tambahan, contona, data geo (hatur nuhun maxmind pikeun ieu) sareng rekam dina pangkalan data. Kami hoyong ngajantenkeun jasa sabisa-gancang supados tiasa dianggo kalayan konfigurasi minimal. Kami geus dilaksanakeun pungsionalitas nangtukeun schema data dumasar kana struktur acara json asup. Jinis data ditetepkeun ku nilai. Objék bersarang diuraikeun sareng diréduksi jadi struktur datar:

//входящий 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"
}

Sanajan kitu, arrays ayeuna ngan saukur dirobah jadi string sabab Henteu sakabéh database relational ngarojong widang ulang. Ieu oge mungkin keur ngaganti ngaran widang atawa ngahapus aranjeunna ngagunakeun aturan pemetaan pilihan. Éta ngamungkinkeun anjeun ngarobih skéma data upami diperyogikeun atanapi ngarobih hiji jinis data ka anu sanés. Contona, upami widang json ngandung string kalawan timestamp (field_3_sub_field_1_sub_sub_field_1 ti conto di luhur), lajeng dina raraga nyieun hiji widang dina database jeung tipe timestamp, Anjeun kudu nulis aturan pemetaan dina konfigurasi nu. Dina basa sejen, tipe data widang ditangtukeun mimitina ku nilai json, lajeng tipe aturan casting (lamun ngonpigurasi) diterapkeun. Kami parantos ngaidentifikasi 4 jinis data utama: STRING, FLOAT64, INT64 sareng TIMESTAMP. Aturan pemetaan sareng jinis tuang sapertos kieu:

rules:
  - "/field_1/subfield_1 -> " #правило удаления поля
  - "/field_2/subfield_1 -> /field_10/subfield_1" #правило переноса поля
  - "/field_3/subfield_1/subsubfield_1 -> (timestamp) /field_20" #правило переноса поля и приведения типа

Algoritma pikeun nangtukeun tipe data:

  • ngarobah struktur json kana struktur datar
  • nangtukeun tipe data widang ku nilai
  • nerapkeun pemetaan jeung aturan casting tipe

Lajeng tina struktur json asup:

{
    "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"
    }
}

skéma data bakal diala:

"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

Kami ogé ngira yén pangguna kedah tiasa ngonpigurasikeun partisi atanapi ngabagi data dina pangkalan data dumasar kana kriteria anu sanés sareng ngalaksanakeun kamampuan pikeun nyetél nami méja kalayan konstanta atanapi éksprési dina konfigurasi. Dina conto di handap ieu, acara bakal disimpen kana méja kalayan nami diitung dumasar kana nilai tina product_type sareng widang _timestamp (contona. suplai_2020_10):

tableName: '{{.product_type}}_{{._timestamp.Format "2006_01"}}'

Sanajan kitu, struktur acara asup bisa robah dina runtime. Kami parantos ngalaksanakeun algoritma pikeun pariksa bédana antara struktur tabel anu tos aya sareng struktur acara anu bakal datang. Lamun bédana kapanggih, tabél bakal diropéa kalawan widang anyar. Jang ngalampahkeun ieu, nganggo patch query SQL:

#Пример для Postgres
ALTER TABLE "schema"."table" ADD COLUMN new_column character varying

gawena undagi

Sajarah open source kami: kumaha kami ngadamel jasa analitik di Go sareng nyayogikeun umum

Naha anjeun kedah nyerat acara kana sistem file, sareng henteu ngan ukur nyerat langsung kana pangkalan data? Basis data henteu salawasna berkinerja saé nalika nanganan jumlah sisipan anu ageung (Rekomendasi Postgres). Jang ngalampahkeun ieu, Logger nulis acara asup ka file na dina goroutine misah (thread) Pamaca file maca file, lajeng data dirobah sarta ditangtukeun. Saatos manajer Table mastikeun yén skéma tabel nyaéta up-to-date, data bakal ditulis kana database dina hiji bets. Salajengna, kami nambihan kamampuan nyerat data langsung kana pangkalan data, tapi kami nganggo mode ieu pikeun acara anu henteu seueur - contona, konversi.

Open Source sareng rencana pikeun masa depan

Di sawatara titik, jasa mimiti kasampak kawas produk full-fledged sarta kami mutuskeun pikeun ngaleupaskeun ka Open Source. Ayeuna, integrasi sareng Postgres, ClickHouse, BigQuery, Redshift, S3, Snowflake parantos dilaksanakeun. Sadaya integrasi ngadukung modeu bets sareng streaming pikeun ngamuat data. Ditambahkeun rojongan pikeun requests via API.

Skéma integrasi ayeuna sapertos kieu:

Sajarah open source kami: kumaha kami ngadamel jasa analitik di Go sareng nyayogikeun umum

Sanaos jasa éta tiasa dianggo sacara mandiri (contona nganggo Docker), kami ogé gaduh Vérsi hosted, dimana anjeun tiasa nyetél integrasi sareng gudang data, tambahkeun CNAME kana domain anjeun sareng ningali statistik ngeunaan jumlah kajadian. Rencana langsung kami nyaéta pikeun nambihan kamampuan pikeun ngahijikeun henteu ngan ukur statistik tina sumber wéb, tapi ogé data tina sumber data éksternal sareng simpen kana panyimpenan anu anjeun pikahoyong!

→ GitHub
→ Dokuméntasi
→ Slack

Kami bakal bungah upami EventNative ngabantosan masalah anjeun!

Ngan pamaké nu kadaptar bisa ilubiung dina survey. Daptar, Punten.

Sistem pangumpulan statistik naon anu dianggo di perusahaan anjeun?

  • 48,0%Google Analytics12

  • 4,0%Bagéan 1

  • 16,0%Lain (tulis dina komentar)4

  • 32,0%Dilaksanakeun jasa anjeun8

25 pamaké milih. 6 pamaké abstained.

sumber: www.habr.com

Tambahkeun komentar