我已經在 springboot 目錄下啟用了 logrotation,它正在工作,但我看到的是,「content-data-svc.log」實際上是 2MB,但當我執行 ls -ltrh 時,它顯示為 61MB。
如果我查看日誌文件,日誌文件中會有更多空行,因此文件大小會很大。日誌檔案的 50% 是空白空間,其餘的是日誌條目。知道為什麼會發生這種情況嗎?
[aemelics@springboot]$ ls -ltrh
total 4.6M
-rw------- 1 aemelics aemelics 1.6M Apr 11 06:44 content-data-svc.log.2.gz
-rw------- 1 aemelics aemelics 1.1M Apr 12 00:44 content-data-svc.log.1.gz
-rw------- 1 aemelics aemelics 61M Apr 12 02:00 content-data-svc.log
[aemelics@springboot]$ du -shx content-data-svc.log
2.0M content-data-svc.log
以下是我的 logrotate 條目:
[aemelics@springboot]$ cat /etc/logrotate.d/react
/logs/springboot/*.log*
{
su aemelics aemelics
missingok
daily
minsize 20M
copytruncate
notifempty
sharedscripts
compress
rotate 5
postrotate
endscript
}
答案1
該檔案在 的輸出中看起來很大,ls
但在 的輸出中看起來很小du
,並且旋轉後檔案開頭似乎有空白空間的原因是,無論程式寫入日誌檔案是不是開啟檔案以“附加”到。
當日誌檔案輪換時,使用設定檔copytruncate
中設定的選項logrotate
,將建立檔案的副本,並儲存原始文件被截斷的。當文件被截斷時,它的內容被有效刪除,但文件本身並沒有被刪除。
通常,程式會開啟檔案進行追加。這意味著對日誌的每個新寫入都發生在結尾文件的始終。當檔案被截斷時,這表示下一個日誌行將寫入檔案的開頭,因為這也是該點的結尾處。
然而,如果程序沒有以追加模式開啟文件,下一次寫入將轉到上次寫入完成的文件中的任何偏移量,無論文件是否被截斷。
如果檔案已被 截斷logrotate
,則表示寫入會在檔案的開頭和寫入發生點之間建立一個空洞。這個洞充滿了空字節,vi
編輯器將其顯示為^@
。
這就是你的情況發生的情況。
具有這種漏洞的檔案稱為「稀疏」檔案。空洞本身的空位元組實際上並沒有儲存在磁碟上,這就是為什麼du
顯示的大小相當小,但是如果你從頭到尾讀取文件,你會讀取 61M 的資料(文件的邏輯大小,即顯示什麼ls
)。
為了解決這個問題,要么
- 重寫寫入日誌文件的程序,以便以追加模式開啟文件,或者
- 告訴程式重新開放文件輪換時的日誌檔案(這通常是透過向程式發送訊號
HUP
來完成的logrotate
,但您應該閱讀程式手冊),或者 logrotate
從日誌輪轉時重新啟動程式。