使用自定义时间戳(不是当前时间戳)的 Python 日志记录

ric*_*777 4 python logging

我按以下方式使用日志记录模块:

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
                    filename=my_filename,
                    filemode='w')
Run Code Online (Sandbox Code Playgroud)

logging.info("Set up logger")
Run Code Online (Sandbox Code Playgroud)

用于写作。输出是:

2017-11-05 19:10:22,762 root      INFO     Set up logger
Run Code Online (Sandbox Code Playgroud)

问题:我想要一个过去(或未来,无论如何)的时间戳,而不是当前的时间戳。因此,每当我想在日志中写入内容时,我都可以将日期作为参数传递,如下所示:

logging.info(msg="Set up logger", date='2010-01-01 19:10:22,762')
Run Code Online (Sandbox Code Playgroud)

为了有

2010-01-01 19:10:22,762 root      INFO    Set up logger
Run Code Online (Sandbox Code Playgroud)

有什么帮助吗?

小智 6

@m1keil 的答案适用于简单的情况,但如果您想要,例如,拥有多个以不同方式格式化时间的处理程序,或者如果您不需要/想要在每次进行日志记录时指定时间,就会变得很麻烦这是一个稍微复杂一些的解决方案,但是是“更正确的方法”,并且与日志系统的正常时间戳处理集成得更好:

首先,您需要创建一个日志过滤器(过滤器能够修改通过它们所附加的记录器传递的日志记录):

class TimestampFilter (logging.Filter):
    """
    This is a logging filter which will check for a `timestamp` attribute on a
    given LogRecord, and if present it will override the LogRecord creation time
    to be that of the timestamp (specified as a time.time()-style value).
    This allows one to override the date/time output for log entries by specifying
    `timestamp` in the `extra` option to the logging call.
    """

    def filter(self, record):
        if hasattr(record, 'timestamp'):
            record.created = record.timestamp
        return True
Run Code Online (Sandbox Code Playgroud)

然后,只需创建过滤器的实例并将其添加到适当的记录器实例:

logger = logging.getLogger(__name__)
filter = TimestampFilter()
logger.addFilter(filter)
Run Code Online (Sandbox Code Playgroud)

然后,当您想要覆盖日志条目的日期/时间时,在进行日志记录调用时,请在以下位置提供时间戳extra

my_timestamp = time.time() + 86400  # Let's pretend it's tomorrow already
logger.warn("I am a warning from the future!", extra={'timestamp': my_timestamp})
Run Code Online (Sandbox Code Playgroud)