2017-08-28 85 views
0

我想區分失敗的進程和超時進程。 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...

+0

爲什麼不更換

process.wait(timeout=15) 

只需捕獲TimeoutExpired異常即可並在except子句中寫出你想要的消息? – Anis

+0

@Anis當然,你可以通過提供一個描述如何實現這一點的答案來幫助我嗎? –

回答

1

您可以通過

try: 
    process.wait(timeout=15) 
except subprocess.TimeoutExpired: 
    logger.error(<your error message>) 
    return 
1

剛捕獲的錯誤

try: 
    process.wait(timeout=15) 
except subprocess.TimeoutExpired as e: 
    logger.error(e) #logs the default error from subprocess.TimeoutExpired 
    logger.error("Boom") 
    return 

編輯:更加準確,記錄錯誤消息以及

+0

感謝您的幫助。只是因爲Anis速度更快,我會把它交給Anis。千鈞一髮。 –

+0

@JonathanKomar當然,他可能會更準確(subprocess.TimeoutExpired),相應地編輯我的答案,並顯示如何打印默認錯誤,如果你確實需要它。 –

相關問題