我正在使用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。
如何让时间戳包含微秒? 提前谢谢。
答案 0 :(得分:9)
我认为strftime()
不会直接支持%f
。记录器确实提供毫秒作为单独的msecs 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
答案 1 :(得分:3)
我没有找到一种简单的方法来打印微秒,但%(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
答案 2 :(得分:1)
我只是遇到了这个问题-它可以解决。它仅需要对某些日志记录基础架构进行一些改动。参见以下示例:
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
字段即可。
答案 3 :(得分:0)
只需完成python 3.7的@Luo_Hongshuai答案:
format=%(asctime)s.%(msecs)06f
datefmt=%Y-%m-%d %H:%M:%S