删除日志文件后python记录丢失消息

Posted

技术标签:

【中文标题】删除日志文件后python记录丢失消息【英文标题】:python logging lost message after log file is deleted 【发布时间】:2021-08-14 13:13:41 【问题描述】:

我正在使用RotatingFileHandlerTimedRotatingFileHandler。在我手动删除日志文件之前一切正常。 例如,我的日志文件被写入/path/to/mylog.log。如果此文件被删除或压缩,python 将无法找到它,并且所有以后的日志消息都会丢失,尽管所有代码似乎都运行良好。

有什么方法可以同时匹配后续请求:

如果应用程序启动时文件不存在,则创建日志文件。 (我知道logging 模块已经为我做了这个) 如果应用启动后日志文件被删除,请重新创建日志文件并继续记录,无需重启应用。 日志轮换仍然像 RotatingFileHandlerTimedRotatingFileHandler 一样正常工作。

感谢@blues 的回答。我尝试了他的建议,并在这里得到了一些代码,没有经过全面测试,但它似乎可以工作。

import logging
from logging.handlers import RotatingFileHandler, WatchedFileHandler, TimedRotatingFileHandler


class WatchedRotatingFileHandler(RotatingFileHandler, WatchedFileHandler):
    def __init__(self, filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=False):
        RotatingFileHandler.__init__(self, filename=filename, mode='a', maxBytes=maxBytes, backupCount=backupCount, encoding=encoding, delay=delay)
        self.dev, self.ino = -1, -1
        self._statstream()

    def emit(self, record):
        try:
            if self.shouldRollover(record):
                self.doRollover()
            # notice reopenIfNeeded() calls os.stat
            # may cause 
            self.reopenIfNeeded()
            logging.FileHandler.emit(self, record)
        except Exception:
            self.handleError(record)


class WatchedTimedRotatingFileHandler(TimedRotatingFileHandler, WatchedFileHandler):
    def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None):
        TimedRotatingFileHandler.__init__(
            self,
            filename,
            when=when,
            interval=interval,
            backupCount=backupCount,
            encoding=encoding,
            delay=delay,
            utc=utc,
            atTime=atTime
        )
        self.dev, self.ino = -1, -1
        self._statstream()

    def emit(self, record):
        try:
            if self.shouldRollover(record):
                self.doRollover()
            # notice that reopenIfNeeded calls os.stat
            # it may cause efficiency issues
            self.reopenIfNeeded()
            logging.FileHandler.emit(self, record)
        except Exception:
            self.handleError(record)

【问题讨论】:

必须手动删除日志文件吗? 事实上,它是由我们的 Devops 团队 gzip 压缩的,因为文件可能太大了,尽管它一点也不大。他们为服务器上的所有应用程序执行此操作。 @leaf_yakitori 【参考方案1】:

您必须编写自己的 Logger 类来执行此操作。 FileHandlers 假设一旦应用程序启动,文件就不会被脚本之外的任何东西触及。

对于在应用程序运行时可以删除/移动文件的情况有一个特殊的处理程序。它是WatchedFileHandler,它是FileHandler 的一个版本,如果文件消失了,它将重新打开/重新创建文件。但是,对于旋转处理程序没有此版本。

因此,您必须将WatchedFileHandlerRotatingFileHandler 组合起来才能获得两者的功能。

【讨论】:

以上是关于删除日志文件后python记录丢失消息的主要内容,如果未能解决你的问题,请参考以下文章

Python 记录器 - 将 STDOUT 重定向到日志文件以及任何调试消息

车载程序日志出现隔几天日志中间丢失一部分数据的情况。 可能是啥原因导致?

bot删除消息Discord.py python 3.9.2时的日志记录问题

在 NLog 使用 AsyncWrapper 后大部分日志丢失

日志文件丢失

如何使用日志记录 Python 模块写入文件?