Systemd

如何通過file:配置正確記錄由systemd管理的服務日誌

  • January 1, 2022

我有一個由 systemd 管理的服務,它具有以下 systemd 配置,告訴 systemd 將日誌直接寫入文件(沒有 syslog 或任何東西)

StandardOutput=file:/var/log/foo/my.log

我有一個 logrotate 規則

/var/log/foo/*.log
{
       rotate 31
       daily
       missingok
       notifempty
       compress
       delaycompress
       sharedscripts
}

發生的情況是日誌正在輪換,但服務仍在寫入舊的輪換文件,而新的日誌文件保持為空。

我有一個類似的工作設置,服務改為寫入系統日誌。那個工作正常,因為 logrotate 配置有

postrotate
               invoke-rc.d rsyslog rotate > /dev/null

,它通知 syslog 其日誌已被輪換。

問題是,在我有問題的情況下,日誌直接進入文件,所以我不知道是否(或哪個)我需要向 systemd 或實際服務程序發送類似的信號。

copytruncate在 logrotate 中找到了該選項,我很確定它可以解決我的問題,但我覺得這不是理想的方法,否則copytruncate將是 logrotate 的預設行為。

我該如何解決這個問題?我需要向systemd發送一些信號嗎?我需要向服務程序發送一些信號嗎?我必須copytruncate在 logrotate 中使用嗎?

如果重要,該服務是一個使用 logback 寫入標準輸出的 java 程序

copytruncate在這種情況下是正確的答案。這不是預設設置,因為它不太常見,因為您有一個適當的守護程序,您可以發出信號以重新打開日誌文件。

另一種方法是在旋轉後腳本中重新啟動服務,但這可能不方便或不理想。

通過 systemdStandardOutput=file:打開的日誌由服務打開。您可以確認這一點lsof /var/log/mylog.log

所以輪換它取決於服務。如果服務支持在接收到某個信號後重新打開其日誌文件,那麼您只需將該信號發送到服務,而不是systemd

例如,apache 將在收到 USR1 或 HUP 後重新打開其日誌文件。所以你需要向它發送這些信號中的任何一個。

如果服務的單元文件有一個向服務發送適當信號的 ExecReload 行,那麼您可以這樣做:

systemctl reload $service

否則,您必須使用另一種方​​法,例如

kill -$signal $pid

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