Python handlers.TimedRotatingFileHandler旋转不能像我预期的那样工作

问题描述 投票:0回答:1

我需要文件轮换才能在小时更改时发生,而不是在程序开始一小时后发生。

PS:我负责在<hour>:59:58<hour+1>:00:02写日志,以避免等待下一次写。

可能吗?

[handler_file_handler]
class=handlers.TimedRotatingFileHandler
level=INFO
formatter=formatter
delay=False
args=('logfile.log', 'H', 1, 0)
python-3.x logging
1个回答
1
投票

TimedRotatingFileHandler documentation告诉你它使用了当前时间的偏移量;唯一的例外是工作日和每日选项(W0-W6midnight),它们使用atTime作为滚动时间点:

在第一次计算下一个翻转时间时(创建处理程序时),现有日志文件的最后修改时间或当前时间用于计算下一次旋转何时发生。

[...]

如果atTime不是None,它必须是datetime.time实例,它指定翻转发生的时间,对于翻转设置为“午夜”或“特定工作日”的情况。请注意,在这些情况下,atTime值有效地用于计算初始翻转,并且后续翻转将通过正常间隔计算来计算。

如果您必须按小时,小时进行翻转,那么您有两种选择:

  • 创建一个初始日志文件,其中mtime修改值设置为最近的整个小时。然后,这将用于将当前条目写入,并且它将从设置的修改时间旋转整整一个小时。
  • 提供另一个TimedRotatingFileHandler.computeRollover() implementation,它返回下一个整个小时的时间戳,而不仅仅是当前时间+间隔。

后者可能是这里更好的道路;将当前时间舍入到最近的self.interval倍数很简单:

from logging.handlers import TimedRotatingFileHandler

class WholeIntervalRotatingFileHandler(TimedRotatingFileHandler):
    def computeRollover(self, currentTime):
        if self.when[0] == 'W' or self.when == 'MIDNIGHT':
            # use existing computation
            return super().computeRollover(currentTime)
        # round time up to nearest next multiple of the interval
        return ((currentTime // self.interval) + 1) * self.interval

这会将下一个翻转时间计算为间隔的精确倍数。考虑到如果将类的interval参数设置为1以外的值,则下一个整个间隔时间值可能不同; interval=2将选择整除2小时的整个小时,将其设置为0.5,你会看到整个半小时的旋转。

要在fileConfig configuration file中使用上述内容,只需将代码放在模块搜索路径中的模块中,然后在处理程序部分中使用class=modulename.WholeIntervalRotatingFileHandler

演示以显示下一个计算的翻转时间确实是下一个整个小时:

>>> from datetime import datetime
>>> print(datetime.now())   # current time
2018-11-17 16:48:08.793855
>>> handler = WholeIntervalRotatingFileHandler('/tmp/logfile.log', 'H', 1, 0)
>>> print(datetime.fromtimestamp(handler.rolloverAt))  # next rotation time
2018-11-17 17:00:00
© www.soinside.com 2019 - 2024. All rights reserved.