在使用时间旋转记录器创建的每个日志文件上写一个标题

时间:2015-01-08 12:24:32

标签: python logging

我制作了一个时间旋转的记录器,它在午夜创建了一个新的日志文件。在我的日志文件中,我想在每个文件的顶部写一个标题。我正在寻找一种有效的方法来调用一个函数,该函数在创建文件时将此头写入日志文件。

import logging
from logging.handlers import TimedRotatingFileHandler

# create time-rotating log handler
logHandler = TimedRotatingFileHandler(logfile, when='midnight')

# create logger
self.log = logging.getLogger('MyTimeRotatingLogger')
self.log.addHandler(logHandler)

3 个答案:

答案 0 :(得分:7)

我已经解决了!基本上所有需要做的就是覆盖doRollover的{​​{1}}方法,在这个新的父类中也需要一些代码来传递日志记录实例并设置标题内容。对于遇到类似情况的人来说,这是一个广泛的例子。

TimedRotatingFileHandler

答案 1 :(得分:1)

上面的解决方案涵盖了大多数用例,但是如果您仍然想尊重FileHandler.delay属性的行为,我认为最简单的解决方案是覆盖_open()方法:

class MyTimedRotatingFileHandler(TimedRotatingFileHandler):
    def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None, header=''):
        self.header = header
        super().__init__(filename, when, interval, backupCount, encoding, delay, utc, atTime)
    def _open(self):
        stream = super()._open(self)
        if self.header and stream.tell() == 0:
            stream.write(self.header + self.terminator)
            stream.flush()
        return stream

这样,您可以避免以仅包含标题的“空”日志文件结尾,而不必担心将特定的记录器传递给处理程序。

答案 2 :(得分:0)

为了在第一个日志文件中也有标头,我建议对您的解决方案进行略微修改。即,对定义了标题后立即写头的代码段进行了额外的调用,并在记录器设置中交换了一些行(请参见代码中的注释):

from logging.handlers import TimedRotatingFileHandler

class MyTimedRotatingFileHandler(TimedRotatingFileHandler):
    def __init__(self, logfile, when, interval):
        super(MyTimedRotatingFileHandler, self).__init__(logfile, when, interval)
        self._header = ""
        self._log = None

    def write_header(self):
        if self._log is not None and self._header != '': 
            self._log.info(self._header)

    def doRollover(self):
        super(MyTimedRotatingFileHandler, self).doRollover()
        self.write_header()

    def configureHeaderWriter(self, header, log):
        self._header = header
        self._log = log
        self.write_header()     # WRITE HEADER TO FIRST FILE

# create time-rotating log handler
logHandler = MyTimedRotatingFileHandler(logfile, when='midnight')
form = '%(asctime)s %(name)s %(levelname)s: %(message)s'
logFormatter = logging.Formatter(form)
logHandler.setFormatter(logFormatter)

# create logger
log = logging.getLogger('MyLogger')

# CONFIGURE LOG LEVEL AND ATTACH HANDLER TO LOGGER **BEFORE** SETTING THE HEADER
log.setLevel(logging.INFO)
log.addHandler(logHandler)  

logHandler.configureHeaderWriter('test-header', log)