21 世紀的日志應該給與更多關注
相比較人們目前對于日志的關心,我想人們應該給予更多的關注。在設計一個應用的時候,有許多的精力都耗費在了創(chuàng)建客戶邏輯模型,確保所有用例被覆蓋并被正確處理。商務模型被映射到一個持久化存儲(是存在RDBMS或者是NoSQL解決方案中),人們挑選各種框架:web,中間件,批任務,還有可能是用log4j或logback實現的SLF4J(簡單日志門面Simple Logging Facade for Java)。
幾乎所有我參與的應用都是這樣的,日志往往都是二等公民,它依賴于良好的老的字符串日志框架。
但最近我意識到,需要日志記錄的東西遠不止目前基于字符串的日志系統(tǒng)所做的。特別是在系統(tǒng)被部署在云端,具有良好的伸縮性時,這時采集文本文件并將它們聚集到一個公共的地方,感覺就像是黑客行為。
在最近一個應用中,我們實現了一種消息機制,它具有更復雜的信息,彌補了基于字符串日志的不足。我必須要感謝與我共事的一位同事,他說“消息位于我們應用的核心”。我還未曾想過日志作為任何系統(tǒng)的核心。商務邏輯是應用的核心,而不會是日志。但他的話富含真理,因為如果不具備一個能夠知道系統(tǒng)是否確如期望而動作的好的機制,你將無法部署任何東西。
所以我的通知是比較復雜的對象(調試級通知比錯誤級通知的數據要少),NoSQL文檔數據庫是存放我們的日志的絕好存儲庫。一個通知內包含了以下所有類型的數據:
- 當前正在制定的任務,
- 數據來源,
- 發(fā)起日志的組件,
- 被拋出的異常,
- 輸入的參數,
- 承載著我們的請求的Spring Integration Message的消息歷史。
然后,既然我可以用一種“無模式”的風格來存儲復雜對象,我也就可以對日志進行查詢,而且日志到達的順序也沒有什么影響,因為我可以按照來源和創(chuàng)建時間對他們進行排序。這樣我就可以擁有一個安排好的任務,用來在監(jiān)測到大量錯誤的時候產生警告和報告。
這是一個定制的日志實現,因為我們還沒有對提醒使用專用的框架,但我從中得到了比經典的基于字符串的日志文件更多的價值。
我仍然認為log4j和logback是很棒的實現,我們還沒有替換它們,僅僅加入了一個額外的日志特征來克服它們的局限,但即使有了新的logback輸出源,我依然認為當前基于字符串的日志對于生產系統(tǒng)需求來說太簡單了。如果你使用它們更多是為了調試的目的,而且在生產環(huán)境有額外的監(jiān)控方法,那么也許是時候使用一個聰明的、可以在開發(fā)和生產環(huán)境應用的日志解決方案。
假如說10年前,當關系型數據庫統(tǒng)治著存儲世界,這是一件很難實現的事情,而基于文件日志是一個很好的折中方案。那么我認為現在我們已經有方法實現一個更好的日志框架。當前“基于String的文件日志”模型已經很有效率了,尤其是當我們的服務器垂直縮放在單個機器中。但是在一個有許多水平分布服務器的世界,這種模型需要額外的處理。
大玩家們已經使用這種新一代日志系統(tǒng)了,譬如Facebook Scribe和 LinkedIn Kafka log processing.
我真的喜歡 LinkedIn 的方案,而且他也是鼓舞著我去探尋出一個工作在CQRS時尚的新的日志系統(tǒng)。在這個日志系統(tǒng)中,日志實體像事件一樣存入日志數據庫,而且每一個事件通過一系列操作來更新當前的系統(tǒng)狀態(tài)。這個就結合了日志和監(jiān)視器,而且每個監(jiān)視命令直接緩存***的系統(tǒng)狀態(tài)呈現,這些狀態(tài)包括:
- 警報
- 狀態(tài)報告
- 監(jiān)控當前系統(tǒng)狀態(tài)的視圖
它聽起來怎么樣,是不是值得實現這個方案,我們是不是應該開啟一個新一代日志的開源項目了?