Python,我应该如何记录多个子流程中的错误?

时间:2018-10-12 21:22:11

标签: python logging

我需要在Python中实现一个“主管”进程,该进程启动多个子进程并监视其运行。必须解决的任务之一是记录由它们生成的错误消息。 读完question之后,我发现了以下解决方案:

#!/usr/bin/python 
import subprocess
import threading
import time

import logging, logging.handlers

def log_subprocess_output(pipe):
    with pipe:
      for line in iter(pipe.readline, b''): # b'\n'-separated lines
        myLogger.info('got line from subprocess: %r', line)
    myLogger.info("Leaving output handler")

myLogger = logging.getLogger('MTEST')
myLogger.setLevel(logging.DEBUG)
myHandler = logging.FileHandler('log.txt')
formatter = logging.Formatter('%(asctime)s %(name)-15s %(levelname)-8s %(message)s')
myHandler.setFormatter(formatter)
myLogger.addHandler(myHandler)

myLogger.info('Test info message')
myLogger.debug('Test debug message')
myLogger.error('Test error message')
npar=[["test1","1.5","10"], 
      ["test2","1.3","20"],
      ["test3","0.8","30"]]
for pars in npar:
  # Let's start the external application
  cmd=["./ext.py",]+pars
  pd=subprocess.Popen(cmd,stderr=subprocess.PIPE)
  # Now we should start the thread (process?) reading the stderr
  th=threading.Thread(target=log_subprocess_output,args=(pd.stderr,))
  th.start()

外部应用程序在可编程的时间内生成可编程数量的人工错误消息:

#!/usr/bin/python
import sys
import time
period=float(sys.argv[2])
number=int(sys.argv[3])
for i in range(0,number):
   time.sleep(period)
   sys.stderr.write(sys.argv[1]+" "+str(i)+'\n')

提出的解决方案工作可靠(我什至已使用question中提出的HTTP连接的远程日志记录服务器对其进行了测试)。 但是,由于需要混合使用subprocessthreading模块,我不喜欢它。是否有更好的解决方案来记录来自子流程的错误消息?

1 个答案:

答案 0 :(得分:1)

之所以需要线程化的原因是,子进程的输出可以填满其输出缓冲区,这将导致其阻塞,因此永远不会终止,也不会做任何工作。您的进程可能正在忙于做其他事情,因此您必须启动一个线程以在后台读取子进程的输出,而您的进程还要执行其他工作。

如果子进程在后台运行时,如果您没有有用的工作要做,您可以调用pd.communicate(),它读取输出(使用线程,但在幕后),等待子进程,然后将输出返回给您。