Avoimen lähdekoodin historia: kuinka teimme analytiikkapalvelun Gossa ja teimme sen julkisesti saataville

Tällä hetkellä lähes jokainen yritys maailmassa kerää tilastoja käyttäjien toimista verkkoresurssissa. Motivaatio on selvä – yritykset haluavat tietää, miten heidän tuotettaan/verkkosivustoaan käytetään ja ymmärtää paremmin käyttäjiään. Markkinoilla on tietysti suuri määrä työkaluja tämän ongelman ratkaisemiseksi - analytiikkajärjestelmistä, jotka tarjoavat tietoja kojelaudoiden ja kaavioiden muodossa (esim. Google Analytics) Customer Data Platformiin, jonka avulla voit kerätä ja koota tietoja eri lähteistä missä tahansa varastossa (esim. Segmentti).

Mutta löysimme ongelman, jota ei ole vielä ratkaistu. Näin syntyi TapahtumaNative — avoimen lähdekoodin analytiikkapalvelu. Lue, miksi päätimme kehittää omaa palveluamme, mitä se antoi meille ja mikä oli lopputulos (koodinpätkineen).

Avoimen lähdekoodin historia: kuinka teimme analytiikkapalvelun Gossa ja teimme sen julkisesti saataville

Miksi meidän pitäisi kehittää omaa palveluamme?

Oli 2019-luku, selvisimme niin hyvin kuin pystyimme. Vuonna XNUMX kehitimme API First Customer Data Platformin kSense, joka mahdollisti tietojen yhdistämisen eri lähteistä (Facebook-mainokset, Stripe, Salesforce, Google play, Google Analytics jne.) kätevämpää data-analyysiä, riippuvuuksien tunnistamista jne. Olemme huomanneet, että monet käyttäjät käyttävät alustamme tietojen analysointiin erityisesti Google Analyticsia (jäljempänä GA). Keskustelimme joidenkin käyttäjien kanssa ja huomasimme, että he tarvitsevat tuotteensa analytiikkatietoja, jotka he saavat GA:n kautta, mutta Google ottaa näytteitä tiedoista ja monille GA-käyttöliittymä ei ole mukavuuden standardi. Kävimme tarpeeksi keskusteluja käyttäjiemme kanssa ja huomasimme, että monet käyttivät myös Segment-alustaa (joka muuten oli juuri toissapäivänä myytiin 3.2 miljardilla dollarilla).

He asensivat Segment javascript -pikselin verkkoresursseihinsa ja tiedot heidän käyttäjiensä käyttäytymisestä ladattiin määritettyyn tietokantaan (esimerkiksi Postgresiin). Mutta segmentillä on myös haittapuolensa - hinta. Esimerkiksi, jos verkkoresurssilla on 90,000 1,000 MTU (kuukausittain seurattuja käyttäjiä), sinun on maksettava kassalle ~XNUMX XNUMX $ kuukaudessa. Oli myös kolmas ongelma - jotkut selainlaajennukset (kuten AdBlock) estivät analytiikan keräämisen, koska... http-pyynnöt selaimelta lähetettiin GA- ja Segment-verkkotunnuksiin. Asiakkaidemme toiveiden pohjalta olemme luoneet analytiikkapalvelun, joka kerää täydellisen datajoukon (ilman otosta), on ilmainen ja voi toimia omalla infrastruktuurillamme.

Kuinka palvelu toimii

Palvelu koostuu kolmesta osasta: javascript-pikselistä (jonka kirjoitimme myöhemmin uudelleen koneella), palvelinosa on toteutettu GO-kielellä ja Redshiftiä ja BigQueryä suunniteltiin käyttämään talon sisäisenä tietokantana (myöhemmin ne lisäsivät tukea mm. Postgres, ClickHouse ja Snowflake).

GA- ja segmenttitapahtumien rakenne päätettiin jättää ennalleen. Tarvittiin vain kopioida kaikki tapahtumat verkkoresurssista, johon pikseli on asennettu, taustajärjestelmäämme. Kuten käy ilmi, tämä ei ole vaikea tehdä. Javascript-pikseli ohitti alkuperäisen GA-kirjastomenetelmän uudella, mikä kopioi tapahtuman järjestelmäämme.

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

Segment-pikselillä kaikki on yksinkertaisempaa; siinä on väliohjelmistomenetelmiä, joista yhtä käytimme.


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

Tapahtumien kopioimisen lisäksi olemme lisänneet mahdollisuuden lähettää mielivaltaisia ​​json-tiedostoja:


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

Seuraavaksi puhutaan palvelinosasta. Taustajärjestelmän tulee hyväksyä http-pyynnöt, täyttää ne lisätiedoilla, esimerkiksi geotiedoilla (kiitos maxmind tätä varten) ja tallenna se tietokantaan. Halusimme tehdä palvelusta mahdollisimman kätevän, jotta sitä voidaan käyttää minimaalisella konfiguraatiolla. Olemme toteuttaneet toiminnon määrittää dataskeema saapuvan json-tapahtuman rakenteen perusteella. Tietotyypit määritellään arvojen mukaan. Sisäkkäiset objektit hajotetaan ja pelkistetään tasaiseksi rakenteeksi:

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

Matriisit muunnetaan kuitenkin tällä hetkellä yksinkertaisesti merkkijonoiksi, koska Kaikki relaatiotietokannat eivät tue toistuvia kenttiä. On myös mahdollista muuttaa kenttien nimiä tai poistaa niitä valinnaisten kartoitussääntöjen avulla. Niiden avulla voit muuttaa tietoskeemaa tarvittaessa tai muuntaa yhden tietotyypin toiseksi. Jos esimerkiksi json-kenttä sisältää merkkijonon, jossa on aikaleima (field_3_sub_field_1_sub_sub_field_1 yllä olevasta esimerkistä), jotta voit luoda tietokantaan kentän aikaleimatyypillä, sinun on kirjoitettava määrityksiin kartoitussääntö. Toisin sanoen kentän tietotyyppi määritetään ensin json-arvon perusteella, ja sitten sovelletaan tyypin suoratoistosääntöä (jos sellainen on määritetty). Olemme tunnistaneet neljä päätietotyyppiä: STRING, FLOAT4, INT64 ja TIMESTAMP. Kartoitus- ja tyyppikirjoitussäännöt näyttävät tältä:

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

Algoritmi tietotyypin määrittämiseksi:

  • muuntaa json-rakenne litteäksi rakenteeksi
  • kenttien tietotyypin määrittäminen arvojen perusteella
  • soveltamalla kartoitus- ja tyyppivalusääntöjä

Sitten saapuvasta json-rakenteesta:

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

tietoskeema saadaan:

"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

Ajattelimme myös, että käyttäjän pitäisi pystyä konfiguroimaan osiointia tai jakamaan tietoja tietokannassa muiden kriteerien mukaan ja otettiin käyttöön mahdollisuus asettaa taulukon nimi vakiolla tai ilmaisu kokoonpanossa. Alla olevassa esimerkissä tapahtuma tallennetaan taulukkoon, jonka nimi on laskettu tuote_tyyppi- ja _aikaleima-kenttien arvojen perusteella (esim. tarvikkeet_2020_10):

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

Saapuvien tapahtumien rakenne voi kuitenkin muuttua ajon aikana. Olemme toteuttaneet algoritmin, joka tarkistaa olemassa olevan taulukon rakenteen ja saapuvan tapahtuman rakenteen välisen eron. Jos ero löytyy, taulukko päivitetään uusilla kentillä. Voit tehdä tämän käyttämällä korjaustiedoston SQL-kyselyä:

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

Arkkitehtuuri

Avoimen lähdekoodin historia: kuinka teimme analytiikkapalvelun Gossa ja teimme sen julkisesti saataville

Miksi tapahtumat pitää kirjoittaa tiedostojärjestelmään, eikä vain kirjoittaa niitä suoraan tietokantaan? Tietokannat eivät aina toimi hyvin käsiteltäessä suuria määriä lisäyksiä (Postgresin suositukset). Tätä varten Logger kirjoittaa saapuvat tapahtumat tiedostoon ja erillisessä gorutiinissa (säikeessä) Tiedostonlukija lukee tiedoston, sitten tiedot muunnetaan ja määritetään. Kun taulukonhallinta on varmistanut, että taulukkoskeema on ajan tasalla, tiedot kirjoitetaan tietokantaan yhtenä eränä. Myöhemmin lisäsimme mahdollisuuden kirjoittaa tietoja suoraan tietokantaan, mutta käytämme tätä tilaa tapahtumiin, joita ei ole lukuisia - esimerkiksi konversioita.

Open Source ja tulevaisuuden suunnitelmat

Jossain vaiheessa palvelu alkoi näyttää täysivaltaiselta tuotteelta ja päätimme julkaista sen avoimeen lähdekoodiin. Tällä hetkellä on toteutettu integraatioita Postgresin, ClickHousen, BigQueryn, Redshiftin, S3:n ja Snowflaken kanssa. Kaikki integraatiot tukevat sekä erä- että suoratoistotilaa tietojen lataamiseen. Lisätty tuki API:n kautta tehtäville pyynnöille.

Nykyinen integraatiosuunnitelma näyttää tältä:

Avoimen lähdekoodin historia: kuinka teimme analytiikkapalvelun Gossa ja teimme sen julkisesti saataville

Vaikka palvelua voi käyttää itsenäisesti (esimerkiksi Dockerin avulla), meillä on myös isännöity versio, jossa voit määrittää integroinnin tietovarastoon, lisätä CNAME-tunnuksen verkkotunnukseesi ja tarkastella tilastoja tapahtumien määrästä. Välittömänä suunnitelmamme on lisätä mahdollisuus kerätä verkkoresurssin tilastojen lisäksi myös ulkoisten tietolähteiden tietoja ja tallentaa ne haluamaasi tallennustilaan!

→ GitHub
→ Asiakirjat
→ New Rose Hotel

Olemme iloisia, jos EventNative auttaa ratkaisemaan ongelmasi!

Vain rekisteröityneet käyttäjät voivat osallistua kyselyyn. Kirjaudu sisään, ole kiltti.

Mitä tilastonkeruujärjestelmää yrityksessäsi käytetään?

  • 48,0%Google Analytics12

  • 4,0%Segmentti 1

  • 16,0%Toinen (kirjoita kommentteihin)4

  • 32,0%Totesin palvelusi8

25 käyttäjää äänesti. 6 käyttäjää pidättyi äänestämästä.

Lähde: will.com

Lisää kommentti