需求:利用python的subprocess模塊結合logging模塊實現監控子程序運行狀況python
代碼以下(程序阻塞在stdout.readz這裏,日誌裏找不到hang on...................):this
import os import sys import time import subprocess import logging from logging.handlers import RotatingFileHandler todaylog = time.strftime('%Y-%m-%d', time.localtime(time.time())).decode('utf-8') LOG_PATH_FILE = "C:\my.log" LOG_MODE = 'a' LOG_MAX_SIZE = 10 * 1024 * 1024 # 10M per file LOG_MAX_FILES = 10 # 10 Files: my.1, my.2, ... LOG_LEVEL = logging.DEBUG LOG_FORMAT = "%(asctime)s %(levelname)-10s[%(filename)s:%(lineno)d(%(funcName)s)] %(message)s" handler = RotatingFileHandler(LOG_PATH_FILE, LOG_MODE, LOG_MAX_SIZE, LOG_MAX_FILES) formatter = logging.Formatter(LOG_FORMAT) handler.setFormatter(formatter) Logger = logging.getLogger() Logger.setLevel(LOG_LEVEL) Logger.addHandler(handler) pid = os.getpid() def print_error(s): print '\033[31m[%d: ERROR] %s\033[31;m' % (pid, s) def print_info(s): print '\033[32m[%d: INFO] %s\033[32;m' % (pid, s) def print_warning(s): print '\033[33m[%d: WARNING] %s\033[33;m' % (pid, s) def start_child_proc(command): try: if command is None: raise OSError, "Invalid command" #Logger.info("def start_child_proc(command, merged):") child = None child = subprocess.Popen(command, stdout=subprocess.PIPE) return child except subprocess.CalledProcessError: pass # handle errors in the called executable except OSError: raise OSError, "Failed to run command!" def run_forever(command): #print_info("start child process with command: " + ' '.join(command)) Logger.info("start child process with command: " + ' '.join(command)) child = start_child_proc(command) failover = 0 while True: while child.poll() != None: failover = failover + 1 #print_warning("child process shutdown with return code: " + str(child.returncode)) Logger.critical("child process shutdown with return code: " + str(child.returncode)) Logger.info('------------------------------------------') #print_warning("restart child process again, times=%d" % failover) Logger.info("restart child process again, times=%d" % failover) child = start_child_proc(command) # read child process stdout and log it ch = child.stdout.read() print "hang on..................." Logger.info("hang on...................") if ch != '': chlist = ch.split('\n') for chline in chlist: Logger.info(chline) Logger.exception("!!!should never run to this!!!") if __name__ == "__main__": run_forever(['python', 'test.py'])
爲何有時候可以正常運行,有時候會阻塞?查找資料找到相關解釋:rest
還有Stack Overflow上的解釋:日誌
如何解決呢?爲了防止這種狀況的發生,統一使用out, err = child.communicate()代替read()。code