教程:用命令行查詢?nèi)罩尽?zhí)行元查詢與分析靜態(tài)日志文件)
Grafana Loki LogCLI 實戰(zhàn)教程用命令行查詢?nèi)罩尽?zhí)行元查詢與分析靜態(tài)日志文件【免費下載鏈接】lokiLike Prometheus, but for logs.項目地址: https://gitcode.com/GitHub_Trending/lok/loki本篇教程以 Grafana Loki 的官方 LogCLI 教程docs/sources/query/logcli/logcli-tutorial.md為骨架結(jié)合 LogCLI 源碼與入門參考文檔進行深度擴充。LogCLI 是 Loki 的命令行客戶端可以運行 LogQL 查詢、對 Loki 實例執(zhí)行元查詢series、stats、volume、detected-fields 等甚至可以直接查詢靜態(tài)日志文件——非常適合在只有控制臺、沒有 Grafana 可視化面板的環(huán)境中完成日志檢索、基線與容量評估、數(shù)據(jù)衛(wèi)生檢查等管理任務(wù)。讀完本文你將掌握 LogCLI 的安裝與連接配置、日志查詢與指標查詢、基線與性能分析以及離線日志文件查詢等完整實戰(zhàn)技能。場景設(shè)定一家物流公司的包裹日志假設(shè)你是一家新成立的物流公司的站點管理員。公司使用結(jié)構(gòu)化日志記錄每一件包裹的發(fā)出與接收情況日志負載格式如下{timestamp: 2024-11-22T13:22:56.377884, state: New York, city: Buffalo, package_id: PKG34245, package_type: Documents, package_size: Medium, package_status: error, note: Out for delivery, sender: {name: Sender27, address: 144 Elm St, Buffalo, New York}, receiver: {name: Receiver4, address: 260 Cedar Blvd, New York City, New York}}這些日志由 Grafana Alloy 處理在寫入 Loki 之前會先抽取標簽labels和結(jié)構(gòu)化元數(shù)據(jù)structured metadata。你的任務(wù)是用 LogCLI 監(jiān)控這些日志并產(chǎn)出一份關(guān)于包裹整體健康狀況的報告——全程只有一臺控制臺無法使用 Grafana 可視化。前置條件與環(huán)境搭建開始之前你需要準備DockerDocker-compose本機已安裝 LogCLI安裝方式見下文安裝 LogCLI從 Loki releases 頁面 中定義了logcli構(gòu)建目標git clone https://github.com/grafana/loki.git cd loki make logcli可選地把二進制放入$PATHcp cmd/logcli/logcli /usr/local/bin/logcli從源碼結(jié)構(gòu)看LogCLI 的入口是 cmd/logcli/main.go它基于 kingpin 框架注冊了query、instant-query、labels、series、fmt、stats、volume、volume_range、detected-fields、delete等子命令核心查詢邏輯分布在 pkg/logcli 下的query、client、output、print等子包中。啟動演示環(huán)境克隆 Alloy 場景倉庫并啟動 mail-house 示例git clone https://github.com/grafana/alloy-scenarios.git docker compose -f alloy-scenarios/mail-house/docker-compose.yml up -d啟動后Loki 實例暴露在http://localhost:3100附帶一個 Grafana 實例http://localhost:3000用于交叉驗證 LogCLI 的結(jié)果該示例的 Loki 配置刻意讓 ingester 每 5 分鐘 flush 一次 chunk生產(chǎn)環(huán)境不推薦這樣做目的是讓stats等統(tǒng)計命令能夠命中對象存儲稍后你會看到它的影響。連接 LogCLI 與 Loki設(shè)置LOKI_ADDR環(huán)境變量指向 Loki 實例export LOKI_ADDRhttp://localhost:3100如果連接的是你自己的、配置了認證的 Loki 實例還需要設(shè)置LOKI_USERNAME和LOKI_PASSWORDGrafana Cloud 用戶則設(shè)置為對應(yīng)的云實例地址與憑據(jù)。驗證連接logcli labels預期輸出類似http://localhost:3100/loki/api/v1/labels?end1732282703894072000start1732279103894072000 package_size service_name state從源碼看這些連接參數(shù)在 cmd/logcli/main.go#L574-L619 中注冊--addr默認http://localhost:3100、--username、--password、--org-id對應(yīng)X-Scope-OrgID請求頭用于繞過認證網(wǎng)關(guān)直接請求指定租戶數(shù)據(jù)、--bearer-token、--ca-cert、--tls-skip-verify、--proxy-url、--retries/--min-backoff/--max-backoff等每一項都有對應(yīng)的LOKI_*環(huán)境變量且環(huán)境變量優(yōu)先于命令行參數(shù)。labels命令的輸出第一行是實際請求的 API URL其余行是該時間窗口內(nèi)的標簽名列表。日志中目前有 3 個標簽package_size、service_name、state。下面開始真正的查詢。查詢?nèi)罩緩暮Y選關(guān)鍵包裹到趨勢統(tǒng)計找出所有關(guān)鍵包裹默認回看窗口是最近 1 小時對應(yīng)--since1h的默認值見 cmd/logcli/main.go#L711查詢service_name為Delivery World且package_status為critical的日志logcli query {service_nameDelivery World} | package_statuscritical輸出類似http://localhost:3100/loki/api/v1/query_range?directionBACKWARDend1732617594381712000limit30query%7Bservice_name%3D%22DeliveryWorld%22%7D%7Cpackage_status%3D%22critical%22start1732613994381712000 Common labels: {package_statuscritical, service_nameDelivery World} 2024-11-26T10:39:52Z {package_idPKG79755, package_sizeSmall, stateTexas} {timestamp: 2024-11-26T10:39:52.521602Z, state: Texas, city: Dallas, package_id: PKG79755, package_type: Clothing, package_size: Small, package_status: critical, note: In transit, sender: {name: Sender38, address: 906 Maple Ave, Dallas, Texas}, receiver: {name: Receiver41, address: 455 Pine Rd, Dallas, Texas}} 2024-11-26T10:39:50Z {package_idPKG34018, package_sizeLarge, stateIllinois} {timestamp: 2024-11-26T10:39:50.510841Z, state: Illinois, city: Chicago, package_id: PKG34018, package_type: Clothing, package_size: Large, package_status: critical, note: Delayed due to weather, sender: {name: Sender22, address: 758 Elm St, Chicago, Illinois}, receiver: {name: Receiver10, address: 441 Cedar Blvd, Naperville, Illinois}}要點默認輸出模式default為時間戳 該流的標簽 原始日志行并附帶Common labels所有結(jié)果共有的標簽等查詢元信息可用--quiet/-q抑制--outputraw只輸出日志行--outputjsonl輸出 Loki API 的 JSON 響應(yīng)。默認只返回前 30 條--limit30。回看 24 小時logcli query --since 24h {service_nameDelivery World} | package_statuscritical增加返回條數(shù)上限logcli query --since 24h --limit 100 {service_nameDelivery World} | package_statuscritical其余常用時間參數(shù)--from/--to指定絕對時間范圍RFC3339Nano 格式、不帶時區(qū)后綴--step用于指標查詢的分辨率步長--batch控制直到達到 limit 前的每批大小默認 1000在 cmd/logcli/main.go#L716 注冊。query命令還支持--tail/-t--follow/-f為別名實時跟蹤日志、--forward正向掃描、--no-labels、--exclude-label/--include-label、--colored-output等輸出控制。從實現(xiàn)看范圍查詢會在 pkg/logcli/query/query.go#L139-L211 中按--batch分批循環(huán)調(diào)用QueryRange以上一批最后一條日志的時間戳作為下一批的起點/終點并處理同時間戳重復條目帶來的重疊直到達到 limit每次請求后打印統(tǒng)計信息配合--stats標志。指標查詢按 1 小時粒度統(tǒng)計包裹數(shù)統(tǒng)計最近 24 小時加州發(fā)出的包裹總數(shù)按 1 小時間隔logcli query --since 24h sum(count_over_time({stateCalifornia}[1h]))返回一個 JSON 對象包含一組 Unix 時間戳與對應(yīng)區(qū)間的包裹計數(shù)。由于是對日志計數(shù)做累計求和總數(shù)會隨時間單調(diào)增長[ { metric: {}, values: [ [1733913765, 46], [1733914110, 114], [1733914455, 179], [1733914800, 250], [1733915145, 318], [1733915490, 392], [1733915835, 396] ] } ]query命令支持指標查詢但輸出的是時間段內(nèi)的多個數(shù)據(jù)點類似 Grafana Explore 的 graph 視圖。再進一步用json解析器抽取package_type字段并過濾出 Documentslogcli query --since 24h sum(count_over_time({stateCalifornia}| json | package_typeDocuments [1h]))返回結(jié)構(gòu)類似但只展示加州發(fā)出 Documents 包裹的 1 小時間隔趨勢。即時指標查詢只看當前時刻的聚合值即時指標查詢instant metric query返回某個特定時間點上指標的值適合快速了解日志的聚合狀態(tài)。查詢最近 5 分鐘加州發(fā)出的包裹數(shù)logcli instant-query sum(count_over_time({stateCalifornia}[5m]))[ { metric: {}, value: [ 1732702998.725, 58 ] } ]注意instant-query相當于 Grafana Explore 的 table 視圖只返回最新數(shù)據(jù)點查詢?nèi)罩拘袝r它沒有實用輸出應(yīng)該始終用query命令。即時查詢可通過--now指定執(zhí)行時刻見 cmd/logcli/main.go#L708。把查詢結(jié)果寫入文件并行下載全量日志LogCLI 可以把查詢結(jié)果寫入文件適合下載庫存報告等全量數(shù)據(jù)。先創(chuàng)建目錄mkdir -p ./inventory然后使用并行下載參數(shù)把Delivery World最近 24 小時的全部日志寫入./inventory目錄logcli query \ --timezoneUTC \ --outputjsonl \ --parallel-duration12h \ --parallel-max-workers4 \ --part-path-prefix./inventory/inv \ --since24h \ {service_nameDelivery World}日志會被拆成兩個文件每個文件包含 12 小時數(shù)據(jù)。注意指定了--parallel-duration后--limit會被忽略cmd/logcli/main.go#L464-L467 中并行模式下強制把Limit置 0。并行下載的實現(xiàn)要點見 pkg/logcli/query/query.go--parallel-duration把時間范圍切分成若干長度相同的 job。以 24 小時、12h 為例會生成 2 個 job。--parallel-max-workers并行 worker 數(shù)量為 1 時不啟動并行走普通路徑。每個 job 通過DoQuery獨立執(zhí)行startWorkers用帶緩沖的 channel 分發(fā)任務(wù)。--part-path-prefix每個 job 的結(jié)果保存為前綴_UTC起始_UTC結(jié)束.part格式的 part 文件下載過程中文件名帶.part后綴完成后去掉。默認情況下已完成 part 文件會跳過不再下載可用--overwrite-completed-parts覆蓋。默認按時間倒序BACKWARD下載 part可用--forward改為正向。--merge-parts按順序讀取 part 文件并輸出到 stdout邊下載邊輸出讀完后默認刪除 part 文件--keep-parts可保留它們。元查詢理解數(shù)據(jù)衛(wèi)生與查詢性能作為站點管理員保持數(shù)據(jù)衛(wèi)生并確保 Loki 高效運行至關(guān)重要。元查詢不返回日志數(shù)據(jù)而是揭示日志的結(jié)構(gòu)與查詢性能。以下示例是官方運維中常用的核心元查詢。檢查序列基數(shù)series cardinality序列series是標簽組合的集合高序列基數(shù)會導致性能下降和存儲成本上升。列出日志中全部唯一序列l(wèi)ogcli series {}{package_sizeSmall, service_nameDelivery World, stateFlorida} {package_sizeMedium, service_nameDelivery World, stateFlorida} {package_sizeSmall, service_nameDelivery World, stateCalifornia} {package_sizeLarge, service_nameDelivery World, stateNew York} {package_sizeSmall, service_nameDelivery World, stateIllinois} {package_sizeLarge, service_nameDelivery World, stateFlorida} {package_sizeMedium, service_nameDelivery World, stateIllinois} {package_sizeLarge, service_nameDelivery World, stateTexas} {package_sizeMedium, service_nameDelivery World, stateCalifornia} {package_sizeMedium, service_nameDelivery World, stateTexas} {package_sizeSmall, service_nameDelivery World, stateTexas} {package_sizeLarge, service_nameDelivery World, stateIllinois} {package_sizeSmall, service_nameDelivery World, stateNew York} {package_sizeMedium, service_nameDelivery World, stateNew York} {package_sizeLarge, service_nameDelivery World, stateCalifornia}空匹配器{}返回所有流。加上--analyze-labels匯總每個標簽的唯一值數(shù)量logcli series {} --analyze-labelsLabel Name Unique Values Found In Streams state 5 15 package_size 3 15 service_name 1 15從實現(xiàn)看pkg/logcli/seriesquery/series.go#L36-L71--analyze-labels會遍歷每個流統(tǒng)計每個標簽名出現(xiàn)的流數(shù)量與唯一值集合按唯一值數(shù)量降序用 tabwriter 打印表格并額外輸出Total Streams與Unique Labels。這是定位高基數(shù)標簽的利器。檢測字段Detected fields判斷標簽 vs 結(jié)構(gòu)化元數(shù)據(jù)detected-fields用json或logfmt解析器對日志行做字段檢測幫你了解日志中存在哪些鍵從而決定哪些鍵適合提升為標簽、哪些適合保留在結(jié)構(gòu)化元數(shù)據(jù)中l(wèi)ogcli detected-fields --since 24h {service_nameDelivery World}label: city type: string cardinality: 15 label: detected_level type: string cardinality: 3 label: note type: string cardinality: 7 label: package_id type: string cardinality: 994 label: package_size_extracted type: string cardinality: 3 label: package_status type: string cardinality: 4 label: package_type type: string cardinality: 5 label: receiver_address type: string cardinality: 991 label: receiver_name type: string cardinality: 100 label: sender_address type: string cardinality: 991 label: sender_name type: string cardinality: 100 label: state_extracted type: string cardinality: 5 label: timestamp type: string cardinality: 1000現(xiàn)在你能理解為什么package_id放在結(jié)構(gòu)化元數(shù)據(jù)中、而package_size做成標簽了package_id基數(shù)高達 994幾乎每個日志條目都不同將來可能需要按它精確查詢適合作為結(jié)構(gòu)化元數(shù)據(jù)package_size基數(shù)只有 3天然適合做標簽。detected-fields默認最多返回 100 個字段--limit、每個子查詢處理 1000 行--line-limit可傳可選的第二個參數(shù)指定單個字段名默認步長--step10s見 cmd/logcli/main.go#L825-L865。檢查查詢性能stats保持 Loki 健康還要關(guān)注查詢性能。stats返回查詢所觸及的數(shù)據(jù)量統(tǒng)計logcli stats --since 24h {service_nameDelivery World}http://localhost:3100/loki/api/v1/index/stats?end1732639430272850000query%7Bservice_name%3D%22DeliveryWorld%22%7Dstart1732553030272850000 { bytes: 12MB chunks: 63 streams: 15 entries: 29529 }包括查詢的字節(jié)數(shù)、chunk 數(shù)、流數(shù)與條目數(shù)。縮小查詢范圍追加第二個標簽可以對比性能logcli stats --since 24h {service_nameDelivery World, package_sizeLarge}{ bytes: 4.2MB chunks: 22 streams: 5 entries: 10198 }可見收窄標簽后觸及的流與條目大幅減少。從實現(xiàn)看pkg/logcli/index/stats.go、pkg/logcli/client/client.go#L193-L204stats請求的是 Loki 的/loki/api/v1/index/stats接口返回的IndexStatsResponse包含 bytes、chunks、streams、entries 四個維度。注意stats/volume僅對使用 TSDB 索引格式的 Loki 實例有效且 LogCLI 只能返回觸及對象存儲的查詢統(tǒng)計。本演示為了讓統(tǒng)計可見而把 ingester 的 flush 間隔壓到 5 分鐘生產(chǎn)環(huán)境不推薦。如果運行演示時沒有看到統(tǒng)計數(shù)據(jù)等幾分鐘再執(zhí)行一次。檢查日志量volume 與 volume_range了解正在寫入 Loki 的數(shù)據(jù)量有助于容量規(guī)劃。查詢Delivery World最近 24 小時的日志總量logcli volume --since 24h {service_nameDelivery World}[ { metric: { service_name: Delivery World }, value: [ 1732640292.354, 11669299 ] } ]結(jié)果包含時間戳與日志攝入總數(shù)。用volume_range查看日志量隨時間的變化logcli volume_range --since 24h --step1h {service_nameDelivery World}--step把日志量按 1 小時桶聚合注意某小時如果沒有日志該小時不會返回值。還可以按特定標簽值分桶聚合logcli volume_range --since 24h --step1h --targetLabelsstate {service_nameDelivery World}volume/volume_range的實現(xiàn)位于 pkg/logcli/index/volume.go底層請求 Loki 的/loki/api/v1/index/volume與/loki/api/v1/index/volume_range接口--targetLabels指定按哪些標簽分組聚合cmd/logcli/main.go#L815volume_range的默認--step1hcmd/logcli/main.go#L819。查詢靜態(tài)日志文件LogCLI 還支持直接查詢不在 Loki 中的靜態(tài)日志文件。上一節(jié)我們把Delivery World的日志存到了./inventory目錄現(xiàn)在用類似命令把結(jié)果合并輸出到單個文件logcli query \ --timezoneUTC \ --parallel-duration12h \ --parallel-max-workers4 \ --part-path-prefix./inventory/inv \ --since24h \ --merge-parts \ --outputraw \ {service_nameDelivery World} ./inventory/complete.log--merge-parts會按順序讀取 part 文件并輸出到 stdout原始日志行模式raw然后通過 shell 重定向?qū)懭隿omplete.log。接著對靜態(tài)文件執(zhí)行查詢cat ./inventory/complete.log | logcli --stdin query {service_nameDelivery World} | json | package_statuscritical注意查詢靜態(tài)日志文件時標簽不會自動識別因此{service_nameDelivery World}在這種情況下是可選的前綴為了表達清晰建議保留json是必須的——它把日志行按 JSON 解析從而提取package_status字段。例如省略json過濾器再試cat ./inventory/complete.log | logcli --stdin query {service_nameDelivery World} | package_statuscritical由于沒有解析 JSONpackage_status字段無法被檢測到查詢返回空結(jié)果。從實現(xiàn)看--stdin標志會把客戶端切換為client.NewFileClient(os.Stdin)cmd/logcli/main.go#L393-L417。其核心機制在 pkg/logcli/client/file.goFileClient為輸入注入一個固定的虛擬標簽sourcelogcli并用本地logql.Engine直接對文件內(nèi)容執(zhí)行 LogQL最大讀取 20MB見defaultMaxFileSize。如果查詢以|或!開頭即省略了流選擇器main.go 會自動注入{sourcelogcli}作為流選擇器使|error這類省略式查詢也能工作。FileClient的SelectLogs會把每行日志按時間順序BACKWARD 為逆序逐條送入日志管道pipeline匹配處理命中則歸入對應(yīng)流。stats、volume、detected-fields、delete等在文件客戶端上返回ErrNotSupported——它們依賴 Loki 的索引能力。常見連接配置速查下表匯總 LogCLI 與 Loki 連接相關(guān)的常用參數(shù)與對應(yīng)環(huán)境變量全部注冊于 cmd/logcli/main.go#L574-L619參數(shù)環(huán)境變量說明--addrLOKI_ADDRLoki 服務(wù)地址默認http://localhost:3100--username/--passwordLOKI_USERNAME/LOKI_PASSWORDHTTP 基本認證憑據(jù)--org-idLOKI_ORG_ID為請求添加X-Scope-OrgID頭用于指定租戶--bearer-token/--bearer-token-fileLOKI_BEARER_TOKEN/LOKI_BEARER_TOKEN_FILEBearer Token 認證--ca-cert/--tls-skip-verifyLOKI_CA_CERT_PATH/LOKI_TLS_SKIP_VERIFYTLS 服務(wù)端證書校驗--cert/--keyLOKI_CLIENT_CERT_PATH/LOKI_CLIENT_KEY_PATH客戶端 mTLS 證書--retries/--min-backoff/--max-backoffLOKI_CLIENT_RETRIES/LOKI_CLIENT_MIN_BACKOFF/LOKI_CLIENT_MAX_BACKOFF查詢失敗重試策略--proxy-url/--envproxyLOKI_HTTP_PROXY_URL/LOKI_ENV_PROXYHTTP 代理--compressLOKI_HTTP_COMPRESSION請求傳輸壓縮--nocacheLOKI_NO_CACHE添加Cache-Control: no-cache請求頭結(jié)論在本次教程中作為物流公司的站點管理員我們使用 LogCLI 完成了三件事查詢?nèi)罩静?gòu)建包裹健康報告通過元查詢理解數(shù)據(jù)衛(wèi)生基數(shù)、檢測字段與查詢性能stats、volume以及直接查詢靜態(tài)日志文件。LogCLI 是理解日志內(nèi)容及其在 Loki 中存儲方式的強大工具。隨著你的解決方案規(guī)模擴大請記得用 LogCLI 持續(xù)監(jiān)控序列基數(shù)與查詢性能——這往往是 Loki 長期健康運行的關(guān)鍵。更多命令細節(jié)可查閱 LogCLI 入門與命令參考命令的全部參數(shù)可通過logcli help、logcli help query等查看。【免費下載鏈接】lokiLike Prometheus, but for logs.項目地址: https://gitcode.com/GitHub_Trending/lok/loki創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考