為什麼你應該瞭解 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、可觀測性等有較深入研究,具有豐富的雲原生分佈式架構設計開發經驗與項目實踐。