Обработчики Python. Поворот TimeTotRotatingFileHandler не работает, как я ожидал - PullRequest
0 голосов
/ 29 октября 2018

Мне нужно, чтобы ротация файлов происходила точно при смене часа, а не через час после запуска программы.

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 голосов
/ 17 ноября 2018

Документация TimedRotatingFileHandler сообщает, что используется смещение от текущего времени; единственными исключениями являются параметры дня недели и дня (W0-W6 и midnight), которые используют atTime в качестве момента времени для пролонгации:

При вычислении времени следующего ролловера в первый раз (при создании обработчика) время последней модификации существующего файла журнала или текущее время используется для вычисления, когда произойдет следующее вращение.

[...]

Если atTime не является None, это должен быть экземпляр datetime.time, который указывает время дня, когда происходит опрокидывание, для случаев, когда опрокидывание происходит «в полночь» или «в определенный день недели». ». Обратите внимание, что в этих случаях значение atTime эффективно используется для вычисления начального ролловера , а последующие ролловеры будут рассчитываться с помощью обычного интервала.

Если вам нужно, чтобы переходы выполнялись ежечасно, на час, тогда у вас есть два варианта:

  • Создайте исходный файл журнала со значением модификации mtime, установленным на самый последний целый час. Затем он будет использоваться для записи текущих записей и будет вращаться целый час с установленного времени изменения.
  • Предоставляет альтернативную TimedRotatingFileHandler.computeRollover() реализацию , которая возвращает метку времени для следующего целого часа, а не только текущее время + интервал.

Последний, вероятно, лучший путь здесь; округление текущего времени до ближайшего 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 файле конфигурации , просто поместите код в модуль, который находится в пути поиска модулей, а затем используйте 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...