2010-12-02 1 views
2

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

Также я хотел бы иметь мастер-журнал всех отдельных процессов processese, другими словами, я хочу, чтобы автоматически (без опроса) записывал все 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

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

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

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

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

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

Для получения дополнительной информации смотрите этот video on non-blocking I/O with Python

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

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