syslog替代者Journal詳細解讀
51CTO編者按:在前幾天的外電頭條中,我們說到紅帽的兩位開發者表示將用The Journal替換掉原本的Syslog。下面這篇是LinuxToy上翻譯的兩位開發者的原文內容,里面對The Journal的功能進行了詳細的介紹,還有一些常見問題的解答,以供參考。
Lennart Poettering 發表長篇文檔介紹 systemd 即將添加的新功能:Journal。
介紹 Journal
今天將為您介紹在過去的幾周我們在致力實現一個 systemd 的新功能。這項新功能同時將幫助我們顯著的簡化最小化安裝的 Linux 系統,同時帶來一些新的概念,也會取代一個經典 Unix 系統中的部件。因此它需要一個比較長的介紹。所以請準備好一杯熱巧克力,慢慢閱讀。
背景:syslog
長久以來 syslog 是每一個 Unix 系統中的重要部件。在漫長的歷史中在各種 Linux 發行版中都有不同的實現去完成類似的工作,它們采取的是邏輯相近,并使用基本相同的文件格式。
如其名所述,syslog 守護進程的任務是系統記錄。它從應用程序和服務中獲取格式各異的日志消息并保存到磁盤上。通常,這些消息唯一的元數據是組件名、優先級、時間戳、進程標簽和 PID。這些屬性由客戶端傳入,不經過驗證就直接原樣保存。很多這些屬性都是可選的,不同的實現中具體的格式也是有很大變化的。有個 RFC 嘗試逐漸改進和規范化消息格式,但是最重要的實現(比如 glibc’s syslog() 調用)基本無視了這些改進。
現實中,寬松的 syslog 日志消息格式帶來了靈活和強大,但同時也成為它最大的不足。因為沒有定義結構化的格式,系統的分析和日志消息處理變得十分混亂:在將其翻譯為人類語言的過程中大量與消息生成源相關的上下文都丟失了。而且還有很多日志分析器會嘗試通過分析人類語言來重構上下文。
Syslog 已經存在了差不多 30 年了,由于它的簡單和普遍,成為系統管理員的一個重要工作。但是它切實存在的局限開始導致一些嚴重的問題:
- 消息的內容無法驗證。每一個本地進程都可以聲稱自己是 Apache PID 4711,而 syslog 也就相信并保存到磁盤上。
- 數據格式散漫。自動化的日志分析器需要分析人類語言字符串來 a) 識別消息類型;b)分析其中的參數。這會導致災難性的運用正則表達式,同時也意味著需要不斷的跟進上游開發者,以免他在新版本中改變了哪怕一點點人類語言日志字符串。于是在這種方式下,為了不影響用戶自定義的正則表達式,所有的日志消息將成為軟件的 ABI,而這通常并不是開發者所期望的。
- 時間戳并不包含時區信息,盡管一些較新的實現提供對它的支持。
- Syslog 只是系統上眾多日志系統的之一。其他的日志包括 utmp/wtmp, lastlog, audit, 內核日志, 固件日志, 和很多應用程序特定格式的日志。這不僅是毫無必要的復雜,并且掩蓋了各個子系統之間日志的關系。
- 閱讀日志文件很簡單但是很低效,很多日志操作的復雜性為 O(n),進行索引基本不可能。
- syslog 的網絡協議很簡單但有限。由于它一般僅支持文件推送傳輸模式,沒有保存和轉發,所以同時有大量進程響應(Thundering Herd)或者包丟失將嚴重影響它的使用。
- 日志文件很容易被駭客篡改,容易將攻擊信息從系統管理員眼皮底下掩蓋起來。
- 沒有訪問控制。除非由系統管理員手動腳本控制,一個用戶要不然擁有日志文件的完整權限,要不就一點兒都沒有。
- 日志項目保存的元數據很有限,缺少一些關鍵信息,比如服務名、授權進程或者穩定的時間戳。
- 日志的自動化滾動是存在的,但是在大多數實現中都不甚理想:并不是持續監視磁盤使用上限,而是在固定時間點上執行滾動操作,因此遺留了 DoS 攻擊的可能。
- 在一些實現中有更新速度限制,但是一般來說并不會考慮所建議的磁盤使用和服務指派信息。
- 一般都有磁盤上日志結構的壓縮,但僅僅在滾動時生效,并且又增加了已經比較糟糕的日志操作復雜性。
- 經典的 Syslog 傳統上并不處理系統啟動早期和關機晚期的日志,盡管在最近的改進中(比如 systemd )增添了此功能。
- 無法記錄二進制數據,在一些情況下恰好是必要的(比如 ATA SMART、SCSI 數據、固件轉儲)。
很多這些問題在最近變得十分明顯,例如覺察修改了日志文件的入侵行為通常僅能靠運氣。此外,由于 syslog 的功能所限,目前部分用戶常常要依靠一些閉源的組件來處理收集到的日志信息,使其變得有意義,訪問更便捷。
日志是服務管理中關鍵的一部分。在 Unix 系統上,絕大多數的運行服務都連接到 syslog 來寫入日志消息。在 systemd 中,我們將日志做為服務管理的核心部分:從 Fedora 16 開始所有啟動的服務都將把標準輸出和錯誤輸出自動連接到 syslog 上。 不管服務是在啟動早期還是正常操作中,它的輸出結果都會保存到系統日志中。因此,由于日志如此重要,于是需要特別配置才能禁用它,將原先的“可選記錄”策略轉變為“可選不記錄”策略。信息透明不再是明智的選擇,而是默認選擇。
在開發 systemd 的過程中 syslog 的局限變得愈加明顯。例如:我們非常想添加的的一個簡化系統管理工作的功能是當使用 “systemctl status foo.service”時,在通常服務信息的下面顯示最近的 10 條日志信息。若是使用經典的 syslog 這個實現將是難以忍受的低效率、不可靠和不安全:需要對于所有日志文件的線性搜索(可能涉及實時解壓的操作),并且存儲的數據也是被修改過的,無法快捷的和 systemd 的服務名和運行環境匹配。
如果用一句話代替這些內容:傳統的 syslog 在 30 年的發展中演變成為有很多嚴重局限的強大工具。
現在,我們將如何改變這個狀況?
Journal
您可能已經從如上的描述中猜出了:我們正在開發一個解決已有日志問題,彌補以上不足并且增添了一些新功能的工具:Journal。
當然,構建一個全新的系統核心組件時,設計目標必須要明確:
- 簡單性:代碼少,依賴少,抽象開銷最小。
- 零維護:日志是除錯和監控系統的核心功能,因此它自己不能再是產生問題,在嚴酷的環境下也要能工作。舉例說,這意味著系統要合理的應對如有限磁盤空間或者 /var 不可用等問題,避免自己引發磁盤空間問題(例如在擴展日志文件時在守護進程正確的實現日志文件滾動)。
- 健壯性:由 Journal 生成的數據文件應該可以由管理員直接訪問,并且在使用 “scp” 或 “rsync” 之類的工具復制到其他主機上的時候依然可用。合理的處理不完整拷貝的情況。Journal 文件瀏覽客戶端應該可以在沒有 Journal 守護進程的情況下工作。
- 移植性:Journal 文件應該在所有類型的 Linux 系統上可用,無論它使用的何種 CPU 或者字節序。在嵌入式 ARM 系統上生成的 Journal 文件應該可以在 x86 的桌面系統上可以讀取,如同本地生成的一般。
- 性能:以復雜性為前提,添加和瀏覽 Journal 操作應該足夠快。最好實現 O(log n) 或者更快,即便在大型組織內的日志監控也有良好性能。
- 整合性:因為日志是服務的基礎之一,Journal 應該和系統的其他部分緊密的整合起來,所以需要特別的聲明才能不使用它。日志是服務管理器的核心責任,所以應該通過整合來反映這一點。
- 最小資源占用:Journal 數據文件需要較小,特別是和經典的 syslog 生成的數據相比時。
- 通用的事件存儲:Journal 應該可以用來進行任何 Journal 條目的存儲,無論其格式、元數據還是大小。
- 統一化:各種不同的日志存儲技術應該統一起來,將所有的可記錄事件保存在同一個數據存儲中。所以 Journal 內容的全局上下文都會被保存并且可供日后查詢。例如一條固件記錄后通常會跟隨一條內核記錄,最終還會有一條用戶態記錄。重要的是當保存到硬盤上時這三者之間的關系不會丟失。
- 高級別工具的基礎:Journal 應該提供一個通用的 API ,以便狀態監控器、恢復工具、崩潰報告生成器和其他高級別的工作來訪問 Journal 數據。
- 擴展性:和 Linux 的適用范圍從嵌入式設備跨越到超級計算機集群一樣,Journal 也應該可以有廣泛。日志對于開發嵌入式設備和維護集群一樣重要。為了保持較小占用,Journal 需要著重于常見的一般使用模式,同時對于一些特定的變化做一定考量。
- 通用性:做為操作系統的基礎模塊,Journal 應該可以通用,并能擴展以滿足于一些應用程序特定的需求。格式應該是可擴展的,并且提供 API。
- 集群和網絡:今日計算機很少是獨立工作的了。所以有必要從 Journal 文件和工具的設計初始就考慮對于多主機安裝配置的支持。
- 安全性:Journal 文件應該是可以驗證的,讓無法檢測的修改不再可能。
說了很多設計目標,下面是一些我們實現過程的技術概覽,并介紹新系統是如何工作的:
受 udev 事件啟發,Journal 條目與環境組塊相似。一個鍵值域,按照換行符分開,使用大寫的變量名。和 udev 設備事件和真實環境組塊相比,有一個主要不同:盡管毫無疑問主要值會是 ASCII 格式的字符串,也支持以二進制為值 -- 某些情況下可以用來添加 ATA SMART 健康信息、SCSI 數據、內核轉儲或固件轉儲。由代碼生成的 Journal 條目可以包含多個域,既可以是已知的類型,也可以是服務/子系統/驅動特定的。
應用程序和服務可以通過將項目域傳遞給 systemd journald 服務來生成項目。該服務可以為項目增加一定數量的元數據。這些受信任域的值由 Journal 服務來決定且無法由客戶端來偽造。一旦牽扯到硬件和內核設備,Journal 服務將為日志項目添加從 udev 數據庫獲得的當前設備信息,其中包含了所有設備名和符號鏈接,以及與 Journal 條目關聯的其他設備數據。
由 Journal 守護進程添加的域將具有下劃線前綴(“_”), 用來標示該區域是可信的,而不是由未知客戶端提供的。應用程序自身無法傳遞以下劃線開頭的的域名稱。這是一個樣例展示在客戶端傳輸基礎上添加內容的日志條目展示:
_SERVICE=systemd-logind.service MESSAGE=User harald logged in MESSAGE_ID=422bc3d271414bc8bc9570f222f24a9 _EXE=/lib/systemd/systemd-logind _COMM=systemd-logind _CMDLINE=/lib/systemd/systemd-logind _PID=4711 _UID=0 _GID=0 _SYSTEMD_CGROUP=/system/systemd-logind.service _CGROUPS=cpu:/system/systemd-logind.service PRIORITY=6 _BOOT_ID=422bc3d271414bc8bc95870f222f24a9 _MACHINE_ID=c686f3b205dd48e0b43ceb6eda479721 _HOSTNAME=waldi LOGIN_USER=500
該樣例條目是由 systemd logind 守護進程在用戶 “harald” 登錄時創建的。如您所見它自動添加了相當復雜的數據,包括一些重要的執行進程參數。更加詳細的定義的域說明請參考:
原生的 Journal 文件格式從經典的日志文件和 Git 倉庫獲得啟發。它被設計來只將日志數據添加到末尾(用來保證基于 mmap() 的訪問的健壯和原子性),以及一些在用來反映新添加內容的文件頭元數據變更。這些用來組成項目的域以獨立對象的方式保存在 Journal 文件中,當需要時被項目所引用。這將節省大量的磁盤空間,因為日志項目通常會有很多的重復(試想:每個本地的消息都會包含相同的HOSTNAME= 和 MACHINE_ID= 域)。數據域還會被壓縮來節省磁盤空間。直接效果就是盡管 Journal 相比經典的 Syslog 明顯記錄了更多的元數據信息,但是磁盤占用卻無明顯變化。
磁盤上使用特定的 64位 LE(從小到大)偏移,目的是簡化操作并保證我們可以存儲大小可觀的二進制數據。日志瀏覽工具和 journald 之間的無需同步,需要瀏覽 Journal 文件的客戶端可以簡單的使用 mmap() 訪問文件,并使用文件變化通知來告知更新。
提供用于客戶端訪問 Journal 文件的庫,用來實現對項目任意域的索引,以及通過單調化或者時序化時間戳的隨機訪問。客戶端庫會自動合并多個 Journal 文件使其看起來好像是一個統一的 Journal 項目流。這用來隱藏底層細節譬如已經歸檔的文件,或屬于多個用戶的 Journal 文件。在瀏覽接口上透明化的 Journal 文件合并是完全動態的:當創建新的 Journal 文件或者刪除舊的文件時都會自動更新瀏覽視圖。事實上,Journal 瀏覽期望做到即時性的,從而實現對 Journal 來源的實時監控。
從非特權登錄用戶發來的消息將按照每用戶分割為獨立的 Journal 文件。使用 POSIX ACL 來實現讀取權限控制,保證用戶可以訪問他自己的 Journal 文件。系統服務生成的 Journal 條目默認情況下無法被一般用戶訪問,除非他們屬于一個特殊的 Unix 用戶組。值得注意的是文件的分割是用來協助合適的訪問控制的,但是全局的上下文并未因此丟失。客戶端會通過所有消息強制按照統一的排序的方式將 Journal 文件合并起來,從而保證自動分配的序列號碼的全局順序。這意味著可以在不影響用戶條目上下文的情況下實現訪問控制。
Journal 的核心思路就是統一目前所用的各類日志記錄技術。因此它將成為 wtmp 的替代品,啟動早期記錄器甚至授權記錄后端。數據將從各種不同的來源生成:printk() 生成的內核消息,syslog(3) 生成的用戶態消息,使用原生 API 生成的用戶態條目,通過 /proc/proc/sys/kernel/core_pattern 生成的核心轉儲及更多。以后我們希望能有固件消息(UEFI 日志)的鉤子,并擴展基于內核的日志來支持內核中結構化日志。因為在 Journal 數據結構中所有的域都是隱式的索引過的,所以跟 wtmp 相比從 Journal 的中提取用戶數據是個很簡單的操作。啟動早期和運行時日志時統一的。只要 /var 不可用,所有的 Journal 條目便會自動保存在 /run 下,等待 /var 可用時再立刻寫入。這意味著最終所有系統生成的消息,不管是在 POST 中由固件,還是在內核初始化,啟動早期還是運行時,都將保存到索引的 Journal 文件中。
為了讓條目可以被客戶端工具識別出來,Journal 條目可選包含一個 128 位的標示符,由生成消息的服務設定于 MESSAGE_ID= 中。這個 ID 應該由開發者在開發過程中隨機生成的。例如,一個 ID 表示“用戶登出”而另外一個 ID 表示“用戶登入”。所有這些事件的條目都分別包含 128 位的 ID,因此將很容易辨識出來并索引。這個 ID 完全可以和 RFC4122 UUID 類型四保持兼容,但是這嚴格的來說并不需要故也不強求。該設計會和其他采用 UUID 標示消息類型的日志系統保持兼容,比如 UEFI 固件日志。考慮到128 位 ID 的全局錯誤代碼的隨機本質,它們并不需要一個集中式的標準化機構來為某個特定的消息類型指定 ID。指定消息 ID 是完全可選的,我們認為只要少量的 Journal 的條目會包括它,比如那些需要被用戶態識別出來的部分。如果一個開發者需要為他新引入的消息類型指定一個新 128 位 ID 的話,只需要運行 “cat /proc/sys/kernel/random/uuid” 即可,它會在每次運行的時候返回一個新的 UUID。這 128 位的 ID 亦可用于實現本地化的消息 UI,按照他在 UI 工具中尋找翻譯過的消息,然后呈現給用戶。
所有的條目都用現實時間和單調時間打上時間戳。為了使單調時間戳有意義,所有的消息同時也包含運行的 Linux 內核的啟動 ID (比如 /proc/sys/kernel/random/boot_id)。精確度是 1 微妙,現實時間采用 UTC 計時以避免遭受和 syslog 類似的時區問題。
Journal 文件可以回滾、刪除、復制到其他機器、合并或者更改。為了保證應用程序、同步公布和網絡服務可靠的識別條目,所有 Journal 條目都可以用一個指針字符串標識。一個這樣的字符串可以標識一個特定的消息,甚至在條目丟失或不可用時也保持不變,于是可以用來定位最近的下一個條目。
如果超過某個限額的話,journald 會自動回滾 Journal 文件。這被內建在磁盤空間分配的邏輯中,目的是避免單純基于時間回滾的漏洞。回滾不僅考慮最大磁盤利用限制,并且還將監視通常的磁盤使用水平來保證磁盤上至少預留有一定空間。
由客戶端發送的條目隱含的受到速率限制,避免未信任的客戶端通過大量發送自身數據的方式沖掉 Journal 中的相關數據。這個速率依照可用磁盤空間調整,于是在磁盤空間富裕的時候速率會高些,而磁盤空間低時將會強制為較低的速率。
在初始版本的 journald 中對于網絡支持會非常簡陋:要在網絡中分享 Journal 文件的話,使用比如 scp、rsync 或者 NFS 復制到一個集中化主機上。Journal 瀏覽器客戶端將會透明化的合并這些文件,如果需要的話進行交叉存儲。在稍候的版本中我們計劃最低限度的擴展 Journal 來支持實時遠程日志,通過用本地 Journal 文件做為緩存的存儲-轉發邏輯來實現 PUSH 和 PULL 兩種模式。不管使用何種模式,Journal 的底層格式設計適用于擴展到大規模主機環境,所有的條目都會用機器 ID 和主機名來標示。目的是實現一種有效的 Journal 監控工具完成透明化、實時的多重主機日志瀏覽任務,并且留給管理員按照自己需要調整傳輸方式的空間,比如是否實時功能比避免大量進程響應(Thundering Herd)更重要等。
互聯網是個險象叢生的地方。對于重要網站的入侵已經變得愈加常見。在成功的滲透之后,攻擊者通常會通過編輯日志文件的方式掩藏他的蹤跡。 這類修改在傳統的 syslog 下很難檢測:因為它用的是沒有加密認證的純文本,所以無法獲知變更。從 Git 中獲得啟發,Journal 中的所有條目都是加密哈希過的,且在文件中包含先前條目的哈希值。這樣的結果是一個條目鏈,每一個條目都可以認證之前的全部。如果最頂端的哈希通常都保存在一個只讀的位置,整個鏈條都可以通過它認證。檢測攻擊者的修改將變得十分容易。
如上所述日志是服務管理的必要部分。這不僅意味著服務本身的日志輸出將傳遞到 Journal,并且將為額外的服務事件生成 Journal 條目,比如當服務開始、錯誤推出、停止或崩潰之時。
Journal 的守護進程 journald 首先將取代目前 systemd 分發的兩個日志相關迷你守護進程(systemd-kmsg-syslogd and systemd-stdout-syslog-bridge)。長期目標是在多種安裝配置中取代傳統的 syslog 守護進程,而不造成沖突。由于運行服務的減少(由 3 降為 1)以及相比全尺寸的 syslog 守護進程少很多代碼的 journald,Linux 系統的資源消耗將會減低。
當前狀態
目前為止,核心的功能和和全部重要的算法已經實現并放置在 systemd git 的 Journal 分支中。但是代碼目前還不完善,缺少一些上面提到的功能。
這篇博文是用來澄清一些社區中對于我們計劃、選擇和原因的誤解。
我們計劃在 Fedora 17 中初步實現,不過在首次亮相中只選擇與極少幾個部件關聯。rsyslog 會和它一起運行,用戶可能會很難注意到它,除了 “systemctl status” 將會顯示所有服務的最近日志信息,以及嘗試使用我們的客戶端工具,比如 “journalctl” 來搜索索引的 Journal 時。
常見問題及回答
我們一直在和不同知識背景的人討論,收集想法、建議和批評。有一些問題經常被重復提到,下面就是我們的回答:
Journal 很酷,但是 systemd 很糟糕。我可以不用 systemd 而單獨使用 journald 么?
不行。日志是服務管理的核心部分。Journal 和 systemd 緊密結合從而保證系統的每一個部分都可以監控,查詢和除錯。生成的 Journal 項目是從 systemd 的不同部分查詢出來的。實際上,systemd 和 journald 是如此緊密耦合以至于拆分開的舉動毫無意義。不過正如所說,這是自由軟件,您可以隨自己愿望修改代碼。最后,您認為 systemd 很糟糕的想法是錯誤的。
運行 Journal 會破壞 rsyslog/syslog-ng 么?
不會。您可以同時運行 rsyslog 或 syslog-ng 及 journald,syslog 消息會雙雙記錄在 rsyslog/syslog-ng 和 Journal 中。但是,Journal 將記錄一些純文本的 syslog 所不具備的豐富元信息。
我的應用程序需要在磁盤保存傳統的純文本日志。我可以配置 Journald 生成么?
不能。如果您需要這樣做的話,只要和 Journal 同時運行一個傳統的 syslog 實現如 rsyslog, 即可幫助您生成想要的文件。
為什么 Journal 不生成傳統的日志文件?
簡單來說,傳統的日志文件無法索引,并且其速度隨著復雜度按照函數 O(n) 降低。原生的 Journal 文件格式下關鍵操作速度隨著復雜度按照 O(log(n)) 降低,性能更佳。更多原因請參考上面章節。
我可以連接一個 syslog 協議兼容的遠程 RFC 到 Journal 么?
在目前您不可以,并且 Journal 也不太可能會默認支持這個。但是編寫一個可行的轉換器或者網關應該不困難。
我在嵌入式設備上使用 systemd 于是對永久性保存日志不感興趣,我可以移除 Journal 么?
不可以。但是您可以告訴 systemd 您不需要永久性日志。通過移除(或者一開始就不創建)/var/log/journal 目錄,在這種情況下 journald 僅會將記錄到 /run/log/journal (如同在早期啟動的情況下)。/run 是臨時的并且會在重啟時丟失,和 /var 不同。在此之上您可以將 Journal 使用的最大磁盤空間設置為一個很小的值。
人人都說 UUID 是有問題的。為何還要用 UUID 來表示消息呢?
UUID 規格的確是奇形怪狀且不必要的復雜。因此我們推薦只要和 UUID 類型4保持一致即可,不用理會 RFC 4122。實際上 UUID 已經在 Linux 上成功的應用了很長時間,所有發行版默認都是依據文件系統 UUID 來執行掛載的。
但是 UUID 從來沒正常工作過!比如 MAC 地址是重復的并且所有我的 USB 設備都使用的同一個。為什么要堅持使用它呢?
我們實際上一直在使用它,比如像上面說的在文件系統中,它工作的很好。硬件都包含有序列號,不少廠商初始化為 1-2-3-4-5,但是它和 UUID 沒什么關系。設備序列號并不是 UUID,不要混淆!
另外,我們并沒有強制使用它們。如上所述它是完全可選的,并且只需要并賦予到需要后來識別出來的消息上即可。
但我在代碼中引入了一個 UUID 來標識一個消息類型,其他人使用了該段代碼做為別的工作的模板,那么 Journal 就會壞掉了。
不,這不對。為什么?很簡單,因為同樣的 128位 ID 將會用來指定同一個錯誤/條件/項目類型,不管來源是什么。比如同樣的 128位 ID 將會用來標識“在塊設備上存在壞扇區”,而不管是哪個設備或驅動器生成了這個消息。如果用戶態軟件需要在不同的服務、驅動或設備之間區分開 Journal 項的話,請使用其他額外的匹配服務/設備/驅動的 Journal 信息域。
不過從另一個角度講,您指出的實際上是個好事情。我們特別鼓勵人們在他們的軟件中重用消息 ID,而不是創造新的。
但是 printf()/printk() 格式化字符串是標識消息類型的更好選擇!
現實并不是這樣的。格式化字符串到頭來不過只是人類語言的模板。將人類語言用于消息類型識別是不可靠的:每個修正的錯誤拼寫都會影響消息類型,并且導致 Journal 客戶端識別消息錯誤。每次對一個 Journal 消息進行擴充或者重寫的時候,將會導致 ABI 破壞。讓人類語言變為 ABI 是致命的錯誤。事實上,將所有消息類型變為 ABI 的方式在經典的正則表達式匹配條件下風險很大。OTOH 消息標識可以在改變人類語言字符串時保持不變,因此很好的將 ABI 和人類語言分割開了。
你們一點兒都不懂!你們應該使用源代碼文件名和位置作為消息的標識符!
這并不可行,因為這將使源代碼位置變為 ABI:問一次開發者在頭文件中增加一行將導致全部消息 ID 的改變。這將是個大問題。
誰會來組織和管理 UUID 的命名空間并生成 UUID?Who would organize and manage the UUID namespace and generate UUIDs? 認真點兒,我們不需要更多官僚機制的人!
128 位隨機 ID 的好處之一就是它的命名空間并不需要管理。所有人都可以從 /proc/sys/kernel/random/uuid 里取出一個隨機 UUID 為他所用。只要需要,開發者可以生成任意多的 UUID 而不需要詢問任意集中管理體制。UUID 允許我們擁有一個共同點的命名空間而無需官僚機制。
但是 UUID?你是認真的么?你是哪個星球來的!?人人都知道像 LANANA 這樣的中介是為應用程序指定全球唯一消息標識 ID 的理想選擇!
Linux 并不是一個孤島。我們需要在 Journal 中與其他基礎架構中所使用消息 ID 無縫整合起來。因此我們選擇了有用途的并且已經在他處實踐過的。同樣,UUID 只不過是為了無需集中管理的唯一標識符。為什么要在沒必要的時候選擇一個人手不足的官僚的集中注冊中心的?
喏,你應該使用逆序的域名表示消息類型,像 Java 一樣!
實質上,比較字符串要比比較固定長度的 ID 更加復雜。并且,實事求是的說這不能解決命名空間的問題,因為估計有 90% 的消息類型將在同個命名空間內:org.freedesktop resp. org.kernel.
但是 ASN.1 OID 可以成為很好的消息類型區分符!
兄弟,沒搞錯吧?
現在我有了更好的主意,不如用 URL 做為類型 ID 吧?
實際上相比逆序域名的方式它并未好多少,不是么?
但是如果你們在每個項目上都要生成一個 UUID 的話,很快便會窮盡我的熵池的!
再度一遍博文,很顯然您并沒有仔細閱讀。 128 位的消息 ID 是由開發者在開發過程中指定的,并不是在運行時。大多數項目在整個開發過程中幾乎不可能生成超過 30 個,這個數量哪怕在 10 年前的機器的熵池中都是微不足道的。
你們這些用戶態的小屁孩們,先是強迫我在系統中使用 20 個 CPU 進程分組,現在又要強迫我在系統中使用惡心的 UUID?
先不談我們并沒有強迫您使用 20 個進程分組的事實,您幾乎肯定已經在使用 UUID 了,因為您的文件系統是在啟動過程中依據 UUID 加載的。將這些當作是實現的具體細節,而您并不喜歡它,那么您就沒必要在消息中添加它。影響的只是消息無法被再度識別,除非使用極度復雜的正則表達式。不過或許這就是您想要的?無論怎樣,我們沒有強迫任何人做任何事。
所以你們是依照發送用戶的 ID 來分割 Journal 項目的了。那么你怎么能保證用戶不會偽裝身份呢?
幸運的是,Linux 內核支持 SCM_CREDENTIALS,可以提供我們無法偽造的消息發送者信息。
Journal 文件格式會標準化么?哪里可以找到磁盤上數據結構的說明?
截至目前我們還沒有打算要將格式其標準化,保留在需要時進行變更的權力。我們會逐步完善磁盤上格式的文檔,但是目前我們不希望能有程序直接讀取、寫入和修改 Journal 文件。對其的訪問可以通過一個共享庫和命令行程序實現。(不過再一次,這是自由軟件,您隨時可以閱讀源代碼!)
為什么你們這些人又搞重復發明?為什么不只把你們想要的增加到已有的 syslog?如果您只想清理日志格式的話,syslog 足夠了。
有些情況下改進現有方案是一種方式,但是當需要的變化太大時,有正確的原因并且對以前解決方案提供了良好的兼容性的重新發明卻是更好的選擇。我們相信我們有著正確的原因,并且我們在努力提供最大可能的兼容性。
不,僅僅修復日志格式沒法帶來很多變革。不僅無法實現最基本的二進制文件或敏感的結構化日志,也沒有索引或者訪問控制。
是不是 Journal 將完全拋棄 syslog ?
不,首先,syslog API syslog(3) 作為寫入日志的第一級別接口被支持,并且將持續用作主要的簡單文本日志 API。但是只要元數據(特別是二進制元數據)被加入到條目中,便會轉而使用原生的 Journal API。
其次,Journal 是個全新的產物。從另一個方面說,Syslog 是一個工業標準(盡管是定義的相當孱弱,日志格式幾乎都沒有統一),并且被廣泛接受,存在于為數眾多的操作系統、應用程序和設備中。因此,syslog 依然是很重要的并且將繼續存在于許多安裝配置中。Journal 守護進程并不使用 RFC syslog 協議,將來也不太可能會。當需要一個 syslog 兼容協議的地方,依然需要使用經典的 syslog 實現方案。為了保證此項工作,我們確保 Journal 的實現可以和本地的 syslog 守護進程協作,且將需要的消息轉發給 syslog,使其可以像如同沒有 journald 中介一般的工作。
需要您的加入!
在決定這個設計之前,我們了解一些高負荷的日志用戶,包括那些擁有超過 100 臺活躍主機的用戶。我們也和一些可能成為主要 Journal 用戶的工程師聊過。我們對于使用慣例和擴展性問題尤其感興趣。但是,每一個安裝配置都有自己的需求,因此,如果您在上面的設計描述中看到了某個用于您特定需要的重要功能沒有實現的話,我們希望您能和我們去的聯系。上面的設計著重于日志記錄的底層。目前我們并不負責特定的 UI,所以如果有這方面的需求話請稍候再留下意見。另外,現在還沒到圣誕節,因此我們無法實現所有愿望(請不要失望),但是我們很在意的去了解它們,甚至可以保證至少我們會去考慮它們!先謝過了!
消息來源:Phoronix
【編輯推薦】