我对 logrotation 的观察是,要轮换任何日志文件,logrotate 进程应按以下顺序运行
- 复制有问题的日志文件(我们称之为 file1.log),并使用新名称(在现有名称中添加时间戳或数字,使其成为 file1.log-20140513),
- 删除现有文件(file1.log)并创建一个具有原始名称的新空白日志文件(file1.log),
- 压缩旋转的文件(file1.log-20140513),如果设置了压缩选项,则会创建一个新的压缩文件(file1.log-20140513.gz),
- 删除轮换文件 (file1.log-20140513),最后,
- 移动到下一个文件并对其执行相同的上述 4 个步骤。
我在此过程中遇到以下问题:
- 我的日志文件非常大(每个超过 10 Gb),我有大约 42 个这样的日志文件。
- 写入这些文件的进程同步工作,
- 服务器上的 DiskIO 很好,但是复制仍然需要时间,压缩也需要时间并且压缩也会消耗 CPU。
- 我希望所有新创建的日志文件都从同一时间开始记录日志。
为此,我希望 logrotate 移动 mv 命令执行的一些操作,即重命名文件而不是复制文件。至于压缩,我可以禁用它并通过 cron 安排的另一个脚本触发它。但我希望 logrotate 移动文件而不是复制文件。
现在,我确信这也是 logrotate 的作者会想到的事情,因为它显然节省了磁盘 IO 和完成整个 logrotate 操作所需的时间,所以我想知道为什么要复制文件而不是移动或重命名文件,以及如何通过 logrotate 实现这一点。
注意:我尝试手动执行此操作,即移动正在运行的进程正在写入的文件,并创建一个具有相同名称和相同权限(即 root,这也是进程运行时的权限)的新空白文件,但在移动和创建新文件后,我发现进程没有向其中写入任何内容,因此必须重新启动该进程才能使其写入该文件。有人可以解释这种行为吗,为什么 logrotate 设法使进程写入同一个文件,但我无法使用简单的步骤。
答案1
您所描述的行为仅在通过指令明确指示 logrotate 执行此操作时才会发生copytruncate
。文档警告此行为可能会丢失一些日志数据。该指令应仅作为最后的手段使用。
轮换日志文件的标准方法是重命名,然后向进程发送信号,让其打开新的日志文件。这种方法速度更快,而且不会有丢失部分日志的风险。但它要求写入进程能够切换到新的日志文件。
可以关闭压缩或将其推迟到下一次轮换。如果compress
使用该指令,则旧日志文件将被压缩。如果不使用该指令,则不会压缩它们。
如果同时使用compress
和delaycompress
,则压缩将延迟到下一次轮换。这样,每次轮换后,两个最新的日志文件将尚未被压缩。
答案2
移动并创建新文件后,我发现该过程没有向其中写入任何内容,因此必须重新启动该过程才能使其写入该文件
进程正在写入同一个文件,这就是为什么 lograte 复制而不是移动的原因。当您删除日志时,进程仍会写入日志,您可以看到文件系统使用率在增长,但没有文件。进程重新启动将释放磁盘空间。
考虑
- 少写日志,所有记录的信息都是必要的吗?
- 阅读文档,例如:http://www.thegeekstuff.com/2010/07/logrotate-examples/