日誌與 Loki:只索引 label,不索引全文
· tech
📑 目錄
三支柱第二個:logs。而 Loki 最該懂的一件事,是它一個很聰明、很省的設計選擇——它不像傳統 log 系統(ELK)那樣索引全文,而是「像 Prometheus 一樣只索引 label」。這個選擇讓它便宜到能存海量 log,代價是換一種查法。而且你會發現,上一篇那個 cardinality 的坑,在這裡又原封不動地出現一次。
核心:只索引 label,內容靠 grep
傳統的 Elasticsearch / ELK 把每一行 log 的全文都建索引——任意關鍵字都能秒搜,但代價是索引巨大、吃大量 RAM 與磁碟,貴。Loki 反其道而行:只索引一小組 label,原始 log 內容壓縮後丟 object storage、完全不索引。 查詢因此變成兩步:
這個「先用 label 縮小、再暴力掃」的設計,配上 object storage 當後端,讓 Loki 便宜到你敢把 log 全開、留久。它跟 metric 的 黃金路徑也接得剛好:metric 告訴你「哪個 service、什麼時候」,你拿這兩個 label 進 Loki 一縮,範圍就小了。
同一個 cardinality 陷阱,又出現了
既然 Loki 的 label 也是拿來建索引的,那 上一篇那個 cardinality 的坑就原封不動:label 高基數 → 索引爆炸 → Loki 一樣會死。 所以千萬別把 trace_id、user_id、order_id 這種高基數的東西當 label。那它們要放哪?放進 log 內容本身——而且用 structured 的格式,查詢時再撈出來:
| json 解析、當場撈出來過濾。這樣索引保持小而快、細節保持可查而便宜——同一筆資料,擺對地方,就同時避開了 上一篇的 cardinality 爆炸。所以請務必用 structured logging,別再吐一坨無結構的字串LogQL:還能把 log 變成 metric
LogQL 刻意設計得很像 PromQL,分兩段:label selector(用索引縮小)+ pipeline(過濾、解析)。而它有個很殺的能力——把 log 當場算成 metric:
{service="checkout", level="error"} |= "timeout" # 撈出 checkout 的 timeout 錯誤
{service="checkout"} | json | status >= 500 # 解析 JSON、再按欄位過濾
# 把 log 變成 metric:每秒的錯誤行數(可以直接拿去畫圖、告警)
sum(rate({service="checkout"} |= "error" [5m]))
最後那條很重要:你不必為每件事都預先埋一個 metric——很多時候直接對 log rate() 一下,就得到一條可畫可告警的曲線。這讓 log 和 metric 的界線變得很靈活。
反思
Loki 是「把 Prometheus 的哲學搬到 log」的漂亮示範
Loki 最打動我的,是它把同一個好想法——只索引低基數的 label——從 metric 原封不動搬到了 log:在 metric 上,它避免 series 爆炸;在 log 上,它避免索引爆炸。看懂一個好想法的「形狀」,你就會在別的地方一眼認出它。而 Loki 的取捨也很誠實:它不追求「任意全文都秒搜」(那是 ELK 用錢換來的),而是賭「你排障時多半已經知道要看哪個 service、哪段時間」。對「metric 示警 → 我知道哪個服務出事 → 去看它的 log」這個最常見的路徑,這個賭注幾乎總是對的。認清自己的常見場景、然後為它(而不是為每種極端)最佳化,是很成熟的工程判斷。
「label 進索引、內容進 line」,是一次乾淨的「把貴的東西放對地方」
高基數的 order_id、trace_id 不能進索引(會爆),但你又需要能按它查——Loki 的答案漂亮地化解了這個張力:把它放進 structured 的 log 內容,查詢時再 | json 撈出來。 索引保持小而快,細節保持可查而便宜。這種「熱路徑放低基數、細節留在冷資料裡按需撈」的分層,其實是所有可觀測性、甚至資料庫索引設計共通的智慧。它也再次驗證了 上一篇那句:同一筆資料,擺對地方,結果天差地遠。 工程上很多問題,不是「能不能存」,而是「該把它放進『快而貴的索引』還是『慢而便宜的儲存』」——分對了,又快又省。
「便宜」不是次要指標,是決定你「敢不敢全都留」的關鍵
戴上 EM/SRE 的成本帽子後,我對「便宜」的敬意越來越高。log 最痛的取捨,是「留多久、留多細」,而這直接被成本決定:ELK 貴,逼你砍 retention、砍 log level,結果事故回溯時,你要的那段 log 早就被清掉了;Loki 便宜,讓你敢把 log 留久、留全,於是它在你需要的那一刻還在。一個便宜到你敢全開的觀測系統,實務價值往往勝過一個功能華麗、卻貴到你只敢開一半的。這收束回這系列的主軸——觀測的終點是行動,而你留不起的資料,在事故當下幫不了你行動。省下的每一塊錢,買的其實是「事故當天,證據還在」。這對人手與預算都有限的團隊,是生死線,不是 nice to have。