Журнал Python, перенаправляющий стандартный вывод из нескольких процессов - PullRequest
2 голосов
/ 02 декабря 2010

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

Также я хотел бы иметь основной журнал всех отдельных процессов процессов, другими словами, я хочу автоматически (без опроса) записать все stdout / stderr для каждого процесса в главный журнал. Это возможно?

Спасибо

class MyProcess:
def __init__(self, process_name , param):
    self.param = param
    self.logfile = logs_dir + "Display_" + str(param) + ".log"
    self.args = [process_name, str(param)]
    self.logger_name = process_name + str(param)
    self.start()
    self.logger = self.initLogger()

def start(self):
    self.process = Popen(self.args, bufsize=1, stdout=PIPE, stderr=STDOUT) #line buffered
    # make each processes stdout non-blocking
    fd = self.process.stdout
    fl = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)

def initLogger(self):
    f  = logging.Formatter("%(levelname)s -%(name)s - %(asctime)s - %(message)s")
    fh = logging.handlers.RotatingFileHandler(self.logfile, maxBytes=max_log_file_size, backupCount = 10)
    fh.setFormatter(f)

    logger = logging.getLogger(self.logger_name)
    logger.setLevel(logging.DEBUG)
    logger.addHandler(fh) #file handler
    return logger

def getOutput(self): #non blocking read of stdout
    try:
        return self.process.stdout.readline()
    except:
        pass

def writeLog(self):
    line = self.getOutput()
    if line:
        self.logger.debug(line.strip()) 
        #print line.strip()



process_name = 'my_prog'
num_processes = 10
processes=[]

for param in range(num_processes)
    processes.append(MyProcess(process_name,param))

while(1):
    for p in processes:
        p.writeLog()

    sleep(0.001)

1 Ответ

1 голос
/ 02 декабря 2010

Ваши варианты здесь

  • Неблокирующий ввод / вывод: Это то, что вы сделали:)

  • Модуль select : Вы можете использовать poll() или select() для отправки показаний для разных входов.

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

  • Сторонние библиотеки : Очевидно, вы также можете использовать Twisted или pyevent для асинхронного доступа к файлам, но я никогда не делал этого .. .

Для получения дополнительной информации смотрите видео о неблокирующем вводе / выводе с Python

Поскольку ваш подход, похоже, работает, я бы просто придерживался его, если наложенная загрузка процессора вас не беспокоит. Если это произойдет, я бы пошел на select.select() на Unix.

Что касается вашего вопроса о главном логгере: поскольку вы хотите отключить отдельные выходы, вы не можете перенаправить все на мастер логгер. Вы должны сделать это вручную.

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