Sakupljanje trupaca od Lokija

Sakupljanje trupaca od Lokija

U Badoou stalno pratimo nove tehnologije i procjenjujemo da li se isplati koristiti u našem sistemu. Željeli bismo podijeliti jednu od ovih studija sa zajednicom. Posvećen je Lokiju, sistemu agregacije dnevnika.

Loki je rješenje za pohranjivanje i pregled dnevnika, a ovaj stek također pruža fleksibilan sistem za njihovu analizu i slanje podataka Prometheusu. U maju je objavljeno još jedno ažuriranje, koje kreatori aktivno promovišu. Zanimalo nas je što Loki može učiniti, koje mogućnosti pruža i u kojoj mjeri može djelovati kao alternativa ELK-u, steku koji sada koristimo.

Šta je Loki

Grafana Loki je skup komponenti za kompletan sistem za rad sa trupcima. Za razliku od drugih sličnih sistema, Loki se bazira na ideji indeksiranja samo metapodataka dnevnika - oznaka (isto kao u Prometheusu), i komprimiranja samih dnevnika u zasebne komade.

Početna stranica, GitHub

Prije nego što uđemo u ono što možete učiniti s Lokijem, želim pojasniti što se podrazumijeva pod "idejom indeksiranja samo metapodataka". Uporedimo Loki pristup i pristup indeksiranju u tradicionalnim rješenjima kao što je Elasticsearch, koristeći primjer linije iz nginx dnevnika:

172.19.0.4 - - [01/Jun/2020:12:05:03 +0000] "GET /purchase?user_id=75146478&item_id=34234 HTTP/1.1" 500 8102 "-" "Stub_Bot/3.0" "0.001"

Tradicionalni sistemi analiziraju cijeli red, uključujući polja s velikim brojem jedinstvenih vrijednosti user_id i item_id, i pohranjuju sve u velikim indeksima. Prednost ovog pristupa je što možete brzo pokrenuti složene upite, budući da se gotovo svi podaci nalaze u indeksu. Ali to dolazi po cijeni jer indeks postaje velik, što se pretvara u zahtjeve za memorijom. Kao rezultat toga, indeks dnevnika punog teksta je uporediv po veličini sa samim zapisnicima. Da biste brzo pretražili po njemu, indeks se mora učitati u memoriju. I što je više dnevnika, indeks brže raste i više memorije troši.

Loki pristup zahtijeva da se iz stringa izdvoje samo potrebni podaci, čiji je broj vrijednosti mali. Na ovaj način dobijamo mali indeks i možemo pretraživati ​​podatke tako što ćemo ih filtrirati po vremenu i indeksiranim poljima, a zatim skenirati ostatak regularnim izrazima ili pretraživanjem podniza. Proces se ne čini najbržim, ali Loki dijeli zahtjev na nekoliko dijelova i izvršava ih paralelno, obrađujući veliku količinu podataka u kratkom vremenu. Broj fragmenata i paralelnih zahtjeva u njima je podesiv; dakle, količina podataka koja se može obraditi u jedinici vremena linearno zavisi od količine obezbeđenih resursa.

Ovaj kompromis između velikog, brzog indeksa i malog, paralelnog indeksa grube sile omogućava Lokiju da kontroliše troškove sistema. Može se fleksibilno konfigurirati i proširiti prema potrebama.

Loki stog se sastoji od tri komponente: Promtail, Loki, Grafana. Promtail prikuplja dnevnike, obrađuje ih i šalje Lokiju. Loki ih čuva. A Grafana može zatražiti podatke od Lokija i prikazati ih. Općenito, Loki se može koristiti ne samo za pohranjivanje dnevnika i pretraživanje po njima. Cijeli stog pruža velike mogućnosti za obradu i analizu ulaznih podataka na Prometheus način.
Opis procesa instalacije možete pronaći ovdje.

Pretraživanje po zapisnicima

Dnevnike možete pretraživati ​​u posebnom Grafana interfejsu - Exploreru. Upiti koriste jezik LogQL, koji je vrlo sličan PromQL-u koji se koristi u Prometheusu. U principu, može se smatrati distribuiranim grep.

Interfejs za pretragu izgleda ovako:

Sakupljanje trupaca od Lokija

Sam zahtjev se sastoji iz dva dijela: selektora i filtera. Selektor je pretraga koja koristi indeksirane metapodatke (oznake) koji su dodijeljeni zapisnicima, a filter je niz za pretraživanje ili regexp koji filtrira zapise definirane od strane selektora. U datom primjeru: U vitičastim zagradama postoji selektor, sve iza je filter.

{image_name="nginx.promtail.test"} |= "index"

Zbog načina na koji Loki radi, ne možete postavljati upite bez selektora, ali oznake mogu biti općenite koliko želite.

Selektor je vrijednost ključ/vrijednost u vitičastim zagradama. Možete kombinovati selektore i specificirati različite uslove pretraživanja koristeći operatore =, != ili regularne izraze:

{instance=~"kafka-[23]",name!="kafka-dev"} 
// Найдёт логи с лейблом instance, имеющие значение kafka-2, kafka-3, и исключит dev 

Filter je tekst ili regexp koji će filtrirati sve podatke koje prima selektor.

Moguće je dobiti ad-hoc grafikone na osnovu primljenih podataka u metričkom modu. Na primjer, možete saznati koliko se često unos koji sadrži string indeks pojavljuje u nginx zapisnicima:

Sakupljanje trupaca od Lokija

Potpuni opis mogućnosti možete pronaći u dokumentaciji LogQL.

Analiza dnevnika

Postoji nekoliko načina za prikupljanje dnevnika:

  • Koristeći Promtail, standardnu ​​komponentu steka za prikupljanje dnevnika.
  • Direktno iz docker kontejnera koristeći Loki Docker Logging Driver.
  • Koristite Fluentd ili Fluent Bit, koji mogu slati podatke Lokiju. Za razliku od Promtail-a, oni imaju gotove parsere za gotovo sve vrste dnevnika i mogu rukovati višelinijskim dnevnikima.

Obično se Promtail koristi za raščlanjivanje. Radi tri stvari:

  • Pronalazi izvore podataka.
  • Pričvršćuje etikete na njih.
  • Šalje podatke Lokiju.

Trenutno Promtail može čitati dnevnike iz lokalnih datoteka i iz systemd dnevnika. Mora biti instaliran na svakoj mašini sa koje se prikupljaju trupci.

Postoji integracija sa Kubernetesom: Promtail automatski, preko Kubernetes REST API-ja, prepoznaje stanje klastera i prikuplja evidencije sa čvora, usluge ili pod, odmah objavljujući oznake na osnovu metapodataka iz Kubernetes-a (ime pod, ime datoteke, itd.) .

Također možete objesiti naljepnice na osnovu podataka iz dnevnika koristeći Pipeline. Pipeline Promtail se može sastojati od četiri vrste faza. Više detalja u službena dokumentacija, odmah ću uočiti neke nijanse.

  1. Parsing stages. Ovo je faza RegEx i JSON. U ovoj fazi izvlačimo podatke iz dnevnika u takozvanu ekstrahovanu mapu. Možemo izdvojiti iz JSON-a jednostavnim kopiranjem polja koja su nam potrebna u ekstrahovanu mapu ili putem regularnih izraza (RegEx), gdje se imenovane grupe „mapiraju“ u ekstrahovanu mapu. Izvučena mapa je skladište ključ/vrijednost, gdje je ključ ime polja, a vrijednost njegova vrijednost iz dnevnika.
  2. Faze transformacije. Ova faza ima dvije opcije: transform, gdje postavljamo pravila transformacije, i izvor - izvor podataka za transformaciju iz ekstrahovane mape. Ako u ekstrahiranoj mapi nema takvog polja, ono će biti kreirano. Na ovaj način moguće je kreirati oznake koje nisu bazirane na ekstrahiranoj mapi. U ovoj fazi možemo manipulirati podacima u ekstrahiranoj mapi koristeći prilično moćnu Golang Template. Osim toga, moramo imati na umu da se ekstrahirana mapa učitava u potpunosti tokom raščlanjivanja, što omogućava, na primjer, provjeru vrijednosti u njoj: “{{if .tag}vrijednost oznake postoji{end}}”. Predložak podržava uslove, petlje i neke funkcije niza kao što su Replace i Trim.
  3. Faze akcije. U ovom trenutku možete učiniti nešto s ekstrahiranim sadržajem:
    • Kreirajte oznaku od ekstrahiranih podataka, koje će Loki indeksirati.
    • Promijenite ili postavite vrijeme događaja iz dnevnika.
    • Promijenite podatke (tekst dnevnika) koji će ići u Loki.
    • Kreirajte metriku.
  4. Faze filtriranja. Faza podudaranja, u kojoj možemo ili poslati unose koje ne trebamo /dev/null ili ih proslijediti na dalju obradu.

Koristeći primjer obrade regularnih nginx dnevnika, pokazat ću kako možete raščlaniti dnevnike koristeći Promtail.

Za test, uzmimo kao nginx-proxy modificiranu nginx sliku jwilder/nginx-proxy:alpine i mali demon koji se može pitati putem HTTP-a. Daemon ima nekoliko krajnjih tačaka na koje može pružiti odgovore različitih veličina, s različitim HTTP statusima i s različitim kašnjenjima.

Prikupljat ćemo dnevnike iz docker kontejnera, koji se mogu pronaći duž putanje /var/lib/docker/containers/ / -json.log

U docker-compose.yml konfigurišemo Promtail i navodimo putanju do konfiguracije:

promtail:
  image: grafana/promtail:1.4.1
 // ...
 volumes:
   - /var/lib/docker/containers:/var/lib/docker/containers:ro
   - promtail-data:/var/lib/promtail/positions
   - ${PWD}/promtail/docker.yml:/etc/promtail/promtail.yml
 command:
   - '-config.file=/etc/promtail/promtail.yml'
 // ...

Dodajte putanju do logova u promtail.yml (postoji opcija “docker” u konfiguraciji, koja radi istu stvar u jednom redu, ali ne bi bila tako jasna):

scrape_configs:
 - job_name: containers

   static_configs:
       labels:
         job: containerlogs
         __path__: /var/lib/docker/containers/*/*log  # for linux only

Kada je ova konfiguracija omogućena, dnevnici iz svih kontejnera će biti poslani Lokiju. Da bismo to izbjegli, mijenjamo postavke testnog nginx-a u docker-compose.yml - dodajemo polje oznake za evidentiranje:

proxy:
 image: nginx.test.v3
//…
 logging:
   driver: "json-file"
   options:
     tag: "{{.ImageName}}|{{.Name}}"

Uređivanje promtail.yml i postavljanje Pipeline-a. Ulaz uključuje zapisnike sljedećeg tipa:

{"log":"u001b[0;33;1mnginx.1    | u001b[0mnginx.test 172.28.0.3 - - [13/Jun/2020:23:25:50 +0000] "GET /api/index HTTP/1.1" 200 0 "-" "Stub_Bot/0.1" "0.096"n","stream":"stdout","attrs":{"tag":"nginx.promtail.test|proxy.prober"},"time":"2020-06-13T23:25:50.66740443Z"}
{"log":"u001b[0;33;1mnginx.1    | u001b[0mnginx.test 172.28.0.3 - - [13/Jun/2020:23:25:50 +0000] "GET /200 HTTP/1.1" 200 0 "-" "Stub_Bot/0.1" "0.000"n","stream":"stdout","attrs":{"tag":"nginx.promtail.test|proxy.prober"},"time":"2020-06-13T23:25:50.702925272Z"}

Faza cjevovoda:

 - json:
     expressions:
       stream: stream
       attrs: attrs
       tag: attrs.tag

Izvlačimo polja stream, attrs, attrs.tag (ako postoje) iz dolaznog JSON-a i stavljamo ih u ekstrahovanu mapu.

 - regex:
     expression: ^(?P<image_name>([^|]+))|(?P<container_name>([^|]+))$
     source: "tag"

Ako smo uspjeli staviti tag polje u ekstrahovanu mapu, onda pomoću regexp-a izdvajamo nazive slike i kontejnera.

 - labels:
     image_name:
     container_name:

Dodjeljujemo oznake. Ako se ključevi image_name i container_name nalaze u ekstrahiranim podacima, tada će njihove vrijednosti biti dodijeljene odgovarajućim oznakama.

 - match:
     selector: '{job="docker",container_name="",image_name=""}'
     action: drop

Odbacujemo sve zapise koji nemaju instalirane oznake image_name i container_name.

  - match:
     selector: '{image_name="nginx.promtail.test"}'
     stages:
       - json:
           expressions:
             row: log

Za sve dnevnike čije je ime_image nginx.promtail.test, izdvojite polje dnevnika iz izvornog dnevnika i stavite ga u ekstrahovanu mapu pomoću ključa reda.

  - regex:
         # suppress forego colors
         expression: .+nginx.+|.+[0m(?P<virtual_host>[a-z_.-]+) +(?P<nginxlog>.+)
         source: logrow

Čistimo liniju za unos regularnim izrazima i izvlačimo nginx virtuelni host i nginx log liniju.

     - regex:
         source: nginxlog
         expression: ^(?P<ip>[w.]+) - (?P<user>[^ ]*) [(?P<timestamp>[^ ]+).*] "(?P<method>[^ ]*) (?P<request_url>[^ ]*) (?P<request_http_protocol>[^ ]*)" (?P<status>[d]+) (?P<bytes_out>[d]+) "(?P<http_referer>[^"]*)" "(?P<user_agent>[^"]*)"( "(?P<response_time>[d.]+)")?

Parsirajte nginx dnevnik koristeći regularne izraze.

    - regex:
           source: request_url
           expression: ^.+.(?P<static_type>jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|pdf|txt|tar|wav|bmp|rtf|js|flv|swf|html|htm)$
     - regex:
           source: request_url
           expression: ^/photo/(?P<photo>[^/?.]+).*$
       - regex:
           source: request_url
           expression: ^/api/(?P<api_request>[^/?.]+).*$

Hajde da analiziramo request_url. Koristeći regexp određujemo svrhu zahtjeva: na statičke podatke, na fotografije, na API i postavljamo odgovarajući ključ u ekstrahovanoj mapi.

       - template:
           source: request_type
           template: "{{if .photo}}photo{{else if .static_type}}static{{else if .api_request}}api{{else}}other{{end}}"

Koristeći uvjetne operatore u Templateu, provjeravamo instalirana polja u ekstrahiranoj mapi i postavljamo potrebne vrijednosti za polje request_type: photo, static, API. Dodijelite drugo ako ne uspije. request_type sada sadrži tip zahtjeva.

       - labels:
           api_request:
           virtual_host:
           request_type:
           status:

Postavili smo oznake api_request, virtual_host, request_type i status (HTTP status) na osnovu onoga što smo uspjeli staviti u ekstrahovanu mapu.

       - output:
           source: nginx_log_row

Promjena izlaza. Sada očišćeni nginx dnevnik iz ekstrahovane mape ide Lokiju.

Sakupljanje trupaca od Lokija

Nakon pokretanja gornje konfiguracije, možete vidjeti da su svakom unosu dodijeljene oznake na osnovu podataka iz dnevnika.

Jedna stvar koju treba imati na umu je da dohvaćanje oznaka s velikim brojem vrijednosti (kardinalnosti) može značajno usporiti Lokija. To jest, ne biste trebali stavljati, na primjer, user_id u indeks. Više o tome pročitajte u članku “Kako oznake u Lokiju mogu učiniti upite dnevnika bržim i lakšim" Ali to ne znači da ne možete pretraživati ​​po user_id bez indeksa. Morate koristiti filtere prilikom pretraživanja („zgrabite“ podatke), a indeks ovdje djeluje kao identifikator toka.

Vizualizacija dnevnika

Sakupljanje trupaca od Lokija

Loki može djelovati kao izvor podataka za Grafana grafove koristeći LogQL. Podržane su sljedeće funkcije:

  • rate — broj zapisa u sekundi;
  • count over time — broj zapisa u navedenom opsegu.

Postoje i funkcije agregacije Sum, Avg i druge. Možete napraviti prilično složene grafikone, na primjer grafikon broja HTTP grešaka:

Sakupljanje trupaca od Lokija

Standardni izvor podataka Loki je donekle smanjen u funkcionalnosti u odnosu na izvor podataka Prometheus (na primjer, ne možete promijeniti legendu), ali Loki se može povezati kao izvor s tipom Prometheus. Nisam siguran da li je ovo dokumentovano ponašanje, ali sudeći po odgovoru programera “Kako konfigurirati Lokija kao Prometheus izvor podataka? · Izdanje #1222 · grafana/loki“, na primjer, potpuno je legalan, a Loki je potpuno kompatibilan s PromQL-om.

Dodajte Loki kao izvor podataka s tipom Prometheus i dodajte URL /loki:

Sakupljanje trupaca od Lokija

I možemo praviti grafikone, kao da radimo sa metrikom iz Prometeja:

Sakupljanje trupaca od Lokija

Mislim da je neusklađenost u funkcionalnosti privremena i programeri će to ispraviti u budućnosti.

Sakupljanje trupaca od Lokija

metrika

Loki pruža mogućnost izdvajanja numeričkih metrika iz dnevnika i slanja ih Prometheusu. Na primjer, nginx dnevnik sadrži broj bajtova po odgovoru, kao i, uz određenu modifikaciju standardnog formata dnevnika, vrijeme u sekundama koje je bilo potrebno da se odgovori. Ovi podaci se mogu izdvojiti i poslati Prometeju.

Dodajte još jedan odjeljak u promtail.yml:

- match:
   selector: '{request_type="api"}'
   stages:
     - metrics:
         http_nginx_response_time:
           type: Histogram
           description: "response time ms"
           source: response_time
           config:
             buckets: [0.010,0.050,0.100,0.200,0.500,1.0]
- match:
   selector: '{request_type=~"static|photo"}'
   stages:
     - metrics:
         http_nginx_response_bytes_sum:
           type: Counter
           description: "response bytes sum"
           source: bytes_out
           config:
             action: add
         http_nginx_response_bytes_count:
           type: Counter
           description: "response bytes count"
           source: bytes_out
           config:
             action: inc

Opcija vam omogućava da definirate i ažurirate metriku na osnovu podataka iz ekstrahovane karte. Ove metrike se ne šalju Lokiju - pojavljuju se u krajnjoj točki Promtail /metrics. Prometheus mora biti konfiguriran da prima podatke primljene u ovoj fazi. U gornjem primjeru, za request_type=“api” prikupljamo metriku histograma. Sa ovom vrstom metrike zgodno je dobiti percentile. Za statički i foto, prikupljamo zbir bajtova i broj redova u kojima smo dobili bajtove da bismo izračunali prosjek.

Pročitajte više o metrikama ovdje.

Otvorite port na Promtailu:

promtail:
     image: grafana/promtail:1.4.1
     container_name: monitoring.promtail
     expose:
       - 9080
     ports:
       - "9080:9080"

Uvjerite se da se metrika s promtail_custom prefiksom pojavi:

Sakupljanje trupaca od Lokija

Postavljanje Prometeja. Dodajte oglas za posao:

- job_name: 'promtail'
 scrape_interval: 10s
 static_configs:
   - targets: ['promtail:9080']

I crtamo grafikon:

Sakupljanje trupaca od Lokija

Na taj način možete saznati, na primjer, četiri najsporija upita. Također možete postaviti nadzor za ove metrike.

Skaliranje

Loki može biti u pojedinačnom binarnom ili u razdijeljenom načinu (horizontalno skalabilan način). U drugom slučaju, može sačuvati podatke u oblaku, a delovi i indeks se pohranjuju odvojeno. Verzija 1.5 uvodi mogućnost skladištenja na jednom mjestu, ali se još uvijek ne preporučuje korištenje u proizvodnji.

Sakupljanje trupaca od Lokija

Komadići se mogu pohraniti u S3 kompatibilnu memoriju, a horizontalno skalabilne baze podataka mogu se koristiti za pohranu indeksa: Cassandra, BigTable ili DynamoDB. Ostali dijelovi Lokija - Distributeri (za pisanje) i Querier (za upite) - su bez državljanstva i također su horizontalno skalirani.

Na konferenciji DevOpsDays Vancouver 2019, jedan od učesnika Callum Styan najavio je da s Lokijem njegov projekt ima petabajte dnevnika s indeksom manjim od 1% ukupne veličine: “Kako Loki povezuje metrike i zapise - i štedi vam novac".

Poređenje Lokija i ELK-a

Veličina indeksa

Da testiram rezultujuću veličinu indeksa, uzeo sam evidencije iz nginx kontejnera za koji je konfigurisan gore navedeni Pipeline. Dnevnik je sadržavao 406 reda sa ukupnim volumenom od 624 MB. Dnevnici su generisani u roku od sat vremena, otprilike 109 unosa u sekundi.

Primjer dva reda iz dnevnika:

Sakupljanje trupaca od Lokija

Kada je indeksirao ELK, ovo je dalo veličinu indeksa od 30,3 MB:

Sakupljanje trupaca od Lokija

U slučaju Lokija, to je rezultiralo otprilike 128 KB indeksa i otprilike 3,8 MB podataka u komadima. Vrijedi napomenuti da je dnevnik umjetno generiran i nije imao veliku raznolikost podataka. Jednostavan gzip na originalnom Docker JSON logu sa podacima dao je kompresiju od 95,4%, a uzimajući u obzir činjenicu da je samo očišćeni nginx log poslat samom Lokiju, kompresija do 4 MB je razumljiva. Ukupan broj jedinstvenih vrijednosti za Loki oznake bio je 35, što objašnjava malu veličinu indeksa. Za ELK dnevnik je također očišćen. Tako je Loki komprimirao originalne podatke za 96%, a ELK za 70%.

Potrošnja memorije

Sakupljanje trupaca od Lokija

Ako uporedimo cijeli Prometheus i ELK stack, onda Loki "jede" nekoliko puta manje. Jasno je da Go servis troši manje od Java servisa, a poređenje veličine JVM Heap Elasticsearch-a i dodijeljene memorije za Loki je netačno, ali ipak vrijedi napomenuti da Loki koristi mnogo manje memorije. Njegova CPU prednost nije toliko očigledna, ali je takođe prisutna.

Brzina

Loki brže "proždire" trupce. Brzina zavisi od mnogo faktora - kakvi su logovi, koliko smo sofisticirani u njihovom raščlanjivanju, mreža, disk, itd. - ali je definitivno veća od ELK-a (u mom testu - otprilike duplo više). To se objašnjava činjenicom da Loki stavlja mnogo manje podataka u indeks i, shodno tome, troši manje vremena na indeksiranje. Sa brzinom pretraživanja, situacija je suprotna: Loki primjetno usporava na podacima većim od nekoliko gigabajta, dok ELK-ova brzina pretraživanja ne ovisi o veličini podataka.

Pretraživanje po zapisnicima

Loki je značajno inferioran u odnosu na ELK u smislu mogućnosti pretraživanja dnevnika. Grep sa regularnim izrazima je moćan, ali je inferioran u odnosu na zrelu bazu podataka. Nedostatak upita raspona, agregacija samo po oznakama, nemogućnost pretraživanja bez oznaka - sve nas to ograničava u potrazi za informacijama od interesa u Lokiju. To ne znači da se pomoću Lokija ništa ne može pronaći, ali definira tok rada s logovama kada prvi put pronađete problem u Prometheusovim grafikonima, a zatim koristite ove oznake da potražite što se dogodilo u zapisnicima.

sučelje

Prije svega, prelijepo je (izvinite, nisam mogao odoljeti). Grafana ima zgodan interfejs, ali Kibana je mnogo bogatija funkcijama.

Prednosti i mane Lokija

Jedna od prednosti je što se Loki integrira s Prometheusom, tako da dobijamo metriku i upozorenja iz kutije. Pogodan je za prikupljanje dnevnika i njihovo pohranjivanje iz Kubernetes podova, jer ima otkrivanje usluga naslijeđeno od Prometheusa i automatski pričvršćuje oznake.

Loša strana je slaba dokumentacija. Neke stvari, na primjer, karakteristike i mogućnosti Promtail-a, otkrio sam tek u procesu proučavanja koda, srećom on je otvorenog koda. Još jedan nedostatak su slabe mogućnosti raščlanjivanja. Na primjer, Loki ne može raščlaniti višelinijske zapise. Još jedan nedostatak je što je Loki relativno mlada tehnologija (izdanje 1.0 je bilo u novembru 2019.).

zaključak

Loki je 100% zanimljiva tehnologija koja je pogodna za male i srednje projekte, omogućavajući rješavanje mnogih problema agregiranja dnevnika, pretraživanja dnevnika, praćenja i analize dnevnika.

Loki ne koristimo na Badoou jer imamo ELK stack koji nam odgovara i koji je godinama obrastao raznim prilagođenim rješenjima. Za nas je kamen spoticanja traženje po logovima. Sa skoro 100 GB dnevnika dnevno, važno nam je da možemo pronaći sve i još malo i to brzo. Za crtanje i praćenje koristimo druga rješenja koja su prilagođena našim potrebama i međusobno integrirana. Loki stack ima opipljive prednosti, ali nam neće dati više nego što već imamo, a njegove koristi sigurno neće nadmašiti troškove migracije.

I iako je nakon istraživanja postalo jasno da ne možemo koristiti Loki, nadamo se da će vam ovaj post pomoći u odabiru.

Spremište s kodom korištenim u članku se nalazi ovdje.

izvor: www.habr.com

Dodajte komentar