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


22

我有一个简单的脚本,可以将大量日志输出到屏幕,然后将STDOUT通过管道传输到文件中以存储日志。由于此脚本运行时间很长,因此我需要旋转日志文件,以便将它们丢到更小,更易于管理的文件中。

我面临的问题是,一旦logrotate将当前日志文件移动到新的日志文件中,新创建的日志文件就不再填充日志了。似乎一旦删除了原始日志文件,它的文件处理程序就会丢失并且重定向将不再起作用。

我还发现此帖子与我有同样的问题,并声称可以使用>>而不是>重定向输出来修复它。我测试了他的解决方案,但对我来说不起作用。有谁知道如何保持重定向工作?


4
如果您要写入截断的文件,我仍然建议您使用“ >>”而不是“>”:因为以追加模式打开的“ >>”会一直查找到文件末尾每次写。这样,当您截断文件(使其从XXXX字节变为0字节)时,它将“搜索到结束”,因此将知道它现在必须在字节0之后写入。否则,它可能在字节XXXX之后写入,因此创建一个带有XXXX空字节的稀疏文件(例如,当“>”时,fd只能记住该文件在该文件中的位置,然后从那里写入,而不会意识到文件大小缩小了!)
Olivier Dulac 2014年

Answers:


25

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

copytruncate在创建副本后,将原日志文件截断到位,而不是移动旧日志文件并有选择地创建新的日志文件。当无法告知某些程序关闭其日志文件时,可以使用它,从而可能永远永久地写入(附加)以前的日志文件。请注意,复制文件和截断文件之间的时间间隔非常短,因此某些日志记录数据可能会丢失。使用此选项时,创建选项将无效,因为旧的日志文件保留在原位


2
可能值得一提:在短时间内,在compress操作之前,数据已被复制。那一次给我们带来了一个问题,但是那是我们的坏处,因为我们不应该那么接近lv空间极限。另外,如man代码片段所述,您可能会在复制和截断操作之间丢失一些日志数据。
Belmin Fernandez 2014年

6

或者,您也可以:

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

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

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

    local5.* /var/log/mylogfile

  • 为此日志设置logrotate规则。


仅当您具有显式的输出命令(如)时,此方法才有效echo。从脚本调用的第三方工具的输出以及某些输出也无法通过这种方式重定向到记录器
Daniel Alder 2015年

4

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
}

0

您可以将stdout传递给“ split”(Linux中coreutils的一部分)。它允许您根据大小,行数等将文件/ stdin分成多个块。一旦将其分成块,则可以根据需要使用logrotate对其进行管理。

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.