Logging,Metrics 和 Tracing
昨天晚上在看Gophercon大會PPT的時候無意中看到了關於Metrics,Tracing和Logging相關的一篇文章,湊巧這些我基本都接觸過,也是去年後半年到現在一直在做和研究的東西。從去年的關於Metrics的goappmonitor,到今年在排查問題時腦洞的基於log全鏈路(Tracing)追蹤系統的設計,正好是對這三個話題的實踐。這不禁讓我對它們的關係進行思考:Metrics和Looging的區別是什麼?Tracing還需要Logging嗎?我們什麼時候需要Metrics?它們之間有什麼關聯?
這其實也是我在設計goappmonitor的時候一直困擾我的問題,當時一直在想我要構建一個監控go程序的應用,它能夠度量請求,函數調用,內存,CPU等等這些指標,無疑我需要侵入性的去打點,那麼問題來了,我們的應用中是有自己的日誌系統的,那麼同一份數據需要記錄兩次嗎?我該如何劃分這個界線?毫無疑問,Metrcis和Logging是有數據重疊的。我們可以任務Metrics是對可觀測性指標的一種度量,例如請求數,函數調用次數等,但是對於Metrcis來說,它有著自己獨特的屬性——聚合。另外,我們知道我們記錄日誌(Logging)是以事件為元數據,即記錄當前發生了什麼,這是Logging的關注屬性。在構想產品全鏈路追蹤系統時,類似的問題再一次出現,我在記錄Tracing數據的時候,或多多少會有Logging的數據,在Tracing中我認為重要的是鏈路數據指標屬性,例如調用了哪些函數棧,該請求處理時間是多少等等,同樣我們會在函數中記錄得到了哪些請求,即Logging,但Tracing也有著自己獨特的屬性——請求範圍。
如下圖:
日誌,什麼是日誌,不知道大家有沒有想過它的定義或者邊界。Logging即是記錄處理的離散事件,比如我們應用的調試信息或者錯誤信息等發送到ES;審計跟蹤時間信息通過Kafka處理送到BigTable等數據倉儲等等,大多數情況下記錄的數據很分散,並且相互獨立,也許是錯誤信息,也許僅僅只是記錄當前的事件狀態,或者是警告信息等等。
當我們想知道我們服務的請求QPS是多少,或者當天的用戶登錄次數等等,這時我們可能需要將一部分事件進行聚合或計數,也就是我們說的Metrics。可聚合性即是Metrics的特徵,它們是一段時間內某個度量(計數器或者直方圖)的原子或者是元數據。例如接收的HTTP數量可以被建模為計數器,每次的HTTP請求即是我們的度量元數據,可以進行簡單的加法聚合,當持續了一段時間我們又可以建模為直方圖。
Logging是處理請求範圍內的信息,即可以綁定到系統中單個事務對象的生命周期的任何數據或元數據。對於每一次Tracing,例如HTTP請求的Tracing,我們只需要關注請求目前到達的節點狀態,當前耗時,誰接收了這個請求等等,不用關係目前的系統日誌,錯誤信息等等這些事件。或者像出站RPC到遠程服務的持續時間; 將實際SQL查詢的文本發送到資料庫; 或入站HTTP請求的相關ID等等。
通過以上我們可以將重疊部分這樣定義:
有人可能會想到,對於許多典型的雲應用程序最終都將成為Tracing,因此該邊界是在更廣泛的跟蹤背景下進行討論。 但我們現在可以看到,並不是所有的Logging事件都是可聚合或者說可聚合的意義;並不是所有的度量都有在Tracing之中。 它們之間有相互重疊,也有絕對的覆蓋。
在業界對於以上的實踐可以看到現有系統進行的分類。例如,Prometheus開始專註于衡量系統,隨著時間的推移可能會越來越多地追蹤,從而成為Tracing的指標,但可能不會太深入到日誌記錄中,同時基於Dapper的各類分散式鏈路追蹤系統也在不斷出現。 ELK提供log的記錄,滾動和聚合,並在其他領域不停的積累更多的特性,並集成進來。
所以,日誌系統,度量系統,追蹤系統這三個緯度所關注重點是不一樣的。一般來說日誌系統是對我們應用或者系統事件做一個記錄,這些記錄是我們問題排查,取證的一些依據;度量系統是對某些我們關注事件的聚合,當達到一定指標我們會設置告警,會設置自適應機制,會有容災等等;在追蹤系統我們更關注請求的質量和服務可行性,是我們優化系統,排查問題的高階方法。一般來說,它們的優先順序依次降低。
參考文獻:
Metrics, tracing, and logging
Dapper,大規模分散式系統的跟蹤系統 by bigbully
董的博客 " 開源日誌系統比較
推薦閱讀:
※理解架構版本
※如何成為一名軟體架構師?
※使用 caddy 作為微服務的 API gateway
※是時候想想該怎麼刪代碼了
※一次生產事故的優化經歷