Linux logrotation 文件显示的大小比平常不正确

Linux logrotation 文件显示的大小比平常不正确

我已经在 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)。

为了解决这个问题,要么

  1. 重写写入日志文件的程序,以便以追加模式打开文件,或者
  2. 告诉程序重新开放文件轮换时的日志文件(这通常是通过向程序发送信号HUP来完成的logrotate,但您应该阅读程序手册),或者
  3. logrotate从日志轮转时重新启动程序。

相关内容