python WatchedFileHandler在轮换后仍然写入旧文件

时间:2016-02-09 17:48:07

标签: python logging rotation

我一直在使用WatchedFileHandler作为我的python日志记录文件处理程序,因此我可以使用logrotate(在ubuntu 14.04上)轮换我的日志,你知道这是文档所说的对于。我的logrotate配置文件看起来像

/path_to_logs/*.log {
        daily
        rotate 365
        size 10M
        compress
        delaycompress
        missingok
        notifempty
        su root root
}

一切似乎都运转得很好。我使用logstash将我的日志发送到我的弹性搜索集群,一切都很棒。我为我的调试日志添加了第二个日志文件,该文件被轮换但没有被logstash监视。我注意到,当该文件被旋转时,python只是继续写入/path_to_debug_logs/*.log.1并且永远不会开始写入新文件。如果我手动拖尾/path_to_debug_logs/*.log.1,它会立即切换并开始写入/path_to_debug_logs/*.log

这对我来说真的很奇怪。

我相信正在发生的事情是logstash总是拖尾我的非调试日志,有些人会在调用logrotate后触发切换到新文件。如果在没有切换的情况下调用logrotate两次,则会将log.1文件移动并压缩为log.2.gz,python无法再登录并且日志丢失。

显然,有一堆hacky解决方案(例如cronjob时不时地记录我的所有日​​志),但我觉得我一定做错了。

由于多种原因,我使用WatchedFileHandlerlogrotate代替RotatingFileHandler,但主要是因为它会在轮换后很好地压缩我的日志。

更新:

我尝试了在我的日志轮换配置脚本末尾添加手动尾部的可怕黑客。

sharedscripts
postrotate
    /usr/bin/tail -n 1 path_to_logs/*.log.1
endscript

这大部分时间都可以正常工作,但有时因为没有明确原因而随机失败,所以不是解决方案。我还尝试了一些不那么糟糕的解决方案,我已经修改了WatchFileHandler检查文件是否已更改但没有运气的方式。

我非常确定我的问题的根源是日志存储在网络驱动器上,这在某种程度上会混淆文件系统。

我用RotatingFileHandler将我的轮换移动到python,但如果有人知道处理这个问题的正确方法,我很乐意知道。

2 个答案:

答案 0 :(得分:0)

使用logrotate的copytruncate选项。来自docs

  

copytruncate

     

在创建副本后截断原始日志文件,而不是移动旧日志文件并可选地创建新日志文件,当某些程序无法被告知关闭其日志文件并因此可能继续写入时,可以使用它(永远附加到上一个日志文件。请注意,复制文件和截断文件之间的时间片非常小,因此某些日志记录数据可能会丢失。使用此选项时,create选项将不起作用,因为旧的日志文件保持不变。

答案 1 :(得分:0)

WatchedFileHandler在写入之前在日志文件中检测到设备和/或inode更改时执行翻转。也许logstash未观看的文件没有看到其设备/ inode发生变化?这可以解释为什么处理程序继续写入它。