![如何在退出前修復 systemd 日誌記錄最後幾行的單位屬性?](https://rvso.com/image/89156/%E5%A6%82%E4%BD%95%E5%9C%A8%E9%80%80%E5%87%BA%E5%89%8D%E4%BF%AE%E5%BE%A9%20systemd%20%E6%97%A5%E8%AA%8C%E8%A8%98%E9%8C%84%E6%9C%80%E5%BE%8C%E5%B9%BE%E8%A1%8C%E7%9A%84%E5%96%AE%E4%BD%8D%E5%B1%AC%E6%80%A7%EF%BC%9F.png)
我有一個記錄到標準輸出的 systemd 服務。從那裡,systemd 捕獲 STDOUT 並將其寫入日誌。
我使用一個常見的習慣用法來處理錯誤,其中我進行echo
一些診斷,然後以非零錯誤代碼退出:
echo "my final error";
exit 1;
我的問題是,這最後echo
一行出現在日記中,但與我的「單位」沒有正確關聯。透過查看journalctl -o json-pretty
,我可以看出有什麼區別。最終日誌記錄缺少屬性 _SYSTEMD_CGROUP 和 _SYSTEMD_UNIT。
我認為正在發生的是一種競爭條件。我懷疑 bash 腳本journald
在進入退出行之前不會等待完全處理。因此,在處理完日誌條目exit
之前就到達了該行。嘗試尋找發送日誌記錄的日誌,但現在找不到它,因為該裝置不再運行。journald
journald
unit
sleep 1
如果我是對的,我可能可以通過在我的聲明之前解決這個問題exit 1
,但是有沒有更好的方法來獲得最終的日誌屬性?
systemd
我在 Ubuntu 16.04 上使用版本 229。
答案1
@mark-stosberg,這是一個已知問題:由於 /proc 與 SCM_CREDS 競爭,journald 無法將從退出的進程傳入的訊息歸因於其 cgroup
您可以在那裡找到解決方法:https://github.com/systemd/systemd/issues/2913#issuecomment-219702148
將進程名稱設定為傳送到日誌系統或核心日誌緩衝區的日誌行的前綴。
並運行
journalctl _SYSTEMD_UNIT=unit + UNIT=unit + SYSLOG_IDENTIFIER=id
答案2
我研究了一下這個,看來是systemd 的已知問題,有一個拉取請求。
此修復涉及快取服務的元數據,以便即使服務已退出,其元數據仍然可用於正確對最後幾個日誌進行分類。
它也被認為是CoreOS 的開放錯誤,它使用 systemd。
該錯誤也在 systemd freedesktop.org 錯誤追蹤器上進行了跟踪,如下所示:
進一步測試發現,遺失日誌歸屬的問題更加嚴重使用者單位——我認為這是一個單獨的問題。為了系統單位,競爭條件相對較小,並且sleep 1;
在服務腳本中的退出之前添加可以在列印的最後一個日誌和退出之前添加足夠的填充來解決問題。