logrotate 日誌切割 原理

2021-10-02 23:24:54 字數 1321 閱讀 4477

logrotate 是怎麼做到滾動日誌時不影響程式正常的日誌輸出呢?logrotate 提供了兩種解決方案。

create

copytruncate

介紹一下相關的 linux 下的檔案操作機制。

linux 檔案系統裡檔案和檔名的關係如下圖。

目錄也是檔案,檔案裡存著檔名和對應的 inode 編號。通過這個 inode 編號可以查到檔案的元資料和檔案內容。檔案的元資料有引用計數、操作許可權、擁有者 id、建立時間、最後修改時間等等。檔案件名並不在元資料裡而是在目錄檔案中。因此檔案改名、移動,都不會修改檔案,而是修改目錄檔案。

借《unix 環境高階程式設計》裡的圖說一下程序開啟檔案的機制。

這也就是預設的方案,可以通過 create 命令配置檔案的許可權和屬組設定;這個方案的思路是重新命名原日誌檔案,建立新的日誌檔案。詳細步驟如下:

重新命名正在輸出日誌檔案,因為重新命名只修改目錄以及檔案的名稱,而程序操作檔案使用的是 inode,所以並不影響原程式繼續輸出日誌。

建立新的日誌檔案,檔名和原日誌檔案一樣,注意,此時只是檔名稱一樣,而 inode 編號不同,原程式輸出的日誌還是往原日誌檔案輸出。

最後通過某些方式通知程式,重新開啟日誌檔案;由於重新開啟日誌檔案會用到檔案路徑而非 inode 編號,所以開啟的是新的日誌檔案。

如上也就是 logrotate 的預設操作方式,也就是 mv+create 執行完之後,通知應用重新在新檔案寫入即可。mv+create 成本都比較低,幾乎是原子操作,如果應用支援重新開啟日誌檔案,如 syslog, nginx, mysql 等,那麼這是最好的方式。

不過,有些程式並不支援這種方式,壓根沒有提供重新開啟日誌的介面;而如果重啟應用程式,必然會降低可用性,為此引入了如下方式。

該方案是把正在輸出的日誌拷 (copy) 乙份出來,再清空 (trucate) 原來的日誌;詳細步驟如下:

將當前正在輸出的日誌檔案複製為目標檔案,此時程式仍然將日誌輸出到原來檔案中,此時,原檔名也沒有變。

清空日誌檔案,原程式仍然還是輸出到預案日誌檔案中,因為清空檔案只把檔案的內容刪除了,而 inode 並沒改變,後續日誌的輸出仍然寫入該檔案中。

如上所述,對於 copytruncate 也就是先複製乙份檔案,然後清空原有檔案。

通常來說,清空操作比較快,但是如果日誌檔案太大,那麼複製就會比較耗時,從而可能導致部分日誌丟失。不過這種方式不需要應用程式的支援即可。

tomcat日誌切割 logrotate

每天晚上,cron daemon會自動執行 etc cron.daily目錄下的任務 這個會觸發 etc cron.daily logrotate檔案,logrotate一般是隨linux按安裝的。它會執行這個命令 etc sbin logrotate etc logrotate.conf 注意空格...

logrotate切割nohup日誌大小不變

阿里雲1000元通用代金券點此領取 昨天線上伺服器磁碟報警,登入後檢視發現單個應用日誌nohup.out達到了十幾個g,明明做了logrotate日誌切割,日誌還是在不斷的增大 logrotate配置檔案如下 data tomcat log檢視 var lib logrotate.status 確實...

使用logrotate切割nginx日誌

配置 1 在 etc logrotate.d目錄下建立乙個nginx的配置檔案 nginx 配置內容如下 vim etc logrotate.d nginx usr local nginx logs log 儲存退出。2 執行logrotate usr sbin logrotate f etc lo...