如何检测Python子进程中的超时是否已经达到?
我想区分失败的进程和超时进程。 Python 确实捕获错误并清楚地标识它。这很好,但没有雪茄,因为我想写我自己的日志消息,对应于超时错误。请参阅下面的我目前的实施和我想要的解释。如何检测Python子进程中的超时是否已经达到?
如果程序是这样的:
#!/usr/bin/env python3
"""
My job is to demonstrate a problem detecting timeout failures.
"""
import os
import sys
import logging
import subprocess
import time
# Create main (root) logging object
logger = logging.getLogger('{}'.format(__file__))
logger.setLevel(logging.DEBUG)
# Formatter
consoleh = logging.StreamHandler(sys.stdout)
consoleh.setLevel(logging.INFO)
console_formatter = logging.Formatter('%(asctime)s %(name)s PID: %(process)d TID: %(thread)d %(levelname)s \n ==> %(message)s',datefmt='%Y-%m-%d at %H:%M:%S.%s')
consoleh.setFormatter(console_formatter)
logger.addHandler(consoleh)
def preHook(script):
logger.debug('preHook called.')
command = "{}".format(script)
logger.info('preHook Executing with 15 second timeout: \n /bin/sh -c {}'.format(command))
process = subprocess.Popen(command,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)# timeout in seconds
process.wait(timeout=15)
proc_stdout, proc_stderr = process.communicate()
if process.returncode == 0:
logger.info('preHook: Process complete: \n Command: /bin/sh -c {}\n STDOUT: "{}"\n STDERR: "{}"\n Exit Code: {}\n at: {}'.format(command,proc_stdout.decode('utf8').strip(),proc_stderr.decode('utf8').strip(),process.returncode,time.time()))
else:
exitcode = 1
logger.error('preHook: Process failed: \n Command: /bin/sh -c {}\n STDOUT: "{}"\n STDERR: "{}"\n Exit Code: {}\n at: {}'.format(command,proc_stdout.decode('utf8').strip(), proc_stderr.decode('utf8').strip(),process.returncode,time.time()))
def main():
preHook('find -type f')
if __name__ == "__main__":
main()
我如何能赶上超时错误,并在标准错误输出写入相关的消息?
控制台输出
Python的子进程包明显捕获超时错误。
2017-08-28 at 09:44:57.1503906297 detecttimeout.py PID: 16915 TID: 140534594959104 INFO
==> preHook Executing with 15 second timeout:
/bin/sh -c find -type f
Traceback (most recent call last):
File "detecttimeout.py", line 40, in <module>
main()
File "detecttimeout.py", line 37, in main
preHook('find -type f')
File "detecttimeout.py", line 28, in preHook
process.wait(timeout=15)
File "/home/USER/devel/python/Python-3.4.5/Lib/subprocess.py", line 1561, in wait
raise TimeoutExpired(self.args, timeout)
subprocess.TimeoutExpired: Command 'find -type f' timed out after 15 seconds
我想赶上超时,就像我做失败的过程。为了实现捕获失败的进程,我使用逻辑中显示的返回代码。消息preHook: Process failed...
发生。我想再发一条消息:preHook: Process timed out...
。
您可以通过
try:
process.wait(timeout=15)
except subprocess.TimeoutExpired:
logger.error(<your error message>)
return
刚捕获的错误
try:
process.wait(timeout=15)
except subprocess.TimeoutExpired as e:
logger.error(e) #logs the default error from subprocess.TimeoutExpired
logger.error("Boom")
return
编辑:更加准确,记录错误消息以及
感谢您的帮助。只是因为Anis速度更快,我会把它交给Anis。千钧一发。 –
@JonathanKomar当然,他可能会更准确(subprocess.TimeoutExpired),相应地编辑我的答案,并显示如何打印默认错误,如果你确实需要它。 –
为什么不更换
只需捕获TimeoutExpired异常即可并在except子句中写出你想要的消息? – Anis
@Anis当然,你可以通过提供一个描述如何实现这一点的答案来帮助我吗? –