【问题标题】:Python logging redirecting stdout from multiple processesPython日志记录从多个进程重定向标准输出
【发布时间】:2011-05-19 03:41:43
【问题描述】:

我正在尝试捕获多个进程的标准错误和标准输出,并使用 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)

【问题讨论】:

    标签: python logging redirect stdout pipe


    【解决方案1】:

    您的选择是

    • 非阻塞 I/O:这就是你所做的 :)

    • select module您可以使用poll()select() 为不同的输入分派读取。

    • 线程:为要监控的每个文件描述符创建一个线程并使用阻塞 I/O。不建议使用大量文件描述符,但至少它适用于 Windows。

    • 第三方库:显然,您也可以使用Twistedpyevent 进行异步文件访问,但我从来没有这样做过......

      李>

    欲了解更多信息,请观看此video on non-blocking I/O with Python

    由于您的方法似乎有效,如果施加的处理器负载不会打扰您,我会坚持下去。如果是这样,我会在 Unix 上选择 select.select()

    至于您关于主记录器的问题:因为您想打开单个输出,所以您不能将所有内容都重定向到主记录器。您必须手动执行此操作。

    【讨论】:

      猜你喜欢
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 2016-09-24
      • 1970-01-01
      • 1970-01-01
      • 2020-11-28
      • 2011-05-17
      • 2017-04-13
      相关资源
      最近更新 更多