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