My main program logs to its own log file and the sub-process should have its own log file. I replaced the logger object inside the multiprocessing process, but the logging data from the sub-process is additionally redirected to the main log file.
How can I prevent this?
The structure looks like this:
import logging
import sys
import os
from pathlib import Path
import multiprocessing
import time
import requests
class ProcessFilter(logging.Filter):
    """Only accept log records from a specific pid."""
    def __init__(self, pid):
        self._pid = pid
    def filter(self, record):
        return record.process == self._pid
def create_logger(file):
    log = logging.getLogger(__name__)
    log.setLevel(logging.DEBUG)
    log.addFilter(ProcessFilter(pid=os.getpid()))
    file_handler = logging.FileHandler(file)
    stream_handler = logging.StreamHandler(sys.stdout)
    formatter = logging.Formatter('[%(asctime)s] %(levelname)s [%(filename)s.%(funcName)s:%(lineno)d] %(message)s',
                                  datefmt='%a, %d %b %Y %H:%M:%S')
    file_handler.setFormatter(formatter)
    stream_handler.setFormatter(formatter)
    log.addHandler(file_handler)
    log.addHandler(stream_handler)
    return log
def subprocess_init():
    global log
    sub_log_file = str(Path.home()) + '/logfile_sub.log'
    log = create_logger(sub_log_file)
    do_subprocess_stuff()
def do_subprocess_stuff():
    count = 0
    while True:
        create_log("subprocess", count)
        time.sleep(5)
        count += 1
def main_tasks():
    num = 10
    while num > 0:
        create_log("main", num)
        time.sleep(5)
        num -= 1
def create_log(text, num):
    log.debug(text + " log %s", num)
if __name__ == '__main__':
    file = str(Path.home()) + '/logfile.log'
    log = create_logger(file)
    sub_process = multiprocessing.Process(target=subprocess_init, args=())
    sub_process.daemon = True
    sub_process.start()
    main_tasks()
Advertisement
Answer
I am simply translating this answer to fit multiprocessing.
import logging
class ProcessFilter(logging.Filter):
    """Only accept log records from a specific pid."""
    def __init__(self, pid):
        self._pid = pid
    def filter(self, record):
        return record.process == self._pid
import logging
import os
def create_logger(file):
    log = logging.getLogger('')  # why use this logger and not __name__ ?
    log.setLevel(logging.DEBUG)
    log.addFilter(ProcessFilter(pid=os.getpid()))  # logger wide filter
    file_handler = logging.FileHandler(file)
    stream_handler = logging.StreamHandler(sys.stdout)
    formatter = logging.Formatter('[%(asctime)s] %(levelname)s [%(filename)s.%(funcName)s:%(lineno)d] %(message)s',
                                  datefmt='%a, %d %b %Y %H:%M:%S')
    file_handler.setFormatter(formatter)
    stream_handler.setFormatter(formatter)
    log.addHandler(file_handler)
    log.addHandler(stream_handler)
    return log
NB. you can also put the filter on a specific handler