我有一个简单的脚本,它会将一堆日志输出到屏幕上,然后我将 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 进行管理。