日誌(Log)是軟體中最古老、也最基礎的資訊載體。從第一次靠著 print 找出第一個 Bug,到後來只在關鍵路徑留下精煉訊息,工程師對於 Log 的態度,正是從「全部記下來」走到「精準記下來」的過程。本章作為 Logs 篇的開篇,整理 Log 的處理流程、常見格式,以及它在現代可觀測性(Observability)生態中的位置。

日誌資訊的處理流程#

Log 的格式雖然多樣,使用方式也因情境而異,但整體流程仍可套用 Observability 四步驟:生成、收集、儲存、使用。

生成#

Log 的來源主要有三類,分別對應不同的輸出管道:

  • Console:透過 STDOUT 或 STDERR 輸出,常見於開發階段或容器化環境。
  • File:寫入本機檔案,通常會搭配輪替(Rotate)機制管理檔案大小。
  • Stream:直接透過網路把 Log 推送到 Log Server,例如使用 Forwarder 將事件轉發出去。

實務上 Log 不會只有訊息本文,常會夾帶補充欄位,例如:

  • 時間:事件發生的時間戳記。
  • Level:等級資訊,如 DEBUG、INFO、WARN、ERROR、FATAL。
  • 補充上下文:IP、主機名稱、程式名稱、函式名稱等識別資訊。

依據結構,Log 大致可分為文字格式(Text)與結構化日誌(Structured Logging)兩派:

  • Text:純文字格式,搭配 Pattern 樣板輸出,例如以 %d{yyyy-MM-dd HH:mm:ss} [%-5p] [%c] [%t] %m%n 形式輸出 2021-09-19 15:00:00 [INFO] [main] [com.example.Main] Hello World!
  • Structured:結構化格式,常見的有 JSON Lines(每行一筆 JSON 物件)以及 logfmt 這類 Key-Value 結構,例如 time="..." level="INFO" message="Hello World!"

結構化日誌的優勢在於補充欄位可以直接以欄位形式擴充,下游工具也能直接以 Key 進行查詢與彙總,例如以 level=INFO 一次撈出所有 INFO 等級事件,不必額外撰寫 Parser。

收集#

收集 Log 的模式可以分成 Push 與 Pull:

  • Push:Log Library 在程式內主動把資料推送到 Log Server,常見於 Stream 形式。
  • Pull:另外執行的代理(Agent)程式從 Console 或 File 主動讀取,再轉送到後端。

收集階段也是處理敏感資訊的重要時機:可能需要新增欄位(例如環境名稱)、遮蔽資料(例如使用者密碼、IP),或是在收集端進行多行(Multiline)合併。Push 模式通常透過 Log Library 處理,而 Pull 模式則交由 Agent(如 Promtail、Fluent Bit、Vector)負責。

儲存#

儲存方式深受「之後要怎麼用」影響:

  • 想要做全文搜尋與互動式分析,常見選擇是 ELK Stack(Elasticsearch、Logstash、Kibana)這類以倒排索引為核心的方案。
  • 想要在 Kubernetes 與容器情境下保留 Log,許多團隊會改用 Loki 這類以標籤索引(Label Indexing)取代全文索引的工具。
  • 若需要進階的批次分析或機器學習,則可能將 Log 倒進 Apache Spark 等大資料框架。

Log 體量通常龐大,成本控制是不得不面對的議題。常見手段包括:在生成或收集端先過濾不必要的事件、定期清除過期資料、啟用壓縮、選擇較便宜的儲存層級(例如物件儲存)。同時也要留意,部分工具會額外為索引或 Metadata 額外耗用磁碟空間。

使用#

Log 最終要被人或機器消費,常見的使用方式包括:

  • 文字編輯器:用 Ctrl/Cmd + F 或正規表示式做基本查詢。
  • 命令列:在伺服器上以 grepawk 之類的指令過濾。
  • Grafana:透過 Loki 資料來源以 LogQL 進行查詢。
  • Kibana:對 Elasticsearch 做互動式探索與儀表板呈現。
  • SaaS:例如 Datadog Logs,提供整合式查詢、儀表板與告警。

主流組合與選型考量#

經過長年演進,Log 領域已長出數種典型的工具組合:

  • ELK:Elasticsearch、Logstash、Kibana,以全文搜尋為核心。
  • EFK:把 Logstash 換成 Fluentd 作為 Aggregator,廣泛用於 Kubernetes。
  • PLG:Promtail、Loki、Grafana,強調輕量與低成本。
  • SaaS:例如 Datadog,把整條 Pipeline 交給雲端服務。

選型沒有絕對答案,使用者真正需要的可能只是 grep 與一個保留 7 天的本地檔案;過於複雜的工具反而會把學習成本推得太高。但反過來,過少的 Log 又會讓事故時找不到線索。

因為需求會隨組織規模與業務複雜度演進,作者的建議是:起步時挑一個「夠單純、又有擴展空間」的方案,之後再依需要替換或加層。

與 Logs 篇後續章節的銜接#

本章為 Logs 篇的入口,後續章節會依「儲存/使用」與「收集」兩條主軸展開:

  • Loki:Log Aggregation System,搭配 LogQL 做查詢。
  • Promtail:Loki 專屬的 Log Agent,承襲 Prometheus 的標籤模型。
  • Fluent Bit:輕量化的 Telemetry Agent,源自 Fluentd 生態。
  • Vector:以 Rust 撰寫、強調高效能的資料收集器。

原文出處#

  • 原書/iThome:https://ithelp.ithome.com.tw/articles/10327857