15

我正在尝试调试我所依赖的大型库的行为,该库通过其许多源文件使用分散的调试打印语句(不会过多)。问题是,如果不是所有这些调试打印语句,大多数(如果不是全部)都不包含日期/时间戳,因此很难将应用程序级别的故障与库代码本身的故障联系起来。

与其修改所有怀疑与我所看到的故障有关的调试打印的源代码,我认为可以临时修补内置的 Python 打印“函数”,以便所有输出都带有前缀时间戳。

由于内置的​​ print 不是我正在使用的 Python 2.6 环境中的函数,我不知道这是否可能。如果有人这样做或使用 Python 中的另一个钩子实现了类似的结果,那么我将不胜感激您的建议,或者甚至更好的代码来解决这个问题。

4

3 回答 3

26

由于您无法覆盖该write函数(它是只读的),因此一个简单的猴子补丁可能如下所示(将时间戳附加到每个打印行):

old_f = sys.stdout
class F:
    def write(self, x):
        old_f.write(x.replace("\n", " [%s]\n" % str(datetime.now())))
sys.stdout = F()

一个示例如下所示:

>>> print "foo"
foo [2011-02-03 09:31:05.226899]
于 2011-02-03T08:33:31.813 回答
9

时间戳是开始(附加)而不是结束(附加)的另一种解决方案:

from datetime import datetime as dt 

old_out = sys.stdout

class StAmpedOut:
  """Stamped stdout."""
    
  nl = True
  
  def write(self, x):
    """Write function overloaded."""
      if x == '\n':
        old_out.write(x)
        self.nl = True
      elif self.nl:
        old_out.write('%s> %s' % (str(dt.now()), x))
        self.nl = False
      else:
        old_out.write(x)
    
sys.stdout = StAmpedOut()
于 2014-07-19T14:04:07.510 回答
0

我不是 100% 清楚 Velizar 的现有答案如何处理输出与多个 \n 一起发送的情况。我不确定它是否可靠地工作,如果确实如此,我认为它可能依赖于输出流的潜在无证行为。

这是我的解决方案,它在每个打印行的开头添加时间戳,并在没有 \n 的情况下可靠地处理多行/行:

import time
import sys

class TimestampFilter:
    # pending_output stores any output passed to write where a \n has not yet been found
    pending_output = ''
    def write(self, message):
        output = self.pending_output + message
        (output, not_used, self.pending_output) =  output.rpartition('\n')
        if output != '':
            timestamp = time.strftime("%Y-%m-%d %X")
            output = timestamp + " " + output.replace("\n", "\n"+timestamp+" ")
            print(output, file=sys.__stdout__)
            sys.__stdout__.flush()

sys.stdout = TimestampFilter()
于 2019-02-12T11:43:29.330 回答