gpt4 book ai didi

python - 在基于fork的多重处理期间,如何防止python记录器和处理程序的继承?

转载 作者:行者123 更新时间:2023-12-03 18:57:55 25 4
gpt4 key购买 nike

假设我在主流程中配置了日志处理程序。主进程产生一些子进程,由于os.fork()(在Linux中),所有记录器和处理程序均从主进程继承。在下面的示例中,'Hello World'将被打印到控制台100次:

import multiprocessing as mp
import logging


def do_log(no):
# root logger logs Hello World to stderr (StreamHandler)
# BUT I DON'T WANT THAT!
logging.getLogger().info('Hello world {}'.format(no))


def main():
format = '%(processName)-10s %(name)s %(levelname)-8s %(message)s'

# This creates a StreamHandler
logging.basicConfig(format=format, level=logging.INFO)

n_cores = 4
pool = mp.Pool(n_cores)
# Log to stdout 100 times concurrently
pool.map(do_log, range(100))
pool.close()
pool.join()


if __name__ == '__main__':
main()

这将打印如下内容:
ForkPoolWorker-1 root INFO     Hello world 0
ForkPoolWorker-3 root INFO Hello world 14
ForkPoolWorker-3 root INFO Hello world 15
ForkPoolWorker-3 root INFO Hello world 16
...

但是,我不希望子进程从父进程继承所有日志记录配置。因此,在上面的示例中, do_log不应将任何内容打印到 stderr,因为应该没有 StreamHandler

如何防止在不删除或删除原始父进程的情况下继承记录器和处理程序?

编辑:在池初始化时简单地删除所有处理程序是一个好主意吗?
def init_logging():
for logger in logging.Logger.manager.loggerDict.values():
if hasattr(logger, 'handlers'):
logger.handlers = []


pool = mp.Pool(n_cores, initializer=init_logging, initargs=())

此外,我还可以在初始化功能期间安全地 close()所有(文件)处理程序吗?

最佳答案

您不需要阻止它,只需要重新配置日志记录层次结构即可。

我认为您在使用池初始化程序的方向正确。但是,让日志记录包执行其设计的工作,而不是尝试修改内容。让日志记录程序包在工作进程中重新配置日志记录层次结构。

这是一个例子:

def main():

def configure_logging():
logging_config = {
'formatters': {
'f': {
'format': '%(processName)-10s %(name)s'
' %(levelname)-8s %(message)s',
},
},
'handlers': {
'h': {
'level':'INFO',
'class':'logging.StreamHandler',
'formatter':'f',
},
},
'loggers': {
'': {
'handlers': ['h'],
'level':'INFO',
'propagate': True,
},
},
'version': 1,
}

pname = mp.current_process().name
if pname != 'MainProcess':
logging_config['handlers'] = {
'h': {
'level':'INFO',
'formatter':'f',
'class':'logging.FileHandler',
'filename': pname + '.log',
},
}

logging.config.dictConfig(logging_config)

configure_logging() # MainProcess
def pool_initializer():
configure_logging()

n_cores = 4
pool = mp.Pool(n_cores, initializer=pool_initializer)
pool.map(do_log, range(100))
pool.close()
pool.join()

现在,工作进程将每个都记录到各自的日志文件中,并且将不再使用主进程的stderr StreamHandler。

关于python - 在基于fork的多重处理期间,如何防止python记录器和处理程序的继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29015958/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com