2010-12-02 121 views
2

我想捕獲多個進程的stderr和stdout,並使用python日誌記錄模塊將其輸出寫入日誌文件。下面的代碼似乎實現了這一點。目前,如果有任何數據,我會輪詢每個進程的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

你這裏的選項

  • 非阻塞I/O:這是你做了什麼:)

  • select module您可以使用poll()select()爲不同的輸入分配讀取。

  • 主題:爲要監視的每個文件描述符創建一個線程,並使用阻塞I/O。不建議大量的文件描述符,但至少它適用於Windows。

  • 第三方庫:顯然,你也可以使用Twistedpyevent異步文件訪問,但我從來沒有說......

欲瞭解更多信息,請觀看此video on non-blocking I/O with Python

由於您的方法似乎有效,如果施加的處理器負載不會影響您,我會堅持下去。如果是這樣,我會在Unix上使用select.select()

至於你關於主記錄器的問題:因爲你想開發單個輸出,你不能將所有東西都重定向到主記錄器。您必須手動執行此操作。

相關問題