我正在尝试调试我所依赖的large库的行为,该库在其许多源文件中使用了分散的调试打印语句(没有过多使用)。麻烦的是,大多数(如果不是全部的话)所有这些调试打印语句都不包含日期/时间戳,因此很难将应用程序级别的故障与库代码本身内的故障相关联。
而不是修改所有怀疑与我看到的故障有关的调试打印的源代码,我认为有可能临时对内置的Python打印“功能”进行猴子补丁,以便所有输出均以时间戳作为前缀。
由于我正在使用的Python 2.6环境中的built-in print is not a function,所以我不知道这是否可行。如果有人使用Python的另一个钩子做到了这一点或获得了相似的结果,那么我将很感谢您的建议,甚至会为解决该问题提供更好的代码。
由于您无法覆盖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]
时间戳记是开始(前置)而不是结束(附加)的替代解决方案:
old_out = sys.stdout
class St_ampe_dOut:
"""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 = St_ampe_dOut()
我不确定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()