<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          輕量級(jí)日志 Loki 全攻略

          共 1519字,需瀏覽 4分鐘

           ·

          2022-05-20 19:09


          文章來源:https://c1n.cn/0wHvF

          前言

          在對(duì)公司容器云的日志方案進(jìn)行設(shè)計(jì)的時(shí)候,發(fā)現(xiàn)主流的 ELK(Elasticsearch,Logstash,Kibana)或者 EFK(Elasticsearch,F(xiàn)ilebeat or Fluentd,Kibana)比較重,再加上現(xiàn)階段對(duì)于 ES 復(fù)雜的搜索功能很多都用不上,最終選擇了 Grafana 開源的 Loki 日志系統(tǒng)。

          下面我們來介紹下 Loki 的一些基本概念和架構(gòu),當(dāng)然 EFK 作為業(yè)界成熟的日志聚合解決方案也是大家應(yīng)該需要熟悉和掌握的。

          簡介

          Loki 是 Grafana Labs 團(tuán)隊(duì)最新的開源項(xiàng)目,是一個(gè)水平可擴(kuò)展,高可用性,多租戶的日志聚合系統(tǒng)。

          它的設(shè)計(jì)非常經(jīng)濟(jì)高效且易于操作,因?yàn)樗粫?huì)為日志內(nèi)容編制索引,而是為每個(gè)日志流編制一組標(biāo)簽,專門為 Prometheus 和 Kubernetes 用戶做了相關(guān)優(yōu)化。

          該項(xiàng)目受 Prometheus 啟發(fā),官方的介紹就是:Like Prometheus,But For Logs。類似于 Prometheus 的日志系統(tǒng)。

          項(xiàng)目地址:

          https://github.com/grafana/loki/

          與其他日志聚合系統(tǒng)相比,Loki 具有下面的一些特性:

          • 不對(duì)日志進(jìn)行全文索引。通過存儲(chǔ)壓縮非結(jié)構(gòu)化日志和僅索引元數(shù)據(jù),Loki 操作起來會(huì)更簡單,更省成本。
          • 通過使用與 Prometheus 相同的標(biāo)簽記錄流對(duì)日志進(jìn)行索引和分組,這使得日志的擴(kuò)展和操作效率更高,能對(duì)接 alertmanager。
          • 特別適合儲(chǔ)存 Kubernetes Pod 日志;諸如 Pod 標(biāo)簽之類的元數(shù)據(jù)會(huì)被自動(dòng)刪除和編入索引。
          • 受 Grafana 原生支持,避免 kibana 和 grafana 來回切換。

          架構(gòu)說明

          圖片

          組件說明

          說明如下:

          • Promtail 作為采集器,類比 filebeat
          • Loki 相當(dāng)于服務(wù)端,類比 es

          Loki 進(jìn)程包含四種角色:

          • querier 查詢器
          • inester 日志存儲(chǔ)器
          • query-frontend 前置查詢器
          • distributor 寫入分發(fā)器

          可以通過 Loki 二進(jìn)制的 -target 參數(shù)指定運(yùn)行角色。

          read path

          如下:

          • 查詢器接受 HTTP/1 數(shù)據(jù)請(qǐng)求
          • 查詢器將查詢傳遞給所有 ingesters 請(qǐng)求內(nèi)存中的數(shù)據(jù)
          • 接收器接受讀取的請(qǐng)求,并返回與查詢匹配的數(shù)據(jù)(如果有)
          • 如果沒有接受者返回?cái)?shù)據(jù),則查詢器會(huì)從后備存儲(chǔ)中延遲加載數(shù)據(jù)并對(duì)其執(zhí)行查詢
          • 查詢器將迭代所有接收到的數(shù)據(jù)并進(jìn)行重復(fù)數(shù)據(jù)刪除,從而通過 HTTP/1 連接返回最終數(shù)據(jù)集

          write path

          圖片

          如上圖:

          • 分發(fā)服務(wù)器收到一個(gè) HTTP/1 請(qǐng)求,以存儲(chǔ)流數(shù)據(jù)
          • 每個(gè)流都使用散列環(huán)散列
          • 分發(fā)程序?qū)⒚總€(gè)流發(fā)送到適當(dāng)?shù)?inester 和其副本(基于配置的復(fù)制因子)
          • 每個(gè)實(shí)例將為流的數(shù)據(jù)創(chuàng)建一個(gè)塊或?qū)⑵渥芳拥浆F(xiàn)有塊中,, 每個(gè)租戶和每個(gè)標(biāo)簽集的塊都是唯一的
          • 分發(fā)服務(wù)器通過 HTTP/1 鏈接以成功代碼作為響應(yīng)

          部署

          本地化模式安裝

          下載 Promtail 和 Loki:

          wget??https://github.com/grafana/loki/releases/download/v2.2.1/loki-linux-amd64.zip
          wget?https://github.com/grafana/loki/releases/download/v2.2.1/promtail-linux-amd64.zip
          安裝 Promtail:
          $?mkdir?/opt/app/{promtail,loki}?-pv

          #?promtail配置文件
          $?cat?<?/opt/app/promtail/promtail.yaml
          server:
          ??http_listen_port:?9080
          ??grpc_listen_port:?0

          positions:
          ??filename:?/var/log/positions.yaml?#?This?location?needs?to?be?writeable?by?promtail.

          client:
          ??url:?http://localhost:3100/loki/api/v1/push

          scrape_configs:
          ?-?job_name:?system
          ???pipeline_stages:
          ???static_configs:
          ???-?targets:
          ??????-?localhost
          ?????labels:
          ??????job:?varlogs
          ??????host:?yourhost
          ??????__path__:?/var/log/*.log
          EOF

          #?解壓安裝包
          unzip?promtail-linux-amd64.zip
          mv?promtail-linux-amd64?/opt/app/promtail/promtail

          #?service文件
          $?cat?</etc/systemd/system/promtail.service
          [Unit]
          Description=promtail?server
          Wants=network-online.target
          After=network-online.target

          [Service]
          ExecStart=/opt/app/promtail/promtail?-config.file=/opt/app/promtail/promtail.yaml
          StandardOutput=syslog
          StandardError=syslog
          SyslogIdentifier=promtail
          [Install]
          WantedBy=default.target
          EOF

          systemctl?daemon-reload
          systemctl?restart?promtail
          systemctl?status?promtail

          安裝 Loki:

          $?mkdir?/opt/app/{promtail,loki}?-pv

          #?promtail配置文件
          $?cat?<?/opt/app/loki/loki.yaml
          auth_enabled:?false

          server:
          ??http_listen_port:?3100
          ??grpc_listen_port:?9096

          ingester:
          ??wal:
          ????enabled:?true
          ????dir:?/opt/app/loki/wal
          ??lifecycler:
          ????address:?127.0.0.1
          ????ring:
          ??????kvstore:
          ????????store:?inmemory
          ??????replication_factor:?1
          ????final_sleep:?0s
          ??chunk_idle_period:?1h???????#?Any?chunk?not?receiving?new?logs?in?this?time?will?be?flushed
          ??max_chunk_age:?1h???????????#?All?chunks?will?be?flushed?when?they?hit?this?age,?default?is?1h
          ??chunk_target_size:?1048576??#?Loki?will?attempt?to?build?chunks?up?to?1.5MB,?flushing?first?if?chunk_idle_period?or?max_chunk_age?is?reached?first
          ??chunk_retain_period:?30s????#?Must?be?greater?than?index?read?cache?TTL?if?using?an?index?cache?(Default?index?read?cache?TTL?is?5m)
          ??max_transfer_retries:?0?????#?Chunk?transfers?disabled

          schema_config:
          ??configs:
          ????-?from:?2020-10-24
          ??????store:?boltdb-shipper
          ??????object_store:?filesystem
          ??????schema:?v11
          ??????index:
          ????????prefix:?index_
          ????????period:?24h

          storage_config:
          ??boltdb_shipper:
          ????active_index_directory:?/opt/app/loki/boltdb-shipper-active
          ????cache_location:?/opt/app/loki/boltdb-shipper-cache
          ????cache_ttl:?24h?????????#?Can?be?increased?for?faster?performance?over?longer?query?periods,?uses?more?disk?space
          ????shared_store:?filesystem
          ??filesystem:
          ????directory:?/opt/app/loki/chunks

          compactor:
          ??working_directory:?/opt/app/loki/boltdb-shipper-compactor
          ??shared_store:?filesystem

          limits_config:
          ??reject_old_samples:?true
          ??reject_old_samples_max_age:?168h

          chunk_store_config:
          ??max_look_back_period:?0s

          table_manager:
          ??retention_deletes_enabled:?false
          ??retention_period:?0s


          ruler:
          ??storage:
          ????type:?local
          ????local:
          ??????directory:?/opt/app/loki/rules
          ??rule_path:?/opt/app/loki/rules-temp
          ??alertmanager_url:?http://localhost:9093
          ??ring:
          ????kvstore:
          ??????store:?inmemory
          ??enable_api:?true
          EOF

          #?解壓包
          unzip?loki-linux-amd64.zip?
          mv?loki-linux-amd64?/opt/app/loki/loki

          #?service文件

          $?cat?</etc/systemd/system/loki.service
          [Unit]
          Description=loki?server
          Wants=network-online.target
          After=network-online.target

          [Service]
          ExecStart=/opt/app/loki/loki?-config.file=/opt/app/loki/loki.yaml
          StandardOutput=syslog
          StandardError=syslog
          SyslogIdentifier=loki
          [Install]
          WantedBy=default.target
          EOF

          systemctl?daemon-reload
          systemctl?restart?loki
          systemctl?status?loki

          使用

          grafana 上配置 loki 數(shù)據(jù)源

          如下圖:

          圖片

          grafana-loki-dashsource

          在數(shù)據(jù)源列表中選擇 Loki,配置 Loki 源地址:

          圖片

          grafana-loki-dashsource-config

          源地址配置 http://loki:3100 即可,保存。

          保存完成后,切換到 grafana 左側(cè)區(qū)域的 Explore,即可進(jìn)入到 Loki 的頁面:

          圖片

          grafana-loki

          然后我們點(diǎn)擊 Log labels 就可以把當(dāng)前系統(tǒng)采集的日志標(biāo)簽給顯示出來,可以根據(jù)這些標(biāo)簽進(jìn)行日志的過濾查詢:

          圖片

          grafana-loki-log-labels

          比如我們這里選擇 /var/log/messages,就會(huì)把該文件下面的日志過濾展示出來,不過由于時(shí)區(qū)的問題,可能還需要設(shè)置下時(shí)間才可以看到數(shù)據(jù):

          圖片

          grafana-loki-logs

          這里展示的是 promtail 容器里面 / var/log 目錄中的日志。

          promtail 容器 /etc/promtail/config.yml:

          server:
          ??http_listen_port:?9080
          ??grpc_listen_port:?0

          positions:
          ??filename:?/tmp/positions.yaml

          clients:
          ??-?url:?http://loki:3100/loki/api/v1/push

          scrape_configs:
          -?job_name:?system
          ??static_configs:
          ??-?targets:
          ??????-?localhost
          ????labels:
          ??????job:?varlogs
          ??????__path__:?/var/log/*log

          這里的 job 就是 varlog,文件路徑就是 /var/log/*log。

          在 grafana explore 上配置查看日志

          查看日志?rate({job="message"}?|="kubelet"

          算 qps rate({job=”message”} |=”kubelet” [1m])

          只索引標(biāo)簽

          之前多次提到 loki 和 es 最大的不同是 loki 只對(duì)標(biāo)簽進(jìn)行索引而不對(duì)內(nèi)容索引。下面我們舉例來看下。

          靜態(tài)標(biāo)簽匹配模式

          以簡單的 promtail 配置舉例:

          scrape_configs:
          ?-?job_name:?system
          ???pipeline_stages:
          ???static_configs:
          ???-?targets:
          ??????-?localhost
          ?????labels:
          ??????job:?message
          ??????__path__:?/var/log/messages

          配置解讀:

          • 上面這段配置代表啟動(dòng)一個(gè)日志采集任務(wù)
          • 這個(gè)任務(wù)有 1 個(gè)固定標(biāo)簽 job=”syslog”
          • 采集日志路徑為 /var/log/messages,會(huì)以一個(gè)名為 filename 的固定標(biāo)簽
          • 在 promtail 的 web 頁面上可以看到類似 prometheus 的 target 信息頁面

          可以和使用 Prometheus 一樣的標(biāo)簽匹配語句進(jìn)行查詢。

          {job="syslog"}:

          scrape_configs:
          ?-?job_name:?system
          ???pipeline_stages:
          ???static_configs:
          ???-?targets:
          ??????-?localhost
          ?????labels:
          ??????job:?syslog
          ??????__path__:?/var/log/syslog
          ?-?job_name:?system
          ???pipeline_stages:
          ???static_configs:
          ???-?targets:
          ??????-?localhost
          ?????labels:
          ??????job:?apache
          ??????__path__:?/var/log/apache.log

          如果我們配置了兩個(gè) job,則可以使用job=~”apachesyslog”進(jìn)行多 job 匹配;同時(shí)也支持正則和正則非匹配。

          標(biāo)簽匹配模式的特點(diǎn)

          原理如下:
          • 和 prometheus 一致,相同標(biāo)簽對(duì)應(yīng)的是一個(gè)流 prometheus 處理 series 的模式
          • prometheus 中標(biāo)簽一致對(duì)應(yīng)的同一個(gè) hash 值和 refid(正整數(shù)遞增的 id),也就是同一個(gè) series
          • 時(shí)序數(shù)據(jù)不斷的 append 追加到這個(gè) memseries 中
          • 當(dāng)有任意標(biāo)簽發(fā)生變化時(shí)會(huì)產(chǎn)生新的 hash 值和 refid,對(duì)應(yīng)新的 series

          loki 處理日志的模式和 prometheus 一致,loki 一組標(biāo)簽值會(huì)生成一個(gè) stream。日志隨著時(shí)間的遞增會(huì)追加到這個(gè) stream 中,最后壓縮為 chunk。當(dāng)有任意標(biāo)簽發(fā)生變化時(shí)會(huì)產(chǎn)生新的 hash 值,對(duì)應(yīng)新的 stream。

          查詢過程
          • 所以 loki 先根據(jù)標(biāo)簽算出 hash 值在倒排索引中找到對(duì)應(yīng)的 chunk?
          • 然后再根據(jù)查詢語句中的關(guān)鍵詞等進(jìn)行過濾,這樣能大大的提速
          • 因?yàn)檫@種根據(jù)標(biāo)簽算哈希在倒排中查找 id,對(duì)應(yīng)找到存儲(chǔ)的塊在 prometheus 中已經(jīng)被驗(yàn)證過了
          • 屬于開銷低
          • 速度快

          動(dòng)態(tài)標(biāo)簽和高基數(shù)

          所以有了上述知識(shí),那么就得談?wù)剟?dòng)態(tài)標(biāo)簽的問題了。

          兩個(gè)概念:

          • 何為動(dòng)態(tài)標(biāo)簽:說白了就是標(biāo)簽的 value 不固定
          • 何為高基數(shù)標(biāo)簽:說白了就是標(biāo)簽的 value 可能性太多了,達(dá)到 10 萬,100 萬甚至更多

          比如 apache 的 access 日志:

          11.11.11.11?-?frank?[25/Jan/2000:14:00:01?-0500]?"GET?/1986.js?HTTP/1.1"?200?932?"-"?"Mozilla/5.0?(Windows;?U;?Windows?NT?5.1;?de;?rv:1.9.1.7)?Gecko/20091221?Firefox/3.5.7?GTB6"

          在 Promtail 中使用 regex 想要匹配 action 和 status_code 兩個(gè)標(biāo)簽:

          scrape_configs:
          ?-?job_name:?system
          ???pipeline_stages:
          ???static_configs:
          ???-?targets:
          ??????-?localhost
          ?????labels:
          ??????job:?syslog
          ??????__path__:?/var/log/syslog
          ?-?job_name:?system
          ???pipeline_stages:
          ???static_configs:
          ???-?targets:
          ??????-?localhost
          ?????labels:
          ??????job:?apache
          ??????__path__:?/var/log/apache.log

          ??-?job_name:?system
          ????pipeline_stages:
          ???????-?regex:
          ?????????expression:?"^(?P\\S+)?(?P\\S+)?(?P\\S+)?\\[(?P[\\w:/]+\\s[+\\-]\\d{4})\\]?\"(?P\\S+)\\s?(?P\\S+)?\\s?(?P\\S+)?\"?(?P\\d{3}|-)?(?P\\d+|-)\\s?\"?(?P[^\"]*)\"?\\s?\"?(?P[^\"]*)?\"?$"
          ?????-?labels:
          ?????????action:
          ?????????status_code:
          ????static_configs:
          ????-?targets:
          ???????-?localhost
          ??????labels:
          ???????job:?apache
          ???????env:?dev
          ???????__path__:?/var/log/apache.log

          那么對(duì)應(yīng) action=get/post 和 status_code=200/400 則對(duì)應(yīng) 4 個(gè)流:

          11.11.11.11?-?frank?[25/Jan/2000:14:00:01?-0500]?"GET?/1986.js?HTTP/1.1"?200?932?"-"?"Mozilla/5.0?(Windows;?U;?Windows?NT?5.1;?de;?rv:1.9.1.7)?Gecko/20091221?Firefox/3.5.7?GTB6"
          11.11.11.12?-?frank?[25/Jan/2000:14:00:02?-0500]?"POST?/1986.js?HTTP/1.1"?200?932?"-"?"Mozilla/5.0?(Windows;?U;?Windows?NT?5.1;?de;?rv:1.9.1.7)?Gecko/20091221?Firefox/3.5.7?GTB6"
          11.11.11.13?-?frank?[25/Jan/2000:14:00:03?-0500]?"GET?/1986.js?HTTP/1.1"?400?932?"-"?"Mozilla/5.0?(Windows;?U;?Windows?NT?5.1;?de;?rv:1.9.1.7)?Gecko/20091221?Firefox/3.5.7?GTB6"
          11.11.11.14?-?frank?[25/Jan/2000:14:00:04?-0500]?"POST?/1986.js?HTTP/1.1"?400?932?"-"?"Mozilla/5.0?(Windows;?U;?Windows?NT?5.1;?de;?rv:1.9.1.7)?Gecko/20091221?Firefox/3.5.7?GTB6"

          那四個(gè)日志行將變成四個(gè)單獨(dú)的流,并開始填充四個(gè)單獨(dú)的塊。

          如果出現(xiàn)另一個(gè)獨(dú)特的標(biāo)簽組合(例如 status_code =“500”),則會(huì)創(chuàng)建另一個(gè)新流。

          高基數(shù)問題

          就像上面,如果給 ip 設(shè)置一個(gè)標(biāo)簽,現(xiàn)在想象一下,如果您為設(shè)置了標(biāo)簽 ip,來自用戶的每個(gè)不同的 ip 請(qǐng)求不僅成為唯一的流。可以快速生成成千上萬的流,這是高基數(shù),這可以殺死 Loki。

          如果字段沒有被當(dāng)做標(biāo)簽被索引,會(huì)不會(huì)查詢很慢,Loki 的超級(jí)能力是將查詢分解為小塊并并行分發(fā),以便您可以在短時(shí)間內(nèi)查詢大量日志數(shù)據(jù)。

          全文索引問題

          大索引既復(fù)雜又昂貴。通常,日志數(shù)據(jù)的全文索引的大小等于或大于日志數(shù)據(jù)本身的大小。

          要查詢?nèi)罩緮?shù)據(jù),需要加載此索引,并且為了提高性能,它可能應(yīng)該在內(nèi)存中。這很難擴(kuò)展,并且隨著您攝入更多日志,索引會(huì)迅速變大。

          Loki 的索引通常比攝取的日志量小一個(gè)數(shù)量級(jí),索引的增長非常緩慢。

          加速查詢沒標(biāo)簽字段:以上邊提到的 ip 字段為例 - 使用過濾器表達(dá)式查詢。

          {job="apache"}?|=?"11.11.11.11"

          loki 查詢時(shí)的分片(按時(shí)間范圍分段 grep):

          • Loki 將把查詢分解成較小的分片,并為與標(biāo)簽匹配的流打開每個(gè)區(qū)塊,并開始尋找該 IP 地址。
          • 這些分片的大小和并行化的數(shù)量是可配置的,并取決于您提供的資源
          • 如果需要,您可以將分片間隔配置為 5m,部署 20 個(gè)查詢器,并在幾秒鐘內(nèi)處理千兆字節(jié)的日志
          • 或者,您可以發(fā)瘋并設(shè)置 200 個(gè)查詢器并處理 TB 的日志!

          兩種索引模式對(duì)比:

          • es 的大索引,不管你查不查詢,他都必須時(shí)刻存在。比如長時(shí)間占用過多的內(nèi)存
          • loki 的邏輯是查詢時(shí)再啟動(dòng)多個(gè)分段并行查詢
          日志量少時(shí)少加標(biāo)簽:
          • 因?yàn)槊慷嗉虞d一個(gè) chunk 就有額外的開銷
          • 舉例,如果該查詢是 {app=”loki”,level!=”debug”}
          • 在沒加 level 標(biāo)簽的情況下只需加載一個(gè) chunk 即 app=“l(fā)oki” 的標(biāo)簽
          • 如果加了 level 的情況,則需要把 level=info,warn,error,critical 5 個(gè) chunk 都加載再查詢
          需要標(biāo)簽時(shí)再去添加:
          • 當(dāng) chunk_target_size=1MB 時(shí)代表 以 1MB 的壓縮大小來切割塊
          • 對(duì)應(yīng)的原始日志大小在 5MB-10MB,如果日志在 max_chunk_age 時(shí)間內(nèi)能達(dá)到 10MB,考慮添加標(biāo)簽
          日志應(yīng)當(dāng)按時(shí)間遞增:
          • 這個(gè)問題和 tsdb 中處理舊數(shù)據(jù)是一樣的道理
          • 目前 loki 為了性能考慮直接拒絕掉舊數(shù)據(jù)



          END

          關(guān)Java導(dǎo)價(jià)JavaJava發(fā)

          瀏覽 71
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  永久免费 看片直接下载 | 国产豆花在线综合 | 超碰在在线 | 操逼逼综合| 95嫩模主播酒店约 |