<p>我刚碰到这个问题-而且可以解决。它只需要对一些日志基础设施进行一些黑客攻击。请参见以下示例:</p>
<pre class="lang-py prettyprint-override"><code>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')
</code></pre>
<p>这将很高兴地打印:<code>2019-04-10 14:08:28,819931368 (demo-log) foo bar</code></p>
<p>关键是一个修改过的<code>logging.Formatter</code>类,它有一个自定义的<code>formatTime</code>实现。为了安全起见,我还建议使用<code>time.time_ns</code>,在Python 3.7及更高版本中,它将以纳秒为单位返回一个整数。原始的<code>time.time</code>以秒为单位返回一个浮点值,因此显然存在精度问题。通过一个修改过的<code>logging.LogRecord</code>类将其<code>created_ns</code>字段从其扩展构造函数方法中的<code>time.time_ns</code>获取到日志记录中更精确的时间戳。</p>