Python, как я должен регистрировать ошибки из нескольких подпроцессов? - PullRequest
0 голосов
/ 13 октября 2018

Мне нужно реализовать в Python процесс "supervisor", который запускает несколько подпроцессов и контролирует их работу.Одна из задач, которая должна быть решена, - регистрация сообщений об ошибках, сгенерированных ими.Прочитав этот вопрос , я нашел следующее решение:

#!/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')

Представленное решение работает надежно (я даже протестировал его с подключенным по HTTP удаленным сервером регистрации, представленным в этом вопросе ).Однако мне это не нравится из-за необходимости смешивать подпроцесс и поточные модули.Есть ли лучшее решение для регистрации сообщений об ошибках из подпроцессов?

1 Ответ

0 голосов
/ 16 октября 2018

Причина, по которой требуется многопоточность, заключается в том, что выходные данные дочернего процесса могут заполнять его выходные буферы, что приведет к его блокировке и, следовательно, никогда не завершится и не будет работать.Ваш процесс предположительно занят выполнением других вещей, поэтому вам нужно ускорить поток, чтобы прочитать выходные данные дочернего процесса в фоновом режиме, в то время как ваш процесс выполняет другую работу.

Если у вас не было полезной работычтобы сделать, пока дочерний процесс уходит в фоновом режиме, вы можете просто вызвать pd.communicate(), который читает вывод (используя потоки, но под капотом), ждет дочернего процесса и затем возвращает вывод вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...