需求:利用python的subprocess模块结合logging模块实现监控子程序运行情况
代码如下(程序阻塞在stdout.readz这里,日志里找不到hang on...................):
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'])
为什么有时候能够正常运行,有时候会阻塞?查找资料找到相关解释:
还有Stack Overflow上的解释:
如何解决呢?为了防止这种情况的发生,统一使用out, err = child.communicate()代替read()。