Python logger for each function or module

I am trying to start using logging in python and reading a few blogs. One issue that is causing me confusion is creating a log for each function or for each module. In this Blog: Good Logging Practice in Python , it is recommended to get a logger for each function. For example:

import logging

def foo():
    logger = logging.getLogger(__name__)
    logger.info('Hi, foo') 

class Bar(object):
    def __init__(self, logger=None):
        self.logger = logger or logging.getLogger(__name__)

    def bar(self):
        self.logger.info('Hi, bar')

      

The above reasoning is that

Logging.fileConfig and logging.dictConfig disables existing loggers by default. Thus, the parameters set in the file will not apply to your registrar. Better to get a registrar when you need it. It's cheap to set up or get a registrar.

The recommended way that I read everywhere is as shown below. The blog says that this approach "looks harmless, but actually, there is a pitfall"

.

import logging
logger = logging.getLogger(__name__)

def foo():
    logger.info('Hi, foo') 

class Bar(object):
    def bar(self):
        logger.info('Hi, bar')

      

I find the previous approach was tedious as I would have to forget to get the logger in each function. Plus, getting a logger in every function is definitely more expensive than getting a logger once per module. Is the blog author advocating a no-question? Could you avoid this error?

+3


source to share


1 answer


I agree with you; getting a log in every function you use creates way too much unnecessary cognitive overhead to say the least.

The author of the blog is correct that you must be careful to properly initialize (configure) your registrar (s) before using them.

But the approach he suggests only makes sense if you don't have control over the application load and the application entry point (which you usually do).

To avoid premature (implicit) for creating logs that occurs the first time any of the functions of log messages (eg logging.info()

, logging.error()

etc.), if the root of the magazine was not pre-configured, just make sure you set up your registrar to logging .

Initializing the logger from the main thread before starting other threads is also recommended in the Python docs .

The Python protocol tutorial ( basic and advanced ) can serve you as a reference, but for a more concise overview, see the example section from the Python protocol tutorial :



# myapp.py
import logging
import mylib

# get the fully-qualified logger (here: `root.__main__`)
logger = logging.getLogger(__name__)    

def main():
    logging.basicConfig(format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
                        level=logging.DEBUG)
    # note the `logger` from above is now properly configured
    logger.debug("started")
    mylib.something()

if __name__ == "__main__":
    main()

      

and

# mylib.py
import logging

# get the fully-qualified logger (here: `root.mylib`)
logger = logging.getLogger(__name__)

def something():
    logger.info("something")

      

By doing this on stdout

(note the correct one name

):

$ python myapp.py
2017-07-12 21:15:53,334 __main__     DEBUG    started
2017-07-12 21:15:53,334 mylib        INFO     something

      

+2


source







All Articles