Suppose I configured logging handlers in the main process. The main process spawns some children and due to os.fork()
(in Linux) all loggers and handlers are inherited from the main process. In the example below 'Hello World'
would be printed 100 times to the console:
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()
This will print something like:
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
...
However, I don't want the child process to inherit all the logging configuration from the parent. So in the example above do_log
should not print anything to stderr
because there should be no StreamHandler
.
How do I prevent inheriting the loggers and handlers without removing or deleting them in the original parent process?
EDIT: Would it be a good idea to simply remove all handlers at the initialization of the pool?
def init_logging():
for logger in logging.Logger.manager.loggerDict.values():
if hasattr(logger, 'handlers'):
logger.handlers = []
and
pool = mp.Pool(n_cores, initializer=init_logging, initargs=())
Moreover, can I also safely close()
all (file) handlers during the initialization function?