2
votes

I have the root logger that I defined with four handlers;

  • FileHandler ERROR
  • FileHandler INFO
  • FileHandler DEBUG
  • StreamHandler INFO

Now I have a module that has collects logs from multiprocesses by listening to a queue. I want this module to only log to the FileHandlers. I try to achieve that with the following code;

class ModuleLogger(Singleton):
    def __init__(self):
        # Create a queue to stash the messages
        self.queue = Queue(-1)

        # Start thread
        thread = Thread(target=self.__receive)
        thread.daemon = True
        thread.start()

    def __receive(self):
        # Keep checking the queue for new logging messages
        while 1:
            try:
                record = self.queue.get()

                # Exit on None value
                if record is None:
                    break
               
                logger = logging.getLogger(record.name)
                logger.setLevel(logging.DEBUG)

                for handler in logging.getLogger().handlers:
                    if type(handler) != type(logging.StreamHandler()):
                        logger.addHandler(handler)

                logger.handle(record)
        except Exception:
            ...
    ...

However, the messages still get logged to stdout. Though, when I print the logger.handlers it shows only the FileHandlers. So that leads to the question of this SO post; How can I make sure a logger does not use it's parents handlers?

1

1 Answers

3
votes

I think this is just a case of setting the propagate attribute on your child loggers.

https://docs.python.org/3/library/logging.html#logging.Logger.propagate

logger = logging.getLogger("my.sub.logger")
logger.propagate = False

You should only need to do this once for a specifically named child logger, and you can even set it using logging configuration upfront: https://docs.python.org/3/library/logging.config.html#module-logging.config