Tomcat 運行久了,catalina.out、localhost_access_log.*.txt、*.log.* 會佔滿磁碟。本文提供**生產環境安全可用**的兩種批量清理策略:**刪除舊檔**與**截斷當前寫入檔**,並說明為何不能直接 rm 正在寫入的檔案。
# 刪除舊的輪轉日誌 (保留當前 catalina.out、localhost_log.日期.txt)
find /tomcat/logs/ -name '*.log.*' -type f -mtime +7 | xargs rm -f
# 或更精確:僅刪除 catalina.out.*、localhost.*.log 等輪轉檔
find /tomcat/logs/ \( -name 'catalina.out.*' -o -name 'localhost_access_log.*.txt' -o -name 'manager.*.log' \) -type f -mtime +7 -delete
-mtime +7:修改時間超過 7 天 (可改 -mtime +1 等)。-delete 為 find 內建動作,比 xargs rm 更安全 (處理檔名含空白/特殊字元)。catalina.out、localhost_access_log.今天.txt。catalina.out (不重啟 Tomcat 釋放空間)原理:Java/JVM 以 **檔案描述符 (fd)** 寫入日誌,**inode 不變**。truncate 或 : > file 將檔案大小設為 0,**釋放磁碟區塊**,JVM 繼續寫入同一 fd,新資料從開頭寫入,**不需重啟 Tomcat**。
# 單檔截斷
truncate -s 0 /tomcat/logs/catalina.out
# 或
: > /tomcat/logs/catalina.out
# 或
echo "" > /tomcat/logs/catalina.out
find /tomcat/logs/ -name 'catalina.out' -type f -exec truncate -s 0 {} \;
# 若有多個實例目錄
find /opt/tomcat*/logs/ -name 'catalina.out' -type f -exec truncate -s 0 {} \;
-exec truncate -s 0 {} \;:對每個找到的檔案執行截斷。truncate 屬於 coreutils,主流發行版預裝。rm catalina.out?| 操作 | inode | 磁碟空間 | JVM 寫入行為 | 結果 |
|---|---|---|---|---|
rm catalina.out | 目錄項移除,inode 計數 -1,但 **fd 仍持有 inode** → inode 不釋放 | **不釋放** (佔用空間仍在) | 繼續寫入同一 inode (已刪除檔案) | 空間不回收,df 不變,du 變小,**極難排查** |
truncate -s 0 / > file | inode 不變,**資料區塊釋放** | **立即釋放** | 繼續寫入同一 inode,從 offset 0 開始 | 空間回收,日誌連續,Tomcat 無感 |
# /etc/logrotate.d/tomcat
/tomcat/logs/catalina.out {
daily
missingok
rotate 30
compress
delaycompress
notifempty
copytruncate # 關鍵:複製後截斷原檔,JVM fd 不變
create 640 tomcat tomcat
sharedscripts
postrotate
systemctl reload tomcat > /dev/null 2>&1 || true
endscript
}
/tomcat/logs/localhost_access_log.*.txt {
daily
missingok
rotate 60
compress
delaycompress
notifempty
create 640 tomcat tomcat
}
copytruncate:複製內容 → 截斷原檔,**不需重啟 Tomcat**,完美解決 Java fd 鎖定問題。delaycompress:下一次輪轉才壓縮,方便即時排查最新日誌。
# 每天凌晨 2 點清理 7 天前舊日誌
0 2 * * * find /tomcat/logs/ -name '*.log.*' -type f -mtime +7 -delete
# 每週一凌晨 3 點截斷 catalina.out (若未用 logrotate)
0 3 * * 1 truncate -s 0 /tomcat/logs/catalina.out
**刪除舊輪轉檔**用 find -mtime +N -delete,**截斷當前寫入檔**用 truncate -s 0,**自動化輪轉**用 logrotate + copytruncate。三招組合,Tomcat 日誌永遠不會塞爆磁碟,也無需半夜起床重啟服務。