Linux

基於腳本的服務將具有優先級的消息記錄到自己的 systemd 日誌的正確方法是什麼?

  • July 17, 2020

我有一個作為 systemd 服務執行的 shell 腳本,我想將具有精細優先級的消息記錄到該服務的 systemd 日誌中。

當我使用logger(1)時, journald 只記錄一些消息並丟棄其餘消息。哪條消息最終被記錄到服務日誌中似乎是完全隨機的;有時只記錄一兩條消息,有時根本沒有記錄任何消息。

起初我認為這是一個引導順序/依賴問題,但似乎並非如此,因為所有消息都出現在系統日誌(即journalctl --system)中,但不出現在服務日誌中(即journalctl -u SERVICE.service)。我也嘗試過systemd-cat,但不幸的是它的行為相似。

基於腳本的服務將具有優先級的消息記錄到自己的 systemd 日誌的正確方法是什麼?

systemd 遇到logger的問題與它自己的systemd-notify工具遇到的問題相同。該協議是基於數據報的非同步協議,工具只做一項工作。呼叫者派生出一個程序來執行該工具;它觸發一個數據報並忘記它;並且程序退出。

systemd日誌和就緒通知協議的伺服器程序想知道發送者屬於什麼服務,前者是為了在日誌條目中添加正確的服務名稱欄位,後者是為了知道正在談論什麼服務。他們從 Linux 中獲取數據報發送者的程序 ID,然後他們去程序表中查找該程序所屬的控制組,以及它所屬的服務。

如果發送程序已完成其工作並立即退出,則這不起作用(取決於競爭條件)。程序不再在程序表中。 systemd-notify通知失敗;logger資訊不會被標記為屬於相關服務。切換到流協議(例如,使用logger--tcp選項)不會解決此問題*,除非日誌記錄協議本身也*被更改,以便客戶端在關閉流並退出之前等待來自伺服器的響應,而它沒有。RFC 5426 沒有將伺服器確認發送回客戶端。

所以日誌資訊雖然在日誌裡,但沒有打上服務名的標籤,也不會在你按服務名查詢的時候拉出來。(順便說一句,這些不是您認為的單獨日誌。 journalctl只是將過濾器應用於一個大日誌。 -u是一個過濾器。)

這是一個長期存在的、廣為人知的錯誤。

systemd人們將此描述為 Linux 的缺陷。它沒有可用於封裝和跟踪流程集的適當作業對象;AF_LOCAL它的數據報套接字機制也不傳輸此類資訊。如果這樣做,systemd可以將所有服務程序放入一個作業中,並且它的日誌記錄和就緒通知伺服器可以在收到數據報時提取客戶端作業資訊,即使客戶端程序已經退出。

有一個特定於 的特殊協議system-journald,某些版本logger甚至會說話。不,_SYSTEMD_UNIT是在伺服器端設置的“信任欄位”,客戶端設置它的嘗試將被忽略;這也是一個基於數據報的非同步協議,也沒有確認。它有完全相同的問題。

要可靠地使用正確的服務標記日誌條目,請寫入標準錯誤。這是長期存在的,並且可以更可靠地連接到伺服器端的服務單元名稱。是的,您不能指定舊的設施和優先級;這就是你必須做出的權衡。

進一步閱讀

引用自:https://unix.stackexchange.com/questions/598735