Python日志记录模块记录时间戳包括微秒

Han*_* Gu 9 python logging

我使用python的日志记录模块,但需要时间戳包括微秒.似乎时间戳只能达到毫秒级的精确度.这是我的测试代码

import logging

logging.basicConfig(format='%(asctime)s %(levelname)s {%(module)s} [%(funcName)s] %(message)s',

    datefmt='%Y-%m-%d,%H:%M:%S:%f', level=logging.INFO)

class log2_test():

    def test_class(self):

        logging.warning("Warning2 inside the class")

def get_started2():

    logging.info("Logged2 Here")

if __name__ == '__main__':
    get_started2()
Run Code Online (Sandbox Code Playgroud)

这是我得到的输出 -

2015-07-09,16:36:37:f INFO {logger} [get_started2] Logged2 Here
Run Code Online (Sandbox Code Playgroud)

不知何故,%f无法识别.Python版本是2.7.6.

如何获取包含微秒的时间戳?提前致谢.

Mar*_*ans 11

我不认为strftime()%f直接支持.记录器确实提供了毫秒作为单独的msecs 属性,因此您可以在现有时间戳之后自行添加它,如下所示:

logging.basicConfig(format='%(asctime)s.%(msecs)03d %(levelname)s {%(module)s} [%(funcName)s] %(message)s', datefmt='%Y-%m-%d,%H:%M:%S', level=logging.INFO)
Run Code Online (Sandbox Code Playgroud)

这使用您的脚本给了我以下输出:

2015-07-10,09:21:16.841 INFO {test script} [get_started2] Logged2 Here
Run Code Online (Sandbox Code Playgroud)

  • 我实际上需要像微秒一样精确. (2认同)

s-m*_*m-e 5

我刚刚遇到了这个问题 - 它可以解决。它只需要对一些日志记录基础设施进行一些黑客攻击。见下面的例子:

import logging
import time

try: # Python >= 3.7
    from time import time_ns
except: # Python <= 3.6
    from time import time as _time_
    time_ns = lambda: int(_time_() * 1e9)

class LogRecord_ns(logging.LogRecord):
    def __init__(self, *args, **kwargs):
        self.created_ns = time_ns() # Fetch precise timestamp
        super().__init__(*args, **kwargs)

class Formatter_ns(logging.Formatter):
    default_nsec_format = '%s,%09d'
    def formatTime(self, record, datefmt=None):
        if datefmt is not None: # Do not handle custom formats here ...
            return super().formatTime(record, datefmt) # ... leave to original implementation
        ct = self.converter(record.created_ns / 1e9)
        t = time.strftime(self.default_time_format, ct)
        s = self.default_nsec_format % (t, record.created_ns - (record.created_ns // 10**9) * 10**9)
        return s

logging.setLogRecordFactory(LogRecord_ns)

# +++++ DEMO +++++

log_formater = Formatter_ns('%(asctime)s (%(name)s) %(message)s')

logger = logging.getLogger('demo-log')
logger.setLevel(logging.DEBUG)

ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(log_formater)
logger.addHandler(ch)

logger.info('foo bar')
Run Code Online (Sandbox Code Playgroud)

这将愉快地打印: 2019-04-10 14:08:28,819931368 (demo-log) foo bar

关键是一个修改过的logging.Formatter类,它有一个自定义的formatTime. 为了安全起见,我还建议使用time.time_ns,它将在 Python 3.7 及更高版本中以纳秒为单位返回一个整数。原始time.time以秒为单位返回浮点数,因此显然存在精度问题。将更精确的时间戳记入日志记录是通过修改logging.LogRecord类实现的,该类只需从其扩展构造函数方法中获取其created_ns字段time.time_ns

  • @SmartManoj 将当前的 Unix 时间(以秒为单位)作为双精度(64 位)浮点数 - 它会因为数据类型的限制而截掉最后两位数字(纳秒和几十纳秒),只留下数百位纳秒(四舍五入)。距离 1970 年这个纪元越远,这样被删掉的数字就越多。 (2认同)