iT邦幫忙

2

來自 Grafana 與 OpenTelemetry 的 Logging 最佳實踐

雷N 2025-12-22 11:31:381051 瀏覽
  • 分享至 

  • xImage
  •  

完整內容請至幹話王 Blog

現代可觀測性中的 Log 思維革命:來自 Grafana 與 OpenTelemetry 的最佳實踐

以下是影片內容的完整解釋與重點摘要:

1. 2025 年 Log 的角色與重要性

2. OpenTelemetry 為何需要 Logng API? [17:23]

  • 儘管已有很多成熟的 Log [框架(如 Log4j,Python logging),OpenTelemetry 仍推出了自己的 Logging API。

  • 互操作性(Interoperability):最初目的是為了橋接現有的 Log 系統(Log Bridge API)。

  • 統一性:讓使用者能用同一套 API 處理 Metrics、Traces 和 Logs。

  • 強型別與結構化:OpenTelemetry 希望推動 Log 往「結構化(Structured)」方向發展,包含明確的事件名稱(Event Name)與屬性(Attributes),而非僅是純文字字串。

3. 結構化 Log vs. 人類可讀性

  • 兩難:純文字 Log 對人類閱讀除錯很友善,但對機器分析不便;結構化 Log(如 JSON)對機器友善,但人類難以直接閱讀。

  • 建議:Log 應該是結構化的,但保留一個人類可讀的訊息欄位(或將其轉化為 Event Name)。[34:51]

[4. Log 的最佳實踐建議

來賓們分享了具體的實戰建議:

  • 撰寫有意義的錯誤訊息[36:52]

    • Ed強調:當你寫 error log 時,請告訴讀者(通常是未來的你)該怎麼做。不要只寫「資料庫連線失敗」,要寫「資料庫連線失敗,正在重試」或「請檢查某設定」。
  • 直接傳送 vs檔案抓取**[42:50]

    • Jack 建議應用程式應直接透過網路(OTLP協定)發送Log後端,而不是寫入檔案再由 Agent 去抓取(Tail)。這樣能更無縫地保留 Context(如 Trace ID)。

    • Ed 補充建議:在應用程式與後端之間最好有一個本地的Collector**。這樣當需要過濾大量垃圾 Log 時,可以在 Coller 端調整設定,而無需重新部署應用程式。

  • 不要濫用 Log

    • Metrics vs. Logs[47:28]:不要用 Lo 來做高基數(High Cardinality)的計數統計,那應該用 Metrics。

    • Traces vs. Logs [48:29]:如果你想知道「請求花費了多少時間」或「請求的路徑」,請使用 Traces,不要用 Log 印出「開始]請求」、「結束請求」。

  • [Log 等級(Severity[01:03:36]:絕對不要記錄沒有等級的 Log。至少要區分 INFO、ERROR、DEBUG,這對過濾和警報至關重要。

  • 安全性 [01:01:53]:小心不要在 Log 中記錄 PII(個人識別資訊)或 Secrets,也不要記錄完整的 HTTP Headers。

5. 快速問答環節(Good or Bad?)

影片末尾[[57:12]] 進行了一個快問快答遊戲:

  • 格式化 Log 字串?** 不建議(應使用參數化/結構化)。

  • 將所有 Excetion 都記為 Error? 同意。

  • 記錄 Request/Response Body? 通常不建議(成本太高且易洩漏個資,除非有極強烈的除錯需求。

  • 記錄所有細節? 不建議,每一個 bytes都要錢,請有意識地選擇要記錄的內容(Be intention)。


在 Cloud Native 與微服務架構盛行的 2025 年,Log(日誌)這個最古老的除錯工具,是否已經過時?或者它只是需要一點「現代化」的改造?

最近觀看了 Grafana Labs 與 OpenTelemetry (OTel) 技術委員會成員的一場深度對談(Community Call),主題聚焦於 Logging Best Practices。這場討論並非單純的操作教學,而是對於 Log 在現代可觀測性(Observability)中角色的重新定義。

以下整理了影片中的核心觀點,希望能幫助開發者與維運人員打破舊有的 Log 思維,建立更具「意圖性」的可觀測性策略。

1. 觀念翻轉:Log 的定位與「反模式」

在 Tracing(追蹤)技術日益普及的今天,很多人會問:「我還需要 Log 嗎?」答案是肯定的,而且 Log 是不可取代的「唯一真實訊號」。

然而,為了追求新技術,社群中出現了一種名為 Zero Duration Spans(零持續時間 Span) 的怪現象。

什麼是 Zero Duration Span?

開發者為了利用 Tracing 工具的視覺化,將原本該是 Log 的單點事件,包裝成「開始時間等於結束時間」的 Span。

OpenTelemetry 技術委員會成員 Jack Berg 對此提出了精闢的見解:

"If it walks like a log, talks like a log, it's a log." (如果它走起來像 Log,叫起來像 Log,那它就是 Log,別裝了。)

判斷標準

  • Span (Traces):具有層級結構(Hierarchy)與持續時間(Duration)。用來回答「這個請求花了多久?路徑為何?」。

  • Log:發生在特定時間點的事件。用來回答「當下發生了什麼事?」。

最佳實踐:誠實面對資料的本質,不要硬套用 Span 的概念。Log 依然是一等公民。

2. 結構化革命:從「給人看」到「機器優先」

傳統的 Log 是一行行給人類閱讀的字串(Text-based),但在微服務與海量資料的場景下,這種模式已經行不通。OpenTelemetry 正推動 Log 往 結構化(Structured)強型別(Strongly typed) 發展。

為什麼需要結構化?

  • 查詢效率:試想在幾億行 Log 中 grep 字串,與在資料庫中查詢 attributes.http_status_code == 500 的區別。

  • 關聯性:OTel 的目標是讓 Logs、Traces、Metrics 使用統一的語意規範(Semantic Conventions)。

兩難與解法

結構化 Log(如 JSON)對機器友善,但對人類閱讀不便。

  • 建議做法:保留 Log 的結構化欄位(Attributes)供機器分析,但同時保留一個 message 欄位或是將其轉化為易讀的 Event Name 供人類快速瀏覽。

3. 架構演進:File Tail vs. OTLP Direct

你的 Log 是怎麼送到後端的?這涉及到架構的解耦。

傳統模式:File Scraping

應用程式將 Log 寫入磁碟檔案 -> Agent (如 Promtail) 去抓取 (Tail) -> 傳送後端。

  • 缺點:容易丟失 Context(如 Trace ID),且依賴硬碟 I/O。

現代模式:OTLP Direct

應用程式透過網路協定(OTLP)直接將 Log 發送出去。

  • 優點:原生支援結構化,保留完整 Context,無需檔案權限。

🔥 進階技巧:Local Collector Pattern

Grafana Loki 的維護者 Ed 提出了一個極佳的架構建議:在應用程式旁跑一個 Local Collector(作為 Sidecar 或 DaemonSet)。

好處:當你需要將 Log Level 從 INFO 改為 DEBUG 時,你只需要調整 Collector 的過濾規則,完全不需要重新部署應用程式。這實現了極致的維運解耦。

4. 實戰指南:如何寫出「有靈魂」的 Log?

當開發者敲下 logger.error(...) 時,請記住以下原則:

✅ 1. 寫給未來的自己 (Actionable Errors)

不要只寫「連線失敗」。錯誤訊息必須包含「接下來該做什麼」。

  • ❌ Bad: Connection failed.

  • ✅ Good: Connection to DB failed, retrying in 5s. Please check network config. 精神:同理心。 給半夜修 Bug 的人一條明路。

✅ 2. Context is King

沒有 Trace ID 或 User ID 的 Log,在高併發環境下幾乎是雜訊。務必確保 Log 包含足夠的上下文屬性。

⛔ 3. 避免高成本操作

  • 不要 Log Request Body:除非在開發環境,否則這會導致儲存成本爆炸,且有洩漏 PII(個資)與 Secrets(金鑰)的風險。

  • 不要用 Log 做統計:如果你想知道「API 被呼叫幾次」,請用 Metrics,不要用 Log。

總結:Be Intentional (保持意圖)

整場討論可以用這兩個字總結:"Be Intentional"

Log 不再是廉價的 printf。每一行 Log 都有儲存成本、傳輸成本與認知成本。

  • 這條 Log 是給誰看的?(人還是機器?)

  • 它的目的是什麼?(除錯、稽核還是統計?)

  • 它包含了足夠的資訊嗎?

在 2025 年,寫好 Log 不僅是技術能力的展現,更是一種對系統架構與團隊協作的深層思考。


參考來源:Grafana & OpenTelemetry Community Call - Logging Best Practices


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
whitefloor
iT邦研究生 1 級 ‧ 2025-12-23 01:46:36

這太重要了,剛好就看到前輩寫出來了

最近在工作上也是遇到公司有這些問題

像是要把log標準化、結構化、減少不必要的輸出(start/end)
最後還要透過log分級達到自動告警減少人工跟促進即時觀測性
是個很值得研究的題目

雷N iT邦研究生 1 級 ‧ 2025-12-26 10:47:38 檢舉

影片的大神有講,其實吧log內容沒人可以在一開始完整定義出要記錄哪些(包含欄位跟事件)
都是出事慢慢補上去的。所以結構化是先決條件,後續再加,格式不才會亂。知道level的定義,後續在家才知道怎分級。

雷N iT邦研究生 1 級 ‧ 2025-12-26 11:24:14 檢舉

[00:34:33] Lyudmila: 這引出了我想向來賓和 Nicole 提出的問題。在人類閱讀日誌和結構化日誌之間顯然存在著權衡,那麼我們該怎麼做呢?
[00:34:51] Nicole: 我認為可以兩者兼顧。我們可以以某種仍然保持結構化的方式添加人類可讀的內容。比如說,定義好哪些部分是不那麼結構化的,然後就只在那部分保持非結構化;不要試圖把非結構化的東西放到預期應該是結構化的地方。
[00:35:17] Nicole: 什麼類型的不結構化內容呢?回到這些例子,非結構化的部分就像是那個字串,比如 "hello world"。我認為 OpenTelemetry 會說,那些看似非結構化的部分其實也是有結構的,只是你沒有那樣稱呼它而已。例如,你知道 "hello world" 字串被轉換成了一個事件名稱(Event Name),而這個事件名稱本身就是結構化的。
[00:35:49] Ed: 嗯,是的,我同意。但我認為這在現實世界中行不通。我覺得問題在於,你可以......我認為你可以同意,如果大家坐下來審視一個應用程式並查看它的日誌輸出,他們或許能想出一種方法,把訊息轉換成事件,然後讓它們變成固定數量的事件,並讓它完全變成一種機器容易讀取的方式。但在實務上,沒人會這麼做。你知道的,而且當你構建應用程式時,你在當下根本不知道那些資訊,對吧?你真的不知道......有些東西是在你的應用程式存在之後,事後諸葛才看出來的。所以大多數的日誌行是在某人試圖在本地除錯以獲得答案時創建的,然後它們就永遠存在了。

ED想表達:
理想情況:大家坐下來開會,列出系統會發生的所有事件(如 USER_LOGIN_FAILED, PAYMENT_PROCESSED),定義好完美的 Schema,然後寫程式。這樣機器讀起來超爽。
現實情況:沒人有時間做這件事。開發者通常是在寫程式碼的過程中,隨手加上 Log 的。你無法在寫程式的第一天就預知未來所有的除錯場景。
所以會用 msg 這欄位去先隨手記錄一些事情。

我要留言

立即登入留言