copytruncate 實際是如何工作的?
在使用以下配置
copytruncate
旋轉文件之前, 我們想了解一下:logrotate
/app/syslog-ng/custom/output/all_devices.log { size 200M copytruncate dateext dateformat -%Y%m%d-%s rotate 365 sharedscripts compress postrotate /app/syslog-ng/sbin/syslog-ng-ctl reload endscript }
RHEL 7.x,8GB 記憶體,4 個 VCpu
問題:
logrotate
當 syslog-NG 已經打開文件進行日誌記錄時,如何截斷文件?不是資源爭奪嗎?syslog-NG 是否會在沒有任何要記錄的內容時立即關閉文件?
截斷日誌文件實際上是有效的,因為編寫者使用 O_APPEND 打開要寫入的文件。
從open(2)手冊頁:
O_APPEND:文件以追加模式打開。在每次 write(2) 之前,文件偏移量位於文件末尾,就像使用 lseek(2) 一樣。文件偏移量的修改和寫入操作作為單個原子步驟執行。
如前所述,操作是原子的,因此每當發出寫入操作時,它將附加到與文件末尾匹配的目前偏移量,而不是在前一個寫入操作完成之前保存的偏移量。
這使得在截斷操作之後追加工作,將下一個日誌行再次寫入文件的開頭,而無需重新打開文件。
(O_APPEND 的相同功能還可以讓多個寫入者附加到同一個文件,而不會破壞彼此的更新。)
記錄器還使用單個 write(2) 操作寫入日誌行,以防止在截斷或併發寫入操作期間將日誌行分成兩部分。
請注意,像 syslog、syslog-ng 或 rsyslog 這樣的記錄器通常不需要使用
copytruncate
,因為它們支持重新打開日誌文件,通常通過向它們發送 SIGHUP。logrotate 對存在的支持copytruncate
是為了迎合其他記錄器,這些記錄器通常附加到日誌文件,但不一定有重新打開日誌文件的好方法(因此在這些情況下通過重命名進行輪換不起作用。)另請注意,它
copyrotate
具有固有的競爭條件,因為在 logrotate 完成複制之後和發出截斷操作之前,作者可能會在日誌文件中附加一行。這種競爭條件會導致它永遠失去那些日誌行。copytruncate
這就是為什麼通常不推薦使用旋轉日誌的原因,除非這是唯一可行的方法。