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


11

是否有人在使用logrotate之前遇到任何问题,然后才导致日志文件旋转,然后恢复到原来的大小?这是我的发现:

Logrotate脚本:

/var/log/mylogfile.log {
    旋转7
    日常
    压缩
    olddir / log_archives
    Missingok
    无可辩驳的
    复制截断
}

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 Jan 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 
红帽企业Linux ES版本4(Nahant更新4)

对数旋转版本:

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

一些注意事项:

  • 服务无法即时重启,所以这就是我使用copytruncate的原因
  • 根据每天晚上olddir都有日志文件的目录,日志每天晚上都在旋转。

Answers:


18

这可能是因为,即使您截断了文件,写入文件的过程仍将以最后的偏移量继续写入。因此,发生的情况是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


我不这么认为-在几秒钟内,日志文件从0字节变为3.5GB。logrotate完成的总时间约为5分钟。日志文件的写入速度并没有那么快,而且大小始终是原始大小,这似乎太巧合了。
drewrockshard 2011年

应该有一种简单的方法来验证这一点,检查文件并查看其中是否确实包含任何内容。通过运行od -c filename开始| head -n100。它可能会在几行中告诉您,有大量的空字节,以及最新的日志条目。
Kjetil Joergensen 2011年

如果是这种情况,那么我们可以测试cat / dev / null> /var/log/mylogfile.log是否以解决此问题的方式截断文件,而不是使用copytruncate中内置的logrotate?
mtinberg 2011年

2
问题不在于文件被截断的方式,而在于程序如何写入日志文件。为了将日志文件截断是一种可行的方法,您必须使程序以某种方式写入日志文件以寻求将位置0定位。不支持稀疏文件的文件系统可能没有这个问题,尽管我没有目前尚无任何测试方法。
Kjetil Joergensen 2011年

1
这个最终答案实际上更有意义,而解决方法可能最终将是重新启动应用程序。
drewrockshard 2011年

2

非常相信Kjetil做到了。德鲁,您可能还不相信他的解释,但我敦促您仔细阅读他的讲话。

如果您接受它,那么解决方法是在旋转日志时停止并重新启动应用程序,或者使用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

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


0

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

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

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


无法使用,kill -HUP因为无法以任何方式触摸此应用程序-这是我不拥有的敏感应用程序(我什至不管理它-我仅管理OS端),因此我需要能够对此进行对数旋转办法。
drewrockshard 2011年

1
抱歉,原始消息是提早提交的,这是我原始消息的其余部分:今天早上我登录到系统,并且在计划的logrotate /etc/cron.daily启动后文件现在恢复正常。对所有人的问题:logrotate脚本与手动运行logrotate相比有什么不同吗?我的logrotate脚本字面上看起来像/usr/sbin/logrotate /etc/logrotate.conf。这真是莫名其妙。
drewrockshard 2011年

-1

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

SomeScript.sh >> output.txt

希望更清楚。


没有迹象表明使用>脚本可以完成对日志文件的写入。此外,此答案令人困惑,因为脚本之间>>( )脚本之间存在重大差异。最后,如果更新编写代码,则最好在logrotate完成其工作后简单地开始写入新日志文件。
kasperd '16

我修改了答案,因此更清晰。
user578558 '16
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.