logrotate 移动文件后,如何继续将 stdout 重定向到文件?

logrotate 移动文件后,如何继续将 stdout 重定向到文件?

我有一个简单的脚本,它会将一堆日志输出到屏幕上,然后我将 STDOUT 传输到一个文件来存储日志。由于这个脚本运行时间很长,所以我需要轮换日志文件,以便将它们分成更小、更易于管理的文件。

我遇到的问题是,一旦将logrotate当前日志文件移至新文件,新创建的日志文件将不再包含日志。似乎一旦删除原始日志文件,其文件处理程序就会丢失,重定向将不再起作用。

我还发现这个帖子遇到了和我一样的问题,并声称可以通过使用>>而不是>重定向输出来解决。我测试了他的解决方案,但对我来说不起作用。有人知道如何保持重定向工作吗?

答案1

您应该在该日志文件的 logrotate 配置中使用 copytruncate 指令。

copytruncate 在创建副本后就地截断原始日志文件,而不是移动旧日志文件并选择性地创建新日志文件。当某些程序无法关闭其日志文件并因此可能继续永久写入(附加)到上一个日志文件时,可以使用此选项。请注意,复制文件和截断文件之间的时间间隔非常短,因此可能会丢失一些日志数据。使用此选项时,create 选项将不起作用,因为旧日志文件仍保留在原处

答案2

或者,您也可以:

  • 在脚本中使用记录器实用程序而不是管道,并使用专用工具(例如 local5),例如:

    logger -p local5.info -t myscriptname "this is some log data"

  • 配置 syslog 以将此功能写入所需日志文件,例如(rsyslog.conf):

    local5.* /var/log/mylogfile

  • 为此日志设置logrotate规则。

答案3

另一种 Iain 解决方案的替代方案是使用postrotate脚本在轮换完成后重新启动脚本。许多守护进程都采用此方法(重新启动或重新加载守护进程),但由于不了解您的脚本,我不知道此解决方案是否适合您(您的脚本是否依赖于一段时间前生成的某些状态?)。

内容/etc/logrotate.d/your-script-name

/var/log/your-script-name.log {
    # your current logrotate options
    ...
    postrotate
        # this supposing you have the current pid stored
        cat /run/your-script-name.pid | xargs -r kill
        #relaunch it again
        /usr/local/bin/your-script-name
    endscript
}

答案4

您可以将 stdout 管道传输到“split”(Linux 中 coreutils 的一部分)。它允许您根据大小、行数等将文件/stdin 拆分成块。一旦将其分块,您就可以根据需要使用 logrotate 进行管理。

相关内容