Registration in several classes with the module name in the journal

I want to use the logging module instead of printing for debugging information and documentation. The goal is to print to the console with the DEBUG level and register in the file with the INFO level.

I read a lot of documentation, cookbook and other lessons in the registration module, but could not understand how I can use it the way I want it. (I'm on python25)

I want to have the names of the modules in which the logs are written in my log file.

The documentation says that I should use logger = logging.getLogger(__name__) , but how to declare the registrars used in classes in other modules / packages, so they use the same handlers as the main registrar? To recognize the β€œparent”, I can use logger = logging.getLogger(parent.child) , but where do I know who called the class / method?

The example below shows my problem, if I run this, the output will only contain __main__ logs and ignore the logs in Class

This is my main file:

 # main.py import logging from module import Class logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) # create file handler which logs info messages fh = logging.FileHandler('foo.log', 'w', 'utf-8') fh.setLevel(logging.INFO) # create console handler with a debug log level ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) # creating a formatter formatter = logging.Formatter('- %(name)s - %(levelname)-8s: %(message)s') # setting handler format fh.setFormatter(formatter) ch.setFormatter(formatter) # add the handlers to the logger logger.addHandler(fh) logger.addHandler(ch) if __name__ == '__main__': logger.info('Script starts') logger.info('calling class Class') c = Class() logger.info('calling c.do_something()') c.do_something() logger.info('calling c.try_something()') c.try_something() 

Module:

 # module.py imnport logging class Class: def __init__(self): self.logger = logging.getLogger(__name__) # What do I have to enter here? self.logger.info('creating an instance of Class') self.dict = {'a':'A'} def do_something(self): self.logger.debug('doing something') a = 1 + 1 self.logger.debug('done doing something') def try_something(self): try: logging.debug(self.dict['b']) except KeyError, e: logging.exception(e) 

Console output :

 - __main__ - INFO : Script starts - __main__ - INFO : calling class Class - __main__ - INFO : calling c.do_something() - __main__ - INFO : calling c.try_something() No handlers could be found for logger "module" 

In addition: is there a way to get the names of the modules that were recorded in my journal without declaring a new registrar in each class, as described above? Also, as in this case, I need to go self.logger.info() every time I want to write something. I would prefer to use logging.info() or logger.info() in all my code.

Is a global journal perhaps the right answer? But then I won’t get modules where errors occur in the logs ...

And my last question is: Is this a python? Or is there a better recommendation to do such things right.

+7
python namespaces logging
source share
2 answers

In the main module, you configure the name registrar '__main__' (or something that __name__ matches your case), and in module.py you use a different registrar. You either need to configure loggers for each module, or you can configure the root log (by setting logging.getLogger() ) in your main module, which will be applied by default to all registrars of your project.

I recommend using configuration files to configure loggers. This link should give you a good idea of ​​good practices: http://victorlin.me/posts/2012/08/26/good-logging-practice-in-python

EDIT: Use% (module) in your formatting to include the module name in the log message.

+7
source share

You should have one global logger with your handlers:

 logger= logging.getLogger("myapp") #configure handlers 

Then on each module:

logger= logging.getLogger("myapp."+__name__)

If you need registrars for each class, it is up to you - most of the projects that I have seen have (no more) one registrar for each module. My advice: if you do not need different handlers for different classes, stick to one registrar per module or even one registrar per project - if the project is small.

If you need more context in your logs, note that you can print the current function name using %(funcName)s in formatting

+3
source share

All Articles