我已经在 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
从日志轮转时重新启动程序。