為什麼你應該瞭解 Loggie

語言: CN / TW / HK

你可能對日誌並不感興趣。

不過沒關係,本文也不打算介紹Loggie如何採集日誌。

首先請不要被Loggie的名稱限制了思維,我想重新定義一下:

什麼是Log?

從本質上,Log即為Data。而Data,在我們平時的開發中無處不在。

引用知名經典野豬書《Designing Data-Intensive Applications》(還沒看過這本書的請不要錯過)裡的一句話:

現今很多應用程式都是資料密集型(data-intensive) 的,而非計算密集型(compute-intensive) 的。因此CPU很少成為這類應用的瓶頸,更大的問題通常來自資料量、資料複雜性、以及資料的變更速度。

不管我們是CRUD boy或者YAML工程師,恐怕寫程式碼的時候最常接觸和思考的,還是如何設計各種資料模型,如何處理記憶體、磁碟或網路上的位元組,通常這些過程中,會涉及到協議編解碼(JSON/ProtoBuf),資料儲存(SQL/NoSQL)與通訊(HTTP/RPC),訊息傳遞(MQ)等等。

但是,我們在工作中,往往會更加關注專案的業務邏輯,忽略背後的技術本質和抽象,以及工程化的難題與挑戰。長期以來,很容易成為某些第三方庫的熟練封裝工,框架API的機械使用者,別人嘴裡的「調包俠」。

如何避免陷入這種困境?一個好的辦法是選擇一個合適的開源專案,從專案裡學習總結和提煉,嘗試對其中的程式碼進行修改、補充或者優化。

真正合適的選擇其實並不多,當然你也能猜到,這裡我向你推薦Loggie。

因為,Loggie有著直觀、通用的資料鏈路模型:source → interceptor → sink,典型的資料密集型應用,沒有太多的業務屬性,易於擴充套件開發,極致簡單但卻又包羅永珍。

Loggie是什麼?

僅從日誌的場景來解釋,Loggie(https://github.com/loggie-io/loggie/) 是一個基於Golang的輕量級、高效能、雲原生日誌採集Agent和中轉處理Aggregator,支援多Pipeline和元件熱插拔,提供了:

🔨 一棧式日誌解決方案:同時支援日誌中轉、過濾、解析、切分、日誌報警等

☁ 雲原生的日誌形態:快速便捷的容器日誌採集方式,原生的Kubernetes動態配置下發

🔑 生產級的特性:Loggie吸收了我們長期的大規模運維經驗,形成了全方位的可觀測性、快速排障、異常預警、自動化運維能力

但需要再次強調的是,Loggie裡的Log只是Data或者Events在一種具體場景下的稱號,採集日誌只是其中一個叫file source的元件,Loggie裡還有很多其他的source/interceptor/sink:

所以,格局大點,我更願意描述Loggie為:CloudNative Events Connector And Processor

(雲原生的資料聯結器,連線了各種資料來源,可以對各種資料流進行處理、轉換與路由)

從使用形態上Loggie可劃分為:

  • Sidecar形態:部署在每個業務容器一起,用於採集容器日誌在內的資料
  • Agent形態: 每個節點一個或者每個Pod一個,用於採集日誌或者其他資料
  • Aggregator形態: 用於中轉、轉發和處理,可獨立部署成叢集

基於簡單直接的Source → Interceptor → Sink 模型,以及多Pipeline設計,Loggie可以用在很多的場景:

  • 資料採集: 採集容器日誌、節點日誌,採集Prometheus metrics、Kubernetes Events等
  • 資料中轉: 作為中轉機去做資料的聚合、轉發、分流
  • 資料處理: 進行流式資料的切分、轉換、處理
  • 日誌報警: 進行異常日誌的檢測與報警

......

但是,這些都不重要,重要的是:

為什麼你應該瞭解一下Loggie?

Loggie是一個“麻雀雖小,五臟俱全”的專案,特別如果你是一個Gopher,日常寫Golang或者正在學習,Loggie簡直就是為你量身打造。

考慮到Loggie的使用場景,Loggie需要追求極致的輕量化、極致的效能、極致的穩定性以及可維護性。Data-intensive的各種case,在Loggie中都可能有集中的體現。

比如:

  • 佇列模型的知識:如何保證佇列裡的事務或者at least once語義?在佇列中如何實現重試、限流、去重、背壓?如何設計一個持久化佇列?
  • 外掛化設計模型:各種動態的配置(validate/defaults),各種元件的解偶與可插拔
  • 極致的效能追求:如何寫出高效能的Golang程式碼,如何做到面向GC程式設計,這其中有哪些常見的bad taste?
  • 可觀測性:Loggie致力於可觀測性的統一採集與轉發,所以這裡有prometheus metrics、openTelemetry等等。同時如何做好專案自身的可觀測性?這關係到專案是否能夠真的在線上穩定執行,以及長期執行的易用性與可維護性
  • Golang Runtime的一些入門,如何成為熟練使用pprof的一把好手,如何快速進行排障,以及在專案中怎麼做持續的profile?
  • 流式處理:Loggie是如何實現一個輕量級的流式處理功能,怎麼去實現一個簡單的帶有邏輯判斷的DSL?
  • Kubernetes Operator:這裡有分散式的Controller,可選的集中式Operator,還有自動的sidecar注入,以及基於K8s程式設計的歷史與演進
  • 各類檔案系統的知識:通過探究Loggie最常用的file source設計,以及file sink和持久化佇列,你能夠了解如何高效能的和檔案系統打交道
  • 各種中介軟體:Loggie的各種source/sink,有對各種中介軟體SDK的選型,不管是Kafka、Elasticsearch以及後續的Clickhouse, Pulsar等網紅中介軟體,你都可以找到可供參考的code example以及使用的最佳實踐
  • 自動化測試: 在Golang專案裡如何整合靜態程式碼檢查,如何做e2e、整合、Fuzz、壓測自動化測試?如何處理各種依賴的外部元件?

如果你深入瞭解Loggie後,你會發現,平時裡遇到的專案,或多或少都帶有一點Loggie的影子。因為他們都遵循資料密集型應用本質的設計,都可以參考類似的解決思路,像江湖中的某種武功絕學,我們平時練習了太多花裡胡哨的招式,卻一直沒有領悟到大師們祕而不宣的心法,Loggie可能就是那個隱藏在石碑上的口訣。

另外,如果你在某個時刻,需要進行資料的傳輸和處理,請第一時間想到Loggie,看看Loggie能不能滿足你的需求。如果不能,可以考慮一下快速開發一個Source、Sink或Interceptor元件,複用Loggie的能力,可以避免大量重複的開發工作,比如:

  • 在Kubernetes叢集中可方便、快速的使用CRD下發配置,並且支援自動reload、支援指定叢集,無需考慮部署、配置更新等問題
  • 依賴Loggie提供傳輸過程的穩定性和可靠性,保證at-least-once和重試機制,避免資料丟失,以及資料量過多或過大造成的隱患
  • 使用Loggie提供的一系列監控指標,比如佇列長度、傳輸延遲、傳送QPS等,可快速接入Prometheus,同時還可使用一些系統內建的快速排障的介面與能力
  • 使用可插拔的Interceptor可用於自定義的資料處理、格式轉換等,避免過多的定製化程式碼開發

當然,Loggie還是一個很年輕的專案,正式開源後的這段時間,每天都有很多人在問各種問題、提各種需求、給各種建議,Loggie還有太多的功能亟待研發,充滿了各種可能性,如果你感興趣,歡迎來提issues加入討論,提PR為Loggie添磚加瓦。

接下來將有一系列文章,分享我們在開發Loggie的一些思考和收穫,我挑了幾個通用的、有意思的主題組成了這個系列,姑且命名為《A byte of Loggie》,本文可為序。

所以,實際上這是一個“掛著羊頭賣狗肉”的系列,Loggie只是一個引子,引出的是在Loggie實踐中的沉澱、引申、抽象和總結。

最後,第一篇預告:《A byte of Loggie: 各式各樣的佇列及其方法論》

請加入你的延遲佇列。

相關閱讀:

雲原生日誌架構實踐:網易數帆開源Loggie的三生三世

網易X工行:雲原生日誌系統 Loggie 正式開源!

Loggie專案地址:https://github.com/loggie-io/loggie/

作者簡介: 傅軼,網易數帆 輕舟日誌平臺負責人、架構師。目前專注網易數帆輕舟雲原生日誌平臺研發,致力於雲原生技術及其生態體系建設和商業化落地,對Kubernetes、Serverless、可觀測性等有較深入研究,具有豐富的雲原生分散式架構設計開發經驗與專案實踐。