Python日志记录:覆盖日志时间

4

根据Python文档,我正在尝试覆盖logging.Formatter.converter以控制记录的时间。
如下所示-毫秒未被覆盖(它们是当前时间的毫秒数)。

为什么?我如何同时控制毫秒数?

>>> import logging, datetime
>>> formatter = logging.Formatter('%(asctime)s:%(message)s')
>>> handler = logging.StreamHandler()
>>> handler.setFormatter(formatter)
>>> def sim_time(t):
...     return datetime.datetime(2000,1,2,3,4,5,678).timetuple()
...
>>> formatter.converter = sim_time
>>> log = logging.getLogger('test')
>>> log.addHandler(handler)
>>> log.info('hi')
2000-01-02 03:04:05,898:hi
>>> log.info('hi')
2000-01-02 03:04:05,914:hi
>>> log.info('hi')
2000-01-02 03:04:05,434:hi
3个回答

3

覆盖logging.Formatter.formatTime(),使用以下内容:

def sim_time(record, datefmt=None):
    return datetime.datetime(2000,1,2,3,4,5,678).strftime('%Y-%m-%d %H:%M:%S,%f')[:-3]

formatter.formatTime = sim_time

如果您需要在此进程中的所有记录器中使用它,则可以覆盖类函数本身,但请在代码遇到第一个import logging语句后立即执行此操作:

def sim_time(self, record, datefmt=None):
    return datetime.datetime(2000,1,2,3,4,5,678).strftime('%Y-%m-%d %H:%M:%S,%f')[:-3]

import logging
logging.Formatter.formatTime = sim_time

1

timetuple() 不使用毫秒,因此一旦调用该方法,datetime 对象中包含的毫秒信息将会丢失:

>>> d
datetime.datetime(2000, 1, 2, 3, 4, 5, 678)
>>> d.timetuple()
time.struct_time(tm_year=2000, tm_mon=1, tm_mday=2, tm_hour=3, tm_min=4, tm_sec=5, tm_wday=6, tm_yday=2, tm_isdst=-1)

请注意,这不是该特定方法的限制,而是time.struct_time type的限制。
底线是:如果您需要覆盖时间戳,请勿通过time.struct_time对象传递。例如,您可以传递已格式化为字符串的时间戳,而不是虚假时间。当然,根据您的需求可能有更好的方法!

0

这里有一个更好的例子,允许您替换生成的时间,因为接受的答案并没有真正做到这一点。

def inSimulatedTime(self,secs=None):
    global myTimeKeeper
    try:
       ts=myTimeKeeper.getCurrentTimeLocal() # returns a datetime.datetime object
       return ts.timetuple()
except Exception as e:
    #sometimes my timekeeper hasn't been initialized yet.
    return time.localtime(secs)

启用它:

logging.Formatter.converter=inSimulatedTime

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接