Povijest našeg otvorenog koda: kako smo napravili analitičku uslugu u Gou i učinili je javno dostupnom

Trenutno gotovo svaka tvrtka u svijetu prikuplja statistiku o radnjama korisnika na web resursu. Motivacija je jasna – tvrtke žele znati kako se njihov proizvod/web stranica koristi i bolje razumjeti svoje korisnike. Naravno, na tržištu postoji velik broj alata za rješavanje ovog problema – od analitičkih sustava koji daju podatke u obliku nadzornih ploča i grafikona (npr. Google Analytics) na Customer Data Platform, koji vam omogućuju prikupljanje i objedinjavanje podataka iz različitih izvora u bilo kojem skladištu (npr. Segment).

Ali pronašli smo problem koji još nije riješen. Tako je rođeno EventNative — usluga analitike otvorenog koda. Pročitajte zašto smo odlučili razviti vlastitu uslugu, što nam je dala i koji je bio krajnji rezultat (sa dijelovima koda).

Povijest našeg otvorenog koda: kako smo napravili analitičku uslugu u Gou i učinili je javno dostupnom

Zašto bismo trebali razvijati vlastitu uslugu?

Bile su devedesete, preživljavali smo kako smo mogli. 2019. razvili smo API First Customer Data Platform kSense, što je omogućilo agregiranje podataka iz različitih izvora (Facebook oglasi, Stripe, Salesforce, Google play, Google Analytics itd.) za praktičniju analizu podataka, prepoznavanje ovisnosti itd. Primijetili smo da mnogi korisnici koriste našu platformu za analizu podataka posebno Google Analytics (u daljnjem tekstu GA). Razgovarali smo s nekim korisnicima i otkrili da im trebaju analitički podaci za njihov proizvod koje dobivaju pomoću GA-a, ali Google uzorkuje podatke i za mnoge, korisničko sučelje GA nije standard pogodnosti. Imali smo dovoljno razgovora s našim korisnicima i shvatili da mnogi koriste i platformu Segment (koja je, usput rečeno, tek neki dan prodan za 3.2 milijarde dolara).

Instalirali su Segment javascript pixel na svoj web resurs i podaci o ponašanju njihovih korisnika su učitani u navedenu bazu podataka (na primjer Postgres). Ali Segment ima i svoju lošu stranu - cijenu. Na primjer, ako web resurs ima 90,000 1,000 MTU (mjesečno praćenih korisnika), tada trebate platiti ~XNUMX $ mjesečno na blagajni. Postojao je i treći problem - neka proširenja preglednika (kao što je AdBlock) blokirala su prikupljanje analitike jer... http zahtjevi iz preglednika poslani su na domene GA i Segment. Na temelju želja naših klijenata kreirali smo analitičku uslugu koja prikuplja kompletan skup podataka (bez uzorkovanja), besplatna je i može raditi na vlastitoj infrastrukturi.

Kako usluga radi

Servis se sastoji od tri dijela: javascript piksel (koji smo kasnije prepisali u tipkalo), serverski dio je implementiran u GO jeziku, a planirano je korištenje Redshifta i BigQueryja kao interne baze podataka (kasnije su dodali podršku za Postgres, ClickHouse i Snowflake).

Odlučeno je ostaviti nepromijenjenu strukturu GA i Segment događaja. Sve što je bilo potrebno je duplicirati sve događaje s web resursa na kojem je piksel instaliran na našu pozadinu. Kako se pokazalo, to nije teško učiniti. Javascript piksel nadjačao je izvornu metodu biblioteke GA novom, koja je duplicirala događaj u našem sustavu.

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

S pikselom Segment sve je jednostavnije; ima metode međuprograma, od kojih smo mi koristili jednu.


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

Osim kopiranja događaja, dodali smo mogućnost slanja proizvoljnog jsona:


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

Zatim, razgovarajmo o poslužiteljskom dijelu. Pozadina bi trebala prihvatiti http zahtjeve, popuniti ih dodatnim informacijama, na primjer, zemljopisnim podacima (hvala maxmind za to) i zabilježiti u bazu podataka. Željeli smo uslugu učiniti što praktičnijom kako bi se mogla koristiti uz minimalnu konfiguraciju. Implementirali smo funkcionalnost određivanja podatkovne sheme na temelju strukture dolaznog json događaja. Vrste podataka definirane su vrijednostima. Ugniježđeni objekti se rastavljaju i svode na ravnu strukturu:

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

Međutim, nizovi se trenutno jednostavno pretvaraju u nizove jer Ne podržavaju sve relacijske baze podataka polja koja se ponavljaju. Također je moguće promijeniti nazive polja ili ih izbrisati korištenjem opcijskih pravila mapiranja. Omogućuju vam promjenu podatkovne sheme ako je potrebno ili pretvaranje jedne vrste podataka u drugu. Na primjer, ako json polje sadrži niz s vremenskom oznakom (polje_3_podpolje_1_pod_podpolje_1 iz gornjeg primjera), tada da biste stvorili polje u bazi podataka s vrstom vremenske oznake, trebate napisati pravilo mapiranja u konfiguraciji. Drugim riječima, tip podataka polja prvo je određen json vrijednošću, a zatim se primjenjuje pravilo pretvaranja tipa (ako je konfigurirano). Identificirali smo 4 glavne vrste podataka: STRING, FLOAT64, INT64 i TIMESTAMP. Pravila preslikavanja i pretvaranja tipa izgledaju ovako:

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

Algoritam za određivanje vrste podataka:

  • pretvoriti json strukturu u ravnu strukturu
  • određivanje vrste podataka polja po vrijednostima
  • primjenom pravila preslikavanja i pretvaranja tipa

Zatim iz dolazne json strukture:

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

dobit će se shema podataka:

"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

Također smo mislili da bi korisnik trebao moći konfigurirati particioniranje ili podijeliti podatke u bazi podataka prema drugim kriterijima i implementirali smo mogućnost postavljanja naziva tablice s konstantom ili izraz u konfiguraciji. U donjem primjeru, događaj će biti spremljen u tablicu s nazivom izračunatim na temelju vrijednosti polja product_type i _timestamp (na primjer zalihe_2020_10):

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

Međutim, struktura dolaznih događaja može se promijeniti tijekom izvođenja. Implementirali smo algoritam za provjeru razlike između strukture postojeće tablice i strukture dolaznog događaja. Ako se pronađe razlika, tablica će se ažurirati novim poljima. Da biste to učinili, upotrijebite patch SQL upit:

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

arhitektura

Povijest našeg otvorenog koda: kako smo napravili analitičku uslugu u Gou i učinili je javno dostupnom

Zašto trebate pisati događaje u datotečni sustav, a ne samo ih pisati izravno u bazu podataka? Baze podataka ne rade uvijek dobro kada rade s velikim brojem umetaka (Postgres preporuke). Da bi to učinio, Logger zapisuje dolazne događaje u datoteku iu zasebnoj goroutine (nit) Čitač datoteka čita datoteku, zatim se podaci pretvaraju i određuju. Nakon što se Upravitelj tablica uvjeri da je shema tablice ažurna, podaci će biti upisani u bazu podataka u jednoj seriji. Naknadno smo dodali mogućnost upisivanja podataka izravno u bazu, ali ovaj način rada koristimo za događaje koji nisu brojni - primjerice konverzije.

Open Source i planovi za budućnost

U nekom je trenutku usluga počela izgledati kao potpuni proizvod i odlučili smo je objaviti u Open Sourceu. Trenutno su implementirane integracije s Postgres, ClickHouse, BigQuery, Redshift, S3, Snowflake. Sve integracije podržavaju skupne i strujne načine učitavanja podataka. Dodana podrška za zahtjeve putem API-ja.

Trenutna shema integracije izgleda ovako:

Povijest našeg otvorenog koda: kako smo napravili analitičku uslugu u Gou i učinili je javno dostupnom

Iako se usluga može koristiti samostalno (na primjer pomoću Dockera), mi također imamo hostirana verzija, u kojem možete postaviti integraciju sa skladištem podataka, dodati CNAME svojoj domeni i pregledati statistiku o broju događaja. Naši neposredni planovi su dodati mogućnost skupljanja ne samo statistike s web resursa, već i podataka iz vanjskih izvora podataka i njihovo spremanje u bilo koju pohranu po vašem izboru!

→ GitHub
→ Документация
→ Zatišje

Bit će nam drago ako EventNative pomogne u rješavanju vaših problema!

U anketi mogu sudjelovati samo registrirani korisnici. Prijaviti se, molim.

Koji se sustav prikupljanja statistike koristi u vašoj tvrtki?

  • 48,0%Google Analytics12

  • 4,0%Segment1

  • 16,0%Još jedno (napišite u komentarima)4

  • 32,0%Implementirao svoju uslugu8

Glasovalo je 25 korisnika. Suzdržano je bilo 6 korisnika.

Izvor: www.habr.com

Dodajte komentar