Noi di Badoo monitoremu in permanenza e tecnulugia novi è evaluemu s'ellu l'utilizanu o micca in u nostru sistema. Vulemu sparte unu di sti studii cù a cumunità. Hè dedicatu à Loki, un sistema di aggregazione di log.
Loki hè una suluzione per almacenà è vede i logs, è sta pila furnisce ancu un sistema flexible per analizà è mandà dati à Prometheus. In maghju, hè stata liberata una altra aghjurnazione, chì hè attivamente promossa da i creatori. Eramu interessati à ciò chì Loki pò fà, quali caratteristiche furnisce, è in quantu pò agisce cum'è una alternativa à ELK, a pila chì usemu avà.
Cosa hè Loki
Grafana Loki hè un inseme di cumpunenti per un sistema di logu cumpletu. A cuntrariu di l'altri sistemi simili, Loki hè basatu annantu à l'idea di indexà solu metadati di log - etichette (cum'è in Prometheus), è cumpressione i logs stessi fiancu à fiancu in pezzi separati.
Prima di andà in una descrizzione di ciò chì pudete fà cù Loki, vogliu chjarificà ciò chì significa "l'idea di indexà solu metadata". Comparamu l'approcciu di Loki è l'approcciu d'indexazione in soluzioni tradiziunali, cum'è Elasticsearch, usendu l'esempiu di una linea da u log nginx:
I sistemi tradiziunali analizanu tutta a fila, cumprese i campi cù assai valori unichi di user_id è item_id, è almacenanu tuttu in indici grandi. U vantaghju di questu approcciu hè chì pudete eseguisce dumande cumplessu rapidamente, postu chì quasi tutte e dati sò in l'indici. Ma avete da pagà per questu in chì l'indici diventa grande, chì si traduce in esigenze di memoria. In u risultatu, l'indici di testu sanu di logs hè paragunabile in grandezza à i logs stessi. Per fà una ricerca rapida, l'indexu deve esse caricatu in memoria. E più logs, più veloce l'indice aumenta è più memoria consuma.
L'approcciu di Loki esige chì solu i dati necessarii sò estratti da a stringa, u numeru di valori di quale hè chjucu. Questu modu avemu un picculu indice è pudemu cercà i dati filtrà per u tempu è i campi indexati, è poi scansendu u restu cù espressioni regulari o ricerca di substring. U prucessu ùn pare micca u più veloce, ma Loki divide a dumanda in parechje parte è eseguisce in parallelu, processendu una grande quantità di dati in pocu tempu. U numaru di shards è dumande parallele in elli hè configurabile; cusì, a quantità di dati chì ponu esse trattati per unità di tempu dipende linearmente da a quantità di risorse furnite.
Stu scambiu trà un grande indice veloce è un picculu indice di forza bruta parallela permette à Loki di cuntrullà u costu di u sistema. Pò esse cunfiguratu flexiblemente è espansu secondu i vostri bisogni.
A pila Loki hè custituita da trè cumpunenti: Promtail, Loki, Grafana. Promtail raccoglie logs, li processa è li manda à Loki. Loki li tene. È Grafana pò dumandà dati da Loki è mostrà. In generale, Loki pò esse usatu micca solu per almacenà logs è cercà per elli. L'intera pila furnisce grandi opportunità per processà è analizà e dati entranti cù u modu Prometheus.
Una descrizzione di u prucessu di stallazione pò esse truvata ccà.
Ricerca di log
Pudete cercà i logs in una interfaccia speciale Grafana - Explorer. E dumande utilizanu a lingua LogQL, chì hè assai simili à u PromQL utilizatu da Prometheus. In principiu, pò esse pensatu cum'è un grep distribuitu.
L'interfaccia di ricerca hè cusì:
A dumanda stessu hè custituita da duie parti: selettore è filtru. Selector hè una ricerca per metadati indexati (etichette) chì sò assignati à i logs, è u filtru hè una stringa di ricerca o regexp chì filtra i registri definiti da u selettore. In l'esempiu datu: In parentesi curly - u selettore, tuttu dopu - u filtru.
{image_name="nginx.promtail.test"} |= "index"
A causa di a manera chì Loki funziona, ùn pudete micca fà richieste senza un selettore, ma l'etichette ponu esse fatte arbitrariamente generiche.
U selettore hè a chjave-valore di u valore in parentesi curly. Pudete combine selettori è specificà diverse cundizioni di ricerca cù l'operatori =, != o espressioni regulari:
{instance=~"kafka-[23]",name!="kafka-dev"}
// Найдёт логи с лейблом instance, имеющие значение kafka-2, kafka-3, и исключит dev
Un filtru hè un testu o regexp chì filtrarà tutte e dati ricevuti da u selettore.
Hè pussibule ottene gràfiche ad-hoc basatu nantu à e dati ricevuti in u modu metrica. Per esempiu, pudete truvà a frequenza di l'occurrence in i logs nginx di una entrata chì cuntene a stringa d'indici:
Una descrizzione completa di e funziunalità pò esse truvata in a documentazione LogQL.
Analisi di log
Ci hè parechje manere di cullà i logs:
Cù l'aiutu di Promtail, un cumpunente standard di a pila per a cullizzioni di logs.
Aduprate Fluentd o Fluent Bit chì ponu mandà dati à Loki. A cuntrariu di Promtail, anu parsers pronti per quasi ogni tipu di log è ponu ancu gestisce logs multiline.
Di solitu Promtail hè utilizatu per l'analisi. Face trè cose:
Trova fonti di dati.
Attaccà etichette à elli.
Mandate dati à Loki.
Attualmente Promtail pò leghje logs da i fugliali lucali è da u journal systemd. Deve esse stallatu nantu à ogni macchina da quale i logs sò cullati.
Ci hè integrazione cù Kubernetes: Promtail scopre automaticamente u statu di u cluster per mezu di l'API REST di Kubernetes è raccoglie i logs da un node, serviziu o pod, immediatamente postendu etichette basate nantu à metadata da Kubernetes (nome di pod, nome di file, etc.).
Pudete ancu appiccà etichette basate nantu à e dati da u log usendu Pipeline. Pipeline Promtail pò esse cumpostu di quattru tippi di tappe. Più dettagli - in documentazione ufficiale, Vogliu subitu nutà alcune di e sfumature.
Analisi di fasi. Questu hè u stadiu di RegEx è JSON. À questu stadiu, avemu estratti dati da i logs in a chjamata mappa estratta. Pudete estrattà da JSON per simplificà i campi chì avemu bisognu in a mappa estratta, o attraversu espressioni regulari (RegEx), induve i gruppi chjamati sò "mappati" in a mappa estratta. A mappa estratta hè un almacenamentu chjave-valore, induve a chjave hè u nome di u campu, è u valore hè u so valore da i logs.
Trasforma i tappe. Questa tappa hà duie opzioni: trasfurmà, induve avemu stabilitu e regule di trasfurmazioni, è fonte - a fonte di dati per a trasfurmazioni da a mappa estratta. Se ùn ci hè micca un tali campu in a mappa estratta, allora serà creatu. Cusì, hè pussibule di creà etichette chì ùn sò micca basate nantu à a mappa estratta. À questu stadiu, pudemu manipulà e dati in a mappa estratta cù un abbastanza putente mudellu di golang. Inoltre, avemu da ricurdà chì a mappa estratta hè cumplettamente caricata durante l'analisi, chì permette, per esempiu, di verificà u valore in questu: "{{if .tag}tag value exists{end}}". U Template supporta e cundizioni, i loops, è alcune funzioni di stringa cum'è Replace and Trim.
Fasi d'azzione. In questu stadiu, pudete fà qualcosa cù l'estratti:
Crea una etichetta da i dati estratti, chì serà indiziatu da Loki.
Cambia o stabilisce l'ora di l'avvenimentu da u logu.
Cambia i dati (testu di log) chì andarà à Loki.
Crea metrica.
Tappe di filtrazione. A tappa di partita, induve pudemu sia mandà registri chì ùn avemu micca bisognu à /dev/null, o mandalli per un ulteriore prucessu.
Utilizendu l'esempiu di processà i logs nginx ordinali, vi mustrarà cumu pudete analizà i logs cù Promtail.
Per a prova, pigliemu una immagine nginx jwilder/nginx-proxy:alpine mudificata è un picculu demoniu chì pò dumandà sè stessu via HTTP cum'è nginx-proxy. U daemon hà parechje endpoints, à quale pò dà risposti di diverse dimensioni, cù diversi stati HTTP è cù diversi ritardi.
Raccoglieremu i logs da i cuntenituri docker, chì ponu esse truvati longu u percorsu /var/lib/docker/containers/ / -json.log
In docker-compose.yml avemu stallatu Promtail è specifichi u percorsu à a cunfigurazione:
Aghjunghjite u percorsu à i logs à promtail.yml (ci hè una opzione "docker" in a cunfigurazione chì face u listessu in una linea, ma ùn saria micca cusì evidente):
scrape_configs:
- job_name: containers
static_configs:
labels:
job: containerlogs
__path__: /var/lib/docker/containers/*/*log # for linux only
Quandu sta cunfigurazione hè attivata, Loki riceverà logs da tutti i cuntenituri. Per evitari, cambiemu i paràmetri di a prova nginx in docker-compose.yml - aghjunghje logging à u campu di tag:
Per tutti i logs chì l'image_name hè uguali à nginx.promtail.test, avemu estrattu u campu di log da u logu di l'origine è u mette in a mappa estratta cù a chjave di fila.
Parse request_url. Cù l'aiutu di regexp, determinemu u scopu di a dumanda: à statics, to photos, to API è stabilisce a chjave currispundente in a mappa estratta.
- template:
source: request_type
template: "{{if .photo}}photo{{else if .static_type}}static{{else if .api_request}}api{{else}}other{{end}}"
Utilizendu operatori cundiziunali in Template, cuntrollemu i campi installati in a mappa estratta è stabilisce i valori richiesti per u campu request_type: photo, static, API. Assignà un altru se falliu. Avà request_type cuntene u tipu di dumanda.
Avemu stabilitu l'etichette api_request, virtual_host, request_type è status (statu HTTP) basatu annantu à ciò chì avemu sappiutu mette in a mappa estratta.
- output:
source: nginx_log_row
Cambia l'output. Avà u log nginx pulito da a mappa estratta va à Loki.
Dopu avè eseguitu a cunfigurazione sopra, pudete vede chì ogni entrata hè tichjata in basa di dati da u log.
Tenite in mente chì l'estrazione di etichette cù un gran numaru di valori (cardinalità) pò rallentà significativamente Loki. Questu hè, ùn deve micca mette in l'indici, per esempiu, user_id. Leghjite più nantu à questu in l'articuluCumu l'etichette in Loki ponu fà e dumande di log più veloce è faciule". Ma questu ùn significa micca chì ùn pudete micca cercà per user_id senza indici. Hè necessariu d'utilizà filtri durante a ricerca ("grab" secondu a dati), è l'indici quì agisce cum'è un identificatore di flussu.
Visualizazione di log
Loki pò agisce cum'è una fonte di dati per i charts Grafana cù LogQL. E seguenti caratteristiche sò supportate:
rate - numeru di records per seconda;
cuntà cù u tempu - u numeru di records in u intervallu datu.
Ci sò ancu funzioni aggregating Sum, Avg è altri. Pudete custruisce grafici abbastanza cumplessi, per esempiu, un graficu di u numeru di errori HTTP:
A fonte di dati predeterminata di Loki hè un pocu menu funziunale cà a fonte di dati Prometheus (per esempiu, ùn pudete micca cambià a legenda), ma Loki pò esse cunnessu cum'è fonte di tipu Prometheus. Ùn sò micca sicuru se questu hè un cumpurtamentu documentatu, ma à ghjudicà da a risposta di i sviluppatori "Cumu cunfigurà Loki cum'è fonte di dati Prometheus? · Issue #1222 · grafana/loki", per esempiu, hè perfettamente legale è Loki hè cumplettamente cumpatibile cù PromQL.
Aghjunghjite Loki cum'è fonte di dati cù u tipu Prometheus è aghjunghje l'URL /loki:
È pudete fà grafici, cum'è s'ellu travagliassi cù metriche di Prometheus:
Pensu chì a discrepanza in a funziunalità hè tempuranee è i sviluppatori l'arraggianu in u futuru.
Metriche
Loki furnisce l'abilità di estrae metriche numeriche da i logs è di mandà à Prometheus. Per esempiu, u logu nginx cuntene u numeru di bytes per risposta, è ancu, cù una certa mudificazione di u formatu di log standard, u tempu in sicondi chì hà pigliatu per risponde. Queste dati ponu esse estratti è mandati à Prometheus.
L'opzione permette di definisce è aghjurnà e metriche basate nantu à e dati da a mappa estratta. Queste metriche ùn sò micca mandate à Loki - appariscenu in l'endpoint Promtail /metrics. Prometheus deve esse cunfiguratu per riceve dati da questa tappa. In l'esempiu di sopra, per request_type = "api" cullemu una metrica d'istogramma. Cù stu tipu di metrica hè cunvenutu per ottene percentili. Per statics and photos, cullighjemu a summa di bytes è u numeru di fila in quale avemu ricevutu bytes per calculà a media.
Questu modu pudete scopre, per esempiu, e quattru richieste più lente. Pudete ancu cunfigurà u monitoraghju per queste metriche.
Scaling
Loki pò esse in modu binariu unicu è sharded (modu scalabile horizontalmente). In u sicondu casu, pò salvà dati à u nuvulu, è i pezzi è l'indici sò guardati separatamente. In a versione 1.5, a capacità di almacenà in un locu hè implementata, ma ùn hè ancu cunsigliatu per aduprà in a produzzione.
Chunks ponu esse guardati in un almacenamentu S3-compatibile, è e basa di dati scalabile horizontale ponu esse aduprate per almacenà indici: Cassandra, BigTable o DynamoDB. L'altri parti di Loki - Distributori (per scrive) è Querier (per dumande) - sò senza statu è ancu scala horizontale.
À a cunferenza DevOpsDays Vancouver 2019, unu di i participanti Callum Styan hà annunziatu chì cù Loki u so prughjettu hà petabytes di logs cù un indice di menu di 1% di a dimensione tutale: "Cume Loki Correlates Metrics è Logs - è vi risparmia soldi".
Comparazione di Loki è ELK
Taglia di l'indice
Per pruvà a dimensione di l'indici resultanti, aghju pigliatu logs da u containeru nginx per quale u Pipeline sopra hè stata cunfigurata. U schedariu di logu cuntene 406 linii cù un voluminu tutale di 624 MB. I logs sò stati generati in una ora, circa 109 record per seconda.
Un esempiu di duie linee da u logu:
Quandu indexatu da ELK, questu hà datu una dimensione d'indice di 30,3 MB:
In u casu di Loki, questu hà datu circa 128 KB d'indici è circa 3,8 MB di dati in pezzi. Hè da nutà chì u logu hè statu artificialmente generatu è ùn hà micca una larga varietà di dati. Un gzip simplice nantu à u logu originale di Docker JSON cù dati hà datu una cumpressione di 95,4%, è datu chì solu u logu nginx pulitu hè statu mandatu à Loki stessu, a cumpressione à 4 MB hè capisci. U numeru tutale di valori unichi per l'etichette Loki era 35, chì spiega a piccula dimensione di l'indici. Per ELK, u logu hè statu ancu sbulicatu. Cusì, Loki cumpressa i dati originali da 96%, è ELK da 70%.
Cunsumu di memoria
Se paragunemu tutta a pila di Prometheus è ELK, allora Loki "manghja" parechje volte menu. Hè chjaru chì u serviziu Go cunsuma menu di u serviziu Java, è paragunendu a dimensione di a JVM Heap Elasticsearch è a memoria attribuita per Loki hè sbagliata, ma vale a pena nutà chì Loki usa assai menu memoria. U so vantaghju CPU ùn hè micca cusì evidente, ma hè ancu presente.
Speed
Loki "divora" logs più veloce. A vitezza dipende assai fatturi - chì tipu di logs, quantu sufisticatu noi parse, rete, discu, etc. - ma hè definitu più altu ch'è quellu di ELK (in u mo test - circa duie volte). Questu hè spiegatu da u fattu chì Loki mette assai menu dati in l'indici è, per quessa, passa menu tempu in l'indexazione. In questu casu, a situazione hè invertita cù a veloce di ricerca: Loki rallenta notevolmente nantu à e dati più grande di uni pochi gigabyte, mentri per ELK, a velocità di ricerca ùn dipende micca da a dimensione di dati.
Ricerca di log
Loki hè significativamente inferior à ELK in quantu à e capacità di ricerca di log. Grep cù espressioni regulari hè una cosa forte, ma hè inferjuri à una basa di dati per adulti. A mancanza di dumande di gamma, l'agregazione solu per etichette, l'incapacità di circà senza etichette - tuttu questu ci limita in a ricerca di l'infurmazioni d'interessu in Loki. Questu ùn implica micca chì nunda ùn pò esse truvatu cù Loki, ma definisce u flussu di travaglià cù logs, quandu truvate prima un prublema nantu à i charts Prometheus, è dopu cercate ciò chì hè accadutu in i logs usendu sti etichette.
interfaccia
Prima di tuttu, hè bella (scusate, ùn pudia resiste). Grafana hà una bella interfaccia, ma Kibana hè assai più funziunale.
Loki pro è contro
Di i pluses, pò esse nutatu chì Loki si integra cù Prometheus, rispettivamente, uttene metrica è alerting fora di a scatula. Hè cunvene per cullà logs è almacenà cù Kubernetes Pods, postu chì hà una scuperta di serviziu ereditata da Prometheus è attache automaticamente etichette.
Di i minus - documentazione povira. Certi cose, cum'è e funziunalità è e capacità di Promtail, aghju scupertu solu in u prucessu di studià u codice, u benefiziu di open-source. Un altru svantaghju hè a debule capacità di analisi. Per esempiu, Loki ùn pò micca analizà i logs multiline. Inoltre, i svantaghji includenu u fattu chì Loki hè una tecnulugia relativamente ghjovana (la versione 1.0 era in nuvembre 2019).
cunchiusioni
Loki hè una tecnulugia 100% interessante chì hè adattata per i prughjetti chjuchi è mediani, chì vi permette di risolve parechji prublemi di aggregazione di log, ricerca di log, monitoraghju è analisi di log.
Ùn adupremu micca Loki à Badoo, perchè avemu una pila ELK chì ci cunvene è chì hè stata invasata da diverse soluzioni persunalizate annantu à l'anni. Per noi, u stumbling block hè a ricerca in i logs. Cù quasi 100 GB di logs per ghjornu, hè impurtante per noi di pudè truvà tuttu è un pocu di più è fà rapidamente. Per charting è monitoraghju, usemu altre soluzioni chì sò adattate à i nostri bisogni è integrate l'una cù l'altri. A pila di Loki hà benefici tangibili, ma ùn ci darà micca più di ciò chì avemu, è i so benefici ùn superanu esattamente u costu di a migrazione.
E ancu s'è dopu à a ricerca hè diventatu chjaru chì ùn pudemu micca aduprà Loki, speremu chì questu post vi aiuterà à sceglie.
U repositariu cù u codice utilizatu in l'articulu hè situatu ccà.