如何自动在未捕获的任何异常情况下将堆栈跟踪打印到stdout?
我正在使用
pipe = subprocess.Popen(cmd, shell=False, cwd=cwd, env=env,stdout=open(pth,'w'),stderr=open(pth,'w'))
在未捕获的异常中,该文件仅包含 未处理的例外: 但我还要将跟踪写入我的日志文件。
此外,如果异常被重新加入,我想要原始跟踪
由于
答案 0 :(得分:0)
在子进程中初始化logging
模块并分配sys.stdout = LoggerFile()
。然后,子进程中未处理的任何异常都将写入您的日志文件而不是标准输出。如果您希望将其写入两者,请增强LoggerFile
类。
请注意,因为子进程是一个完全独立的解释器,具有自己独立的执行堆栈,所以子进程中发生的异常不能传播回父进程。但您可以发送编码消息来模拟它。
from functools import partial
from itertools import imap
def text_coerce(encoding):
u"given encoding returns function that takes bytes or characters and returns characters"
def decode(data):
u"if given characters returns them; if given bytes decodes them"
if isinstance(data, StringType): # really bytes
return data.decode(encoding)
else: return data
return decode
def consume(iterable):
u"consume all values from an iterable in a loop"
while True:
try:
iterable.next()
except StopIteration:
break
class LoggerFile(object):
u"a non-seekable character-based file-like object that logs all data written to it"
def __init__(self, logger=None, level=logging.INFO, encoding='UTF-8'):
if logger is None: logger = logging.getLogger()
self._encoder = text_coerce(encoding)
self._log = partial(logger.log, level)
self.writelines = partial(map, self.write)
self.close = lambda: None # pretends to close
self.flush = lambda: None # pretends to flush
self.mode = 'w'
def write(self, message):
u"write() results in exactly one log message; same for the print statement when replacing stdout"
message = self._encoder(message).rstrip()
if message != u'': self._log(message)
def writelines(self, message):
consume(imap(self.write, message.split(u'\n')))
答案 1 :(得分:0)
非常感谢所有人。 Wberry的解决方案有效,但没有必要。它只使用
工作正常f = open(pth,'w');
pipe = subprocess.Popen(cmd,shell=False,cwd=cwd,env=env,stdout=f,stderr=f)
我的问题来自redifining excepthook其他地方(因此它启用了Eclipse的断点)。我修好了它(在需要时切换到原始sys.excepthook()
。)
@patrys:我打开一次。这是一种误导性的一线捷径。道歉。