Pagkolekta ng mga log mula kay Loki

Pagkolekta ng mga log mula kay Loki

Kami sa Badoo ay patuloy na sinusubaybayan ang mga bagong teknolohiya at sinusuri kung gagamitin o hindi ang mga ito sa aming system. Nais naming ibahagi ang isa sa mga pag-aaral na ito sa komunidad. Ito ay nakatuon sa Loki, isang log aggregation system.

Ang Loki ay isang solusyon para sa pag-iimbak at pagtingin sa mga log, at ang stack na ito ay nagbibigay din ng isang nababaluktot na sistema para sa pagsusuri ng mga ito at pagpapadala ng data sa Prometheus. Noong Mayo, isa pang update ang inilabas, na aktibong pino-promote ng mga creator. Interesado kami sa kung ano ang magagawa ni Loki, kung anong mga feature ang ibinibigay nito, at hanggang saan ito maaaring kumilos bilang alternatibo sa ELK, ang stack na ginagamit namin ngayon.

Ano ba Loki

Ang Grafana Loki ay isang set ng mga bahagi para sa isang kumpletong sistema ng pag-log. Hindi tulad ng iba pang katulad na mga sistema, ang Loki ay batay sa ideya ng pag-index lamang ng metadata ng log - mga label (tulad ng sa Prometheus), at pag-compress ng mga log nang magkatabi sa magkahiwalay na mga tipak.

Home page, GitHub

Bago tayo pumasok sa kung ano ang maaari mong gawin kay Loki, gusto kong linawin kung ano ang ibig sabihin ng "ideya ng pag-index lamang ng metadata." Ihambing natin ang diskarte sa Loki at ang diskarte sa pag-index sa mga tradisyonal na solusyon tulad ng Elasticsearch, gamit ang halimbawa ng isang linya mula sa nginx log:

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"

Pina-parse ng mga tradisyunal na system ang buong row, kabilang ang mga field na may maraming natatanging user_id at item_id value, at iniimbak ang lahat sa malalaking index. Ang bentahe ng diskarteng ito ay maaari kang magpatakbo ng mga kumplikadong query nang mabilis, dahil halos lahat ng data ay nasa index. Ngunit kailangan mong magbayad para dito dahil ang index ay nagiging malaki, na isinasalin sa mga kinakailangan sa memorya. Bilang resulta, ang full-text index ng mga log ay maihahambing sa laki sa mga log mismo. Upang mabilis na maghanap sa pamamagitan nito, ang index ay dapat na mai-load sa memorya. At kung mas maraming log, mas mabilis ang pagtaas ng index at mas maraming memory ang natupok nito.

Ang diskarte sa Loki ay nangangailangan na ang kinakailangang data lamang ang makuha mula sa string, ang bilang ng mga halaga ay maliit. Sa ganitong paraan nakakakuha kami ng maliit na index at makakapaghanap kami ng data sa pamamagitan ng pag-filter nito ayon sa oras at mga na-index na field, at pagkatapos ay ini-scan ang iba gamit ang mga regular na expression o substring na paghahanap. Mukhang hindi pinakamabilis ang proseso, ngunit hinati ni Loki ang kahilingan sa ilang bahagi at ipinapatupad ang mga ito nang magkatulad, na nagpoproseso ng malaking halaga ng data sa maikling panahon. Ang bilang ng mga shards at parallel na kahilingan sa mga ito ay maaaring i-configure; kaya, ang dami ng data na maaaring iproseso sa bawat yunit ng oras ay nakadepende nang linear sa dami ng mga mapagkukunang ibinigay.

Ang trade-off na ito sa pagitan ng isang malaking fast index at isang maliit na parallel brute-force index ay nagpapahintulot kay Loki na kontrolin ang gastos ng system. Maaari itong madaling i-configure at palawakin ayon sa iyong mga pangangailangan.

Ang Loki stack ay binubuo ng tatlong bahagi: Promtail, Loki, Grafana. Kinokolekta ng Promtail ang mga log, pinoproseso ang mga ito at ipinapadala ang mga ito sa Loki. Iniingatan sila ni Loki. At maaaring humiling ang Grafana ng data mula kay Loki at ipakita ito. Sa pangkalahatan, maaaring gamitin ang Loki hindi lamang para sa pag-iimbak ng mga log at paghahanap sa kanila. Ang buong stack ay nagbibigay ng magagandang pagkakataon para sa pagproseso at pagsusuri ng papasok na data gamit ang Prometheus na paraan.
Ang isang paglalarawan ng proseso ng pag-install ay matatagpuan dito.

Paghahanap ng Log

Maaari kang maghanap sa mga log sa isang espesyal na interface Grafana β€” Explorer. Ginagamit ng mga query ang wikang LogQL, na halos kapareho sa PromQL na ginamit ng Prometheus. Sa prinsipyo, maaari itong isipin bilang isang distributed grep.

Mukhang ganito ang interface ng paghahanap:

Pagkolekta ng mga log mula kay Loki

Ang query mismo ay binubuo ng dalawang bahagi: selector at filter. Ang Selector ay isang paghahanap gamit ang naka-index na metadata (mga label) na itinalaga sa mga log, at ang filter ay isang string ng paghahanap o regexp na nagpi-filter ng mga talaan na tinukoy ng selector. Sa ibinigay na halimbawa: Sa mga kulot na bracket - ang tagapili, lahat pagkatapos - ang filter.

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

Dahil sa paraan ng paggana ni Loki, hindi ka makakagawa ng mga kahilingan nang walang tagapili, ngunit ang mga label ay maaaring gawing generic na arbitraryo.

Ang selector ay ang key-value ng value sa curly braces. Maaari mong pagsamahin ang mga tagapili at tukuyin ang iba't ibang kundisyon sa paghahanap gamit ang mga operator =, != o mga regular na expression:

{instance=~"kafka-[23]",name!="kafka-dev"} 
// Найдёт Π»ΠΎΠ³ΠΈ с Π»Π΅ΠΉΠ±Π»ΠΎΠΌ instance, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ kafka-2, kafka-3, ΠΈ ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚ dev 

Ang filter ay isang text o regexp na magpi-filter sa lahat ng data na natanggap ng selector.

Posibleng makakuha ng mga ad-hoc graph batay sa natanggap na data sa metrics mode. Halimbawa, maaari mong malaman kung gaano kadalas lumilitaw ang isang entry na naglalaman ng string index sa mga log ng nginx:

Pagkolekta ng mga log mula kay Loki

Ang isang buong paglalarawan ng mga tampok ay matatagpuan sa dokumentasyon LogQL.

Pag-parse ng log

Mayroong ilang mga paraan upang mangolekta ng mga log:

  • Sa tulong ng Promtail, isang karaniwang bahagi ng stack para sa pagkolekta ng mga log.
  • Direkta mula sa lalagyan ng docker gamit ang Driver ng Loki Docker Logging.
  • Gumamit ng Fluentd o Fluent Bit na maaaring magpadala ng data sa Loki. Hindi tulad ng Promtail, mayroon silang mga nakahandang parser para sa halos anumang uri ng log at kaya rin nilang hawakan ang mga multiline na log.

Karaniwan ang Promtail ay ginagamit para sa pag-parse. Ginagawa nito ang tatlong bagay:

  • Naghahanap ng mga pinagmumulan ng data.
  • Naglalagay ng mga label sa kanila.
  • Nagpapadala ng data kay Loki.

Sa kasalukuyan ang Promtail ay maaaring magbasa ng mga log mula sa mga lokal na file at mula sa systemd journal. Dapat itong mai-install sa bawat makina kung saan kinokolekta ang mga log.

Mayroong pagsasama sa Kubernetes: Awtomatikong inaalam ng Promtail ang estado ng cluster sa pamamagitan ng Kubernetes REST API at nangongolekta ng mga log mula sa isang node, serbisyo o pod, kaagad na nagpo-post ng mga label batay sa metadata mula sa Kubernetes (pangalan ng pod, pangalan ng file, atbp.).

Maaari ka ring mag-hang ng mga label batay sa data mula sa log gamit ang Pipeline. Ang Pipeline Promtail ay maaaring binubuo ng apat na uri ng mga yugto. Higit pang mga detalye sa opisyal na dokumentasyon, Mapapansin ko kaagad ang ilan sa mga nuances.

  1. Mga yugto ng pag-parse. Ito ang yugto ng RegEx at JSON. Sa yugtong ito, kinukuha namin ang data mula sa mga log papunta sa tinatawag na kinuhang mapa. Maaari kaming mag-extract mula sa JSON sa pamamagitan lamang ng pagkopya ng mga field na kailangan namin sa kinuhang mapa, o sa pamamagitan ng mga regular na expression (RegEx), kung saan ang mga pinangalanang grupo ay "nakamapang" sa kinuhang mapa. Ang Extracted map ay isang key-value store, kung saan ang key ay ang pangalan ng field, at ang value ay ang value nito mula sa mga log.
  2. Ibahin ang anyo ng mga yugto. Ang yugtong ito ay may dalawang opsyon: transform, kung saan itinakda namin ang mga panuntunan sa pagbabago, at source - ang data source para sa pagbabago mula sa nakuhang mapa. Kung walang ganoong field sa na-extract na mapa, malilikha ito. Kaya, posibleng gumawa ng mga label na hindi batay sa nakuhang mapa. Sa yugtong ito, maaari nating manipulahin ang data sa nakuhang mapa gamit ang isang medyo malakas template ng golang. Bilang karagdagan, dapat nating tandaan na ang na-extract na mapa ay ganap na na-load sa panahon ng pag-parse, na ginagawang posible, halimbawa, upang suriin ang halaga dito: "{{if .tag}tag value ay umiiral{end}}". Sinusuportahan ng template ang mga kundisyon, loop, at ilang function ng string gaya ng Palitan at Trim.
  3. Mga yugto ng pagkilos. Sa yugtong ito, maaari kang gumawa ng isang bagay sa na-extract:
    • Gumawa ng label mula sa nakuhang data, na mai-index ni Loki.
    • Baguhin o itakda ang oras ng kaganapan mula sa log.
    • Baguhin ang data (log text) na mapupunta sa Loki.
    • Lumikha ng mga sukatan.
  4. Mga yugto ng pag-filter. Ang yugto ng pagtutugma, kung saan maaari kaming magpadala ng mga tala na hindi namin kailangang /dev/null, o ipadala ang mga ito para sa karagdagang pagproseso.

Gamit ang halimbawa ng pagproseso ng mga ordinaryong nginx log, ipapakita ko kung paano mo mai-parse ang mga log gamit ang Promtail.

Para sa pagsubok, kumuha tayo ng binagong nginx image jwilder/nginx-proxy:alpine bilang nginx-proxy at isang maliit na daemon na maaaring mag-query sa sarili nito sa pamamagitan ng HTTP. Ang daemon ay may ilang mga endpoint, kung saan maaari itong magbigay ng mga tugon ng iba't ibang laki, na may iba't ibang mga status ng HTTP at may iba't ibang mga pagkaantala.

Mangongolekta kami ng mga log mula sa mga docker container, na makikita sa path /var/lib/docker/containers/ / -json.log

Sa docker-compose.yml na-set up namin ang Promtail at tinukoy ang path sa config:

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'
 // ...

Idagdag ang path sa mga log sa promtail.yml (may opsyong "docker" sa config na ganoon din ang ginagawa sa isang linya, ngunit hindi ito masyadong halata):

scrape_configs:
 - job_name: containers

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

Kapag pinagana ang configuration na ito, makakatanggap si Loki ng mga log mula sa lahat ng container. Upang maiwasan ito, binabago namin ang mga setting ng pagsubok nginx sa docker-compose.yml - magdagdag ng pag-log sa field ng tag:

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

I-edit ang promtail.yml at i-set up ang Pipeline. Ang mga log ay ang mga sumusunod:

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

mga yugto ng pipeline:

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

Kinukuha namin ang stream, attrs, attrs.tag na mga field (kung mayroon man) mula sa papasok na JSON at inilalagay namin ang mga ito sa kinuhang mapa.

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

Kung posible na ilagay ang field ng tag sa na-extract na mapa, gamit ang regexp, i-extract namin ang mga pangalan ng larawan at container.

 - labels:
     image_name:
     container_name:

Nagtatalaga kami ng mga label. Kung ang mga key na image_name at container_name ay matatagpuan sa nakuhang data, ang kanilang mga halaga ay itatalaga sa naaangkop na mga label.

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

Itinatapon namin ang lahat ng log na walang mga label na image_name at container_name na nakatakda.

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

Para sa lahat ng log na ang image_name ay katumbas ng nginx.promtail.test, kinukuha namin ang log field mula sa source log at inilalagay ito sa na-extract na mapa gamit ang row key.

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

Nililinis namin ang input string gamit ang mga regular na expression at hinugot ang nginx virtual host at ang nginx log line.

     - 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.]+)")?

I-parse ang nginx log gamit ang mga regular na expression.

    - 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>[^/?.]+).*$

I-parse ang request_url. Sa tulong ng regexp, tinutukoy namin ang layunin ng kahilingan: sa statics, sa mga larawan, sa API at itakda ang kaukulang key sa nakuhang mapa.

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

Gamit ang mga conditional operator sa Template, sinusuri namin ang mga naka-install na field sa na-extract na mapa at itinakda ang mga kinakailangang value para sa request_type na field: photo, static, API. Magtalaga ng iba kung nabigo. Ngayon ang request_type ay naglalaman ng uri ng kahilingan.

       - labels:
           api_request:
           virtual_host:
           request_type:
           status:

Itinakda namin ang mga label na api_request, virtual_host, request_type at status (HTTP status) batay sa kung ano ang nagawa naming ilagay sa na-extract na mapa.

       - output:
           source: nginx_log_row

Baguhin ang output. Ngayon ang nalinis na nginx log mula sa na-extract na mapa ay napupunta sa Loki.

Pagkolekta ng mga log mula kay Loki

Pagkatapos patakbuhin ang config sa itaas, makikita mo na ang bawat entry ay may label batay sa data mula sa log.

Ang isang bagay na dapat tandaan ay ang pagkuha ng mga label na may malaking bilang ng mga halaga (cardinality) ay maaaring makabuluhang pabagalin ang Loki. Iyon ay, hindi mo dapat ilagay sa index, halimbawa, user_id. Magbasa nang higit pa tungkol dito sa artikuloPaano ang mga label sa Loki ay maaaring gawing mas mabilis at mas madali ang mga query sa log". Ngunit hindi ito nangangahulugan na hindi ka makakapaghanap sa pamamagitan ng user_id nang walang mga index. Kinakailangang gumamit ng mga filter kapag naghahanap ("grab" ayon sa data), at ang index dito ay gumaganap bilang isang stream identifier.

Visualization ng log

Pagkolekta ng mga log mula kay Loki

Loki ay maaaring kumilos bilang isang data source para sa Grafana chart gamit ang LogQL. Ang mga sumusunod na tampok ay suportado:

  • rate - bilang ng mga tala sa bawat segundo;
  • bilang sa paglipas ng panahon - ang bilang ng mga tala sa ibinigay na hanay.

Mayroon ding mga pinagsama-samang function Sum, Avg at iba pa. Maaari kang bumuo ng medyo kumplikadong mga graph, halimbawa, isang graph ng bilang ng mga error sa HTTP:

Pagkolekta ng mga log mula kay Loki

Ang default na data source ng Loki ay medyo hindi gaanong gumagana kaysa sa Prometheus data source (halimbawa, hindi mo mababago ang legend), ngunit maaaring ikonekta si Loki bilang Prometheus type source. Hindi ako sigurado kung ito ay dokumentado na pag-uugali, ngunit sa paghusga sa pamamagitan ng tugon mula sa mga developer "Paano i-configure ang Loki bilang Prometheus datasource? Β· Isyu #1222 Β· grafana/loki”, halimbawa, ito ay ganap na legal at ang Loki ay ganap na katugma sa PromQL.

Idagdag si Loki bilang data source na may uri ng Prometheus at idagdag ang URL /loki:

Pagkolekta ng mga log mula kay Loki

At maaari kaming gumawa ng mga graph, na parang nagtatrabaho kami sa mga sukatan mula sa Prometheus:

Pagkolekta ng mga log mula kay Loki

Sa tingin ko, pansamantala lang ang pagkakaiba sa functionality at aayusin ito ng mga developer sa hinaharap.

Pagkolekta ng mga log mula kay Loki

Mga sukatan

Nagbibigay ang Loki ng kakayahang mag-extract ng mga numerical metrics mula sa mga log at ipadala ang mga ito sa Prometheus. Halimbawa, ang log ng nginx ay naglalaman ng bilang ng mga byte bawat tugon, at gayundin, na may isang tiyak na pagbabago ng karaniwang format ng log, ang oras sa mga segundo na kinailangan upang tumugon. Ang data na ito ay maaaring makuha at ipadala sa Prometheus.

Magdagdag ng isa pang seksyon sa 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

Binibigyang-daan ka ng opsyong tukuyin at i-update ang mga sukatan batay sa data mula sa na-extract na mapa. Ang mga sukatang ito ay hindi ipinadala sa Loki - lumalabas ang mga ito sa Promtail /metrics endpoint. Dapat na i-configure ang Prometheus upang makatanggap ng data mula sa yugtong ito. Sa halimbawa sa itaas, para sa request_type="api" nangongolekta kami ng sukatan ng histogram. Sa ganitong uri ng mga sukatan, madaling makakuha ng mga percentile. Para sa mga static at larawan, kinokolekta namin ang kabuuan ng mga byte at ang bilang ng mga row kung saan nakatanggap kami ng mga byte upang kalkulahin ang average.

Magbasa pa tungkol sa mga sukatan dito.

Buksan ang port sa Promtail:

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

Tinitiyak namin na ang mga sukatan na may prefix na promtail_custom ay lumitaw:

Pagkolekta ng mga log mula kay Loki

Pag-set up ng Prometheus. Magdagdag ng job promtail:

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

At gumuhit kami ng isang graph:

Pagkolekta ng mga log mula kay Loki

Sa ganitong paraan malalaman mo, halimbawa, ang apat na pinakamabagal na query. Maaari mo ring i-configure ang pagsubaybay para sa mga sukatang ito.

Pagsusukat

Ang Loki ay maaaring nasa parehong single binary mode at sharded (horizontally-scalable mode). Sa pangalawang kaso, maaari itong mag-save ng data sa cloud, at ang mga chunks at index ay naka-imbak nang hiwalay. Sa bersyon 1.5, ang kakayahang mag-imbak sa isang lugar ay ipinatupad, ngunit hindi pa inirerekomenda na gamitin ito sa produksyon.

Pagkolekta ng mga log mula kay Loki

Maaaring iimbak ang mga chunk sa storage na katugma sa S3, para sa pag-iimbak ng mga index, gumamit ng mga database na nasusukat nang pahalang: Cassandra, BigTable o DynamoDB. Iba pang bahagi ng Loki - Mga Distributor (para sa pagsusulat) at Querier (para sa mga query) - ay stateless at pahalang din ang sukat.

Sa kumperensya ng DevOpsDays Vancouver 2019, inihayag ng isa sa mga kalahok na si Callum Styan na kasama ni Loki ang kanyang proyekto ay may mga petabytes ng mga log na may index na mas mababa sa 1% ng kabuuang sukat: β€œPaano Iniuugnay ni Loki ang Mga Sukatan at Log β€” At Natitipid Ka".

Paghahambing ng Loki at ELK

Laki ng index

Upang subukan ang nagresultang laki ng index, kumuha ako ng mga log mula sa lalagyan ng nginx kung saan na-configure ang Pipeline sa itaas. Ang log file ay naglalaman ng 406 na linya na may kabuuang volume na 624 MB. Nabuo ang mga log sa loob ng isang oras, humigit-kumulang 109 record kada segundo.

Isang halimbawa ng dalawang linya mula sa log:

Pagkolekta ng mga log mula kay Loki

Kapag na-index ng ELK, nagbigay ito ng laki ng index na 30,3 MB:

Pagkolekta ng mga log mula kay Loki

Sa kaso ni Loki, nagbigay ito ng humigit-kumulang 128 KB ng index at humigit-kumulang 3,8 MB ng data sa mga chunks. Ito ay nagkakahalaga ng pagpuna na ang log ay artipisyal na nabuo at hindi nagtatampok ng malawak na pagkakaiba-iba ng data. Ang isang simpleng gzip sa orihinal na log ng Docker JSON na may data ay nagbigay ng compression na 95,4%, at dahil ang nalinis na nginx log lamang ang ipinadala sa Loki mismo, ang compression sa 4 MB ay naiintindihan. Ang kabuuang bilang ng mga natatanging halaga para sa mga label ng Loki ay 35, na nagpapaliwanag sa maliit na sukat ng index. Para sa ELK, na-clear din ang log. Kaya, na-compress ni Loki ang orihinal na data ng 96%, at ELK ng 70%.

Pagkonsumo ng memorya

Pagkolekta ng mga log mula kay Loki

Kung ihahambing natin ang buong stack ng Prometheus at ELK, kung gayon si Loki ay "kumakain" ng ilang beses na mas kaunti. Malinaw na ang serbisyo ng Go ay gumagamit ng mas kaunti kaysa sa serbisyo ng Java, at ang paghahambing ng laki ng Heap Elasticsearch JVM at ang inilalaan na memorya para sa Loki ay hindi tama, ngunit gayunpaman, ito ay nagkakahalaga na tandaan na ang Loki ay gumagamit ng mas kaunting memorya. Ang bentahe ng CPU nito ay hindi masyadong halata, ngunit naroroon din ito.

bilis

Mas mabilis na nag-log si Loki. Ang bilis ay nakasalalay sa maraming mga kadahilanan - kung anong uri ng mga log, kung gaano kahusay ang pag-parse natin sa kanila, network, disk, atbp. - ngunit tiyak na mas mataas ito kaysa sa ELK (sa aking pagsubok - mga dalawang beses). Ito ay ipinaliwanag sa pamamagitan ng katotohanan na ang Loki ay naglalagay ng mas kaunting data sa index at, nang naaayon, gumugugol ng mas kaunting oras sa pag-index. Sa kasong ito, nababaligtad ang sitwasyon sa bilis ng paghahanap: Kapansin-pansing bumabagal ang Loki sa data na mas malaki kaysa sa ilang gigabytes, habang para sa ELK, ang bilis ng paghahanap ay hindi nakadepende sa laki ng data.

Paghahanap ng Log

Ang Loki ay makabuluhang mas mababa sa ELK sa mga tuntunin ng mga kakayahan sa paghahanap ng log. Ang Grep na may mga regular na expression ay isang malakas na bagay, ngunit ito ay mas mababa sa isang pang-adultong database. Ang kakulangan ng mga query sa hanay, pagsasama-sama lamang ayon sa mga label, ang kawalan ng kakayahang maghanap nang walang mga label - nililimitahan kami ng lahat ng ito sa paghahanap ng impormasyong interesado sa Loki. Hindi ito nagpapahiwatig na walang mahahanap gamit ang Loki, ngunit tinutukoy nito ang daloy ng pagtatrabaho sa mga log, kapag una kang nakakita ng problema sa mga chart ng Prometheus, at pagkatapos ay hanapin kung ano ang nangyari sa mga log gamit ang mga label na ito.

interface

First off, maganda ito (sorry, couldn't resist). Ang Grafana ay may magandang interface, ngunit mas gumagana ang Kibana.

Loki kalamangan at kahinaan

Sa mga plus, mapapansin na ang Loki ay sumasama sa Prometheus, ayon sa pagkakabanggit, nakakakuha kami ng mga sukatan at nag-aalerto sa labas ng kahon. Ito ay maginhawa para sa pagkolekta ng mga log at pag-iimbak ng mga ito gamit ang Kubernetes Pods, dahil mayroon itong pagtuklas ng serbisyo na minana mula sa Prometheus at awtomatikong nakakabit ng mga label.

Ng mga minus - mahinang dokumentasyon. Ang ilang mga bagay, halimbawa, ang mga tampok at kakayahan ng Promtail, natuklasan ko lamang sa proseso ng pag-aaral ng code, sa kabutihang palad ito ay open-source. Ang isa pang kawalan ay ang mahinang mga kakayahan sa pag-parse. Halimbawa, hindi ma-parse ni Loki ang mga multiline na log. Ang isa pang kawalan ay ang Loki ay isang medyo batang teknolohiya (ang paglabas ng 1.0 ay noong Nobyembre 2019).

Konklusyon

Ang Loki ay isang 100% kawili-wiling teknolohiya na angkop para sa maliliit at katamtamang mga proyekto, na nagbibigay-daan sa iyong lutasin ang maraming problema ng pagsasama-sama ng log, paghahanap ng log, pagsubaybay at pagsusuri ng mga log.

Hindi namin ginagamit ang Loki sa Badoo, dahil mayroon kaming ELK stack na nababagay sa amin at napuno ng iba't ibang custom na solusyon sa paglipas ng mga taon. Para sa amin, ang hadlang ay ang paghahanap sa mga tala. Sa halos 100 GB ng mga log bawat araw, mahalaga para sa amin na mahanap ang lahat at kaunti pa at magawa ito nang mabilis. Para sa pag-chart at pagsubaybay, gumagamit kami ng iba pang mga solusyon na iniayon sa aming mga pangangailangan at isinama sa isa't isa. Ang Loki stack ay may nakikitang mga benepisyo, ngunit hindi ito magbibigay sa amin ng higit pa kaysa sa kung ano ang mayroon kami, at ang mga benepisyo nito ay hindi eksaktong hihigit sa halaga ng paglipat.

At kahit na pagkatapos ng pananaliksik ay naging malinaw na hindi namin magagamit ang Loki, inaasahan namin na ang post na ito ay makakatulong sa iyo sa pagpili.

Ang repositoryo na may code na ginamit sa artikulo ay matatagpuan dito.

Pinagmulan: www.habr.com

Magdagdag ng komento