close

How to use logging.getLogger(__name__) in multiple modules

Hello Guys, How are you all? Hope You all Are Fine. Today We Are Going To learn about How to use logging.getLogger(name) in multiple modules in Python. So Here I am Explain to you all the possible Methods here.

Without wasting your time, Let’s start This Article.

Table of Contents

How to use logging.getLogger(name) in multiple modules?

  1. How to use logging.getLogger(name) in multiple modules?

    The naming of the loggers is what you are missing. In the example, a logger named spam_application is created in the main module. Then handlers and formatters are created and added to that logger.

  2. use logging.getLogger(name) in multiple modules

    The naming of the loggers is what you are missing. In the example, a logger named spam_application is created in the main module. Then handlers and formatters are created and added to that logger.

Method 1

The logger hierarchy must be defined explicitly in the logger name, using dot-notation. That is, if the logger name in main_module.py is e.g. 'a', then the logger name in auxiliary_module.py must be 'a.b' (not just 'b'), in order for it to inherit the configuration of logger 'a'. This is also mentioned in the getLogger() documentation.

However, this should be taken care of automatically when using __name__, as noted in the logging how-to:

This means that logger names track the package/module hierarchy, and it’s intuitively obvious where events are logged just from the logger name.

The thing is, for this to work, you need to use __name__ in the correct way, and I did not do that.

The problem in my example is in the organization of the files in the cookbook-example package folder:

Both the main module and the auxiliary module are at the same level (i.e. in the same folder). So, as explained here, the __name__ for the main module will then be '__main__' (as it is the top-level script), and the __name__ for the auxiliary module will be 'auxiliary_module' (i.e. the filename), NOT '__main__.auxiliary_module'.

As a result, the logger in the auxiliary module will be a child of the root logger, not a child of the '__main__' logger, and it will thus inherit the root logger configuration (which still has the default logging level WARNING) instead of the configuration specified in the main module.

So, to make the example work, we have several options:

  1. Replace getLogger(__name__) in the main module by getLogger(). This will apply the config to the root logger and therefore also to the auxiliary module logger, as suggested by @shmee.
  2. Replace getLogger(__name__) in the auxiliary module by getLogger('__main__.' + __name__). The result will be equivalent to the original cookbook-example (except that the main logger is now called '__main__' instead of 'spam_application').

Method 2

The naming of the loggers is what you are missing. In the example, a logger named spam_application is created in the main module. Then handlers and formatters are created and added to that logger.

In auxiliary_module loggers are created with names that start with spam_application resp. spam_application.auxiliary. This effectively creates a hierarchy of loggers that propagate to their respective parents unless explicitly disabled. This hierarchy is spam_appliclation <- spam_application.auxiliary <- spam_application.auxiliary.Auxiliary or logger <- module_logger <- self.logger in the case of the cookbook example.

If you replace the explicit logger names by __name__ you end up having a configured logger named __main__ in your main module, which is configured with handlers, but the naming of your auxiliary loggers is not in a way that it would create a hierarchy, hence your auxiliary_module loggers propagate to the implicit root logger which has no handlers configured.

Try the following: Change your class’ init method as follows:

def __init__(self):
    self.logger = logging.getLogger('spam_application.auxiliary.Auxiliary')
    print self.logger.parent
    self.logger.info('creating an instance of Auxiliary')

Then run your main module once with

self.logger = logging.getLogger('spam_application.auxiliary.Auxiliary')

and once with

self.logger = logging.getLogger(__name__)

The output should look like this:

<Logger spam_application.auxiliary (WARNING)> # with explicit logger name
<RootLogger root (WARNING)>                   # using __name__

Summery

It’s all About this issue. Hope all Methods helped you a lot. Comment below Your thoughts and your queries. Also, Comment below which Method worked for you? Thank You.

Also, Read