How to check if a logger exists
Asked Answered
G

2

18

I've had to extend the existing logging library to add some features. One of these is a feature which lets a handler listen to any existing log without knowing if it exists beforehand. The following allows the handler to listen, but does not check if the log exists:

def listen_to_log(target, handler):
    logging.getLogger(target).addHandler(handler)

The issue is that I don't want any handler to listen to a log which isn't being logged to, and want to raise a ValueError if the log doesn't already exist. Ideally I'd do something like the following:

def listen_to_log(target, handler):
    if not logging.logExists(target):
        raise ValueError('Log not found')
    logging.getLogger(target).addHandler(handler)

So far I have been unable to find a function like logging.logExists, is there such a function, or a convenient workaround?

Glucinum answered 3/11, 2018 at 8:40 Comment(2)
There is a dict you could check, see here: code.activestate.com/lists/python-list/621740 but it is undocumented, I think.Cornell
That's perfect, I'd be happy to accept if you provide it as answerGlucinum
S
34

Workaround that works for me and possibly you:

When you create a logger for your own code, you will almost certainly create a logger with handlers (file handler and/or console handler). When you have not yet created a logger and you get the 'root' logger by

logger = logging.getLogger()

then this logger will have no handlers yet. Therefore, I always check whether the logger above results in a logger that has handlers by

logging.getLogger().hasHandlers()

So I create a logger only if the root logger does not have handlers:

logger = <create_my_logger> if not logging.getLogger().hasHandlers() else logging.getLogger()

The "create_my_logger" snippet represents my code/function that returns a logger (with handlers).

Scurvy answered 5/3, 2020 at 15:46 Comment(3)
this is also useful in concurrent logging where loggers may survive process reuse.Sawyer
"When you create a logger for your own code, you will almost certainly create a logger with handlers". Yes, in that case your method works. For instance, logging.basicConfig does it for you. On the other hand, if you previously created a logger without a specified name and without any handlers, you cannot distinguish it from a new, similarly created logger. The reason is that the root logger is not stored in the logging.Logger.manager.loggerDict dictionary, as @Cornell points it out in his answer.Secularism
If you are using < Python 3.2, you can use len(logger.handlers) instead of logger.hasHandlers()Laterite
C
18

WARNING. This is not documented. It may change without notice.

The logging module internally uses a single Manager object to hold the hierarchy of loggers in a dict accessible as:

import logging
logging.Logger.manager.loggerDict

All loggers except the root logger are stored in that dict under their names.

There are few examples on the net: http://code.activestate.com/lists/python-list/621740/ and https://michaelgoerz.net/notes/use-of-the-logging-module-in-python.html (uses Python 2 print)

Cornell answered 4/11, 2018 at 7:10 Comment(1)
I do think this should never change, since the names are not _manager or _loggerDict, but that is up to the maintainer.Glucinum

© 2022 - 2024 — McMap. All rights reserved.