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

2024-03-28 21:46:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用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()

这是我得到的结果--

2015-07-09,16:36:37:f INFO {logger} [get_started2] Logged2 Here

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

如何使时间戳包含微秒? 提前谢谢。


Tags: 模块testimportinfogethereloggingdef
3条回答

我认为strftime()不会直接支持%f。不过,记录器提供毫秒作为单独的毫秒attribute,因此您可以在现有时间戳之后自己添加它,如下所示:

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)

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

2015-07-10,09:21:16.841 INFO {test script} [get_started2] Logged2 Here

我刚碰到这个问题-而且可以解决。它只需要对一些日志基础设施进行一些黑客攻击。请参见以下示例:

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')

这将很高兴地打印: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获取到日志记录中更精确的时间戳。

我没有找到一个简单的方法来打印微秒,但是%(created).6f可能是一个临时解决方案,这将是time.time()的结果,就像1517080746.007748

没有办法删除不必要的部分,所以如果你真的需要微秒,但不想改变你的代码太多, 一个简单的方法是

logging.basicConfig(level=logging.INFO,format="%(asctime)s.%(msecs)03d[%(levelname)-8s]:%(created).6f %(message)s", datefmt="%Y-%m-%d %H:%M:%S")

它会给出低于输出的结果

2018-01-28 04:19:06.807[INFO    ]:1517080746.807794 buy order issued
2018-01-28 04:19:07.007[INFO    ]:1517080747.007806 buy order issued
2018-01-28 04:19:07.207[INFO    ]:1517080747.207817 buy order issued
2018-01-28 04:19:07.407[INFO    ]:1517080747.407829 buy order issued
2018-01-28 04:19:07.607[INFO    ]:1517080747.607840 buy order issued

相关问题 更多 >