Logrotate成功,原始文件恢复到原始大小

Logrotate成功,原始文件恢复到原始大小

之前有人遇到过 logrotate 的问题吗?它会导致日志文件旋转,然后恢复到原来的大小?以下是我的发现:

Logrotate脚本:

/var/log/mylogfile.log {
    旋转 7
    日常的
    压缩
    旧目录 /log_archives
    missok
    通知为空
    复制截断
}

Logrotate 的详细输出:

将 /var/log/mylogfile.log 复制到 /log_archives/mylogfile.log.1
截断 /var/log/mylogfile.log
使用/bin/gzip 压缩日志
删除旧日志 /log_archives/mylogfile.log.8.gz

截断发生后的日志文件

[root@server ~]# ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 part1 part1 0 1月 11 17:32 /var/log/mylogfile.log

几秒钟后:

[root@server ~]# ls -lh /var/log/mylogfile.log
-rw-rw-r-- 1 part1 part1 3.5G 1 月 11 日 17:32 /var/log/mylogfile.log

RHEL 版本:

[root@server ~]# cat /etc/redhat-release
Red Hat Enterprise Linux ES 版本 4(Nahant 更新 4)

Logrotate版本:

[root@DAA21529WWW370 ~]# rpm -qa | grep logrotate
logrotate-3.7.1-10.RHEL4

几点说明:

  • 服务无法即时重启,因此我使用 copytruncate
  • 日志每晚都会轮换,根据olddir每晚包含日志文件的目录进行轮换。

答案1

这可能是因为即使您截断了文件,写入文件的进程仍会继续从最后的偏移量写入。因此,logrotate 会截断文件,大小为零,进程会再次写入文件,从上次的偏移量继续写入,现在您有一个文件,其中包含截断点之前的 NULL 字节以及写入日志的新条目。

od -c 截断+突然增长后,生成如下输出:

0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
33255657600  \0   C   K   B   -   s   e   r   v   e   r       [   h   t   t
33255657620 <more log output>

这说明从偏移量 0 到 33255657600,您的文件由空字节和一些可读数据组成。达到此状态所花的时间与实际写入所有那些空字节所花的时间不同。ext{2,3,4} 文件系统支持一种称为稀疏文件的东西,因此如果您搜索文件中不包含任何内容的区域,则该区域将被视为包含空字节且不会占用磁盘空间。那些空字节实际上不会被写入,只是假定存在,因此从 0 到 3.5GB 所花的时间不会花费太多。(您可以通过执行类似操作来测试所需的时间dd if=${HOME}/.bashrc of=largefile.bin seek=3432343264 bs=1,这应该在几毫秒内生成一个超过 3GB 的文件)。

如果您ls -ls在日志文件被截断后运行它,并且它再次突然增长,它现在应该在行开头报告一个数字,该数字代表实际大小(以磁盘上占用的块为单位),该数字可能比报告的大小小几个数量级ls -l

答案2

我是极其确信 Kjetil 已经成功了。Drew,你可能还不相信他的解释,但我强烈建议你仔细阅读他所说的内容。

如果您接受它,那么解决方法是,在日志轮换时停止并重新启动应用程序,或者使用 apache 的“rotatelogs”之类的工具,通过管道将日志输出提供给工具,然后该工具会负责不时轮换日志文件。例如,我的一个 apache 实例使用以下代码记录日志:

ErrorLog "|/usr/sbin/rotatelogs /www/logs/error_log 604800"

这会导致大量的日志文件名称如下

-rw-r--r--    1 root     root         4078 Dec 21 01:04 error_log.1292457600
-rw-r--r--    1 root     root         4472 Dec 29 08:41 error_log.1293062400
-rw-r--r--    1 root     root        78630 Jan  4 12:57 error_log.1293667200
-rw-r--r--    1 root     root        15753 Jan 12 01:10 error_log.1294272000

无需重新启动 apache 即可显示;然后我可以事后手动压缩它们。请注意轮换是每周进行的,即每 604800 秒,这是传递给 的参数rotatelogs

如果您无法停止并重新启动应用程序,并且无法通过管道记录,那么我认为您遇到了真正的问题。也许其他人会提出建议。

答案3

如果您可以发送整个 logrotate,那就太好了。

为什么要尝试使用 kill -HUP ?(经典的重新加载不重启) 方法。

另外...检查lsof 谁在访问该文件。

答案4

只需使用“>>”表示追加,而不是“>”,后者表示从写入此文件的脚本中创建。我遇到了完全相同的问题,我使用脚本中的追加修复了它。

SomeScript.sh >> 输出.txt

希望这更清楚一些。

相关内容