Python处理程序。TimedRotatingFileHandler旋转无法正常工作

时间:2018-10-29 14:42:22

标签: python-3.x logging

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

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)

1 个答案:

答案 0 :(得分:1)

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

  

第一次(在创建处理程序时)计算下一个过渡时间时,将使用现有日志文件的最后修改时间或当前时间来计算下一个轮换发生的时间。

     

[...]

     

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

如果必须每小时( on )每小时进行一次转换,则有两种选择:

  • 创建一个初始日志文件,并将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以外的值 other ,则下一个整个间隔时间值可能会不同; 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