Good day. I'm trying to solve problem with logging in Python. I'm using Python 3.5.1. I have application, which using a class, imported from other module. I can't enable logging for it. This is a simple representation:
# test.py
import logging
from test_class import TestClass
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.FileHandler('test_log.log', mode='w'))
if __name__ == '__main__':
logger.info('Importing class')
t = TestClass()
t.make_call()
t.make_another_call()
logger.info('End')
# test_class.py
import logging
class TestClass(object):
def __init__(self):
self.logger = logging.getLogger('test_class.TestClass')
def make_call(self):
self.logger.info('Make a call')
def make_another_call(self):
self.logger.info('Make another call')
As you see, logger must wrote to file for lines (two from main module, and two from class. But when I've open log file, I see:
# test_log.log
Importing class
End
So, two logger calls from class didn't have an effect. Any idea, why it's don't work? Thank you in advance.
From the docs:
Multiple calls to getLogger() with the same name will always return a reference to the same Logger object.
The name is potentially a period-separated hierarchical value, like foo.bar.baz (though it could also be just plain foo, for example). Loggers that are further down in the hierarchical list are children of loggers higher up in the list. For example, given a logger with a name of foo, loggers with names of foo.bar, foo.bar.baz, and foo.bam are all descendants of foo. The logger name hierarchy is analogous to the Python package hierarchy, and identical to it if you organise your loggers on a per-module basis using the recommended construction
logging.getLogger(__name__). That’s because in a module,__name__is the module’s name in the Python package namespace.
The way you call getLogger in your code, the call in test.py is done with __main__ and the call in test_class.py is done with test_class, so the latter is not a descendant of the former.
Instead, if, when you set up the handler, you do it on an object you got from calling getLogger() with no argument you will be setting up the handler on the root logging object and all other calls to getLogger() will be further down the hierarchy and will use the handler you specify.
If you want to continue to have the name set for your logging statements in the main module, you can just call getLogger again after you've set up the handler.
For example:
# Call getLogger with no args to set up the handler
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.FileHandler('test_log.log', mode='w'))
if __name__ == '__main__':
# call getLogger again with a name to tag subsequent log statements
logger = logging.getLogger(__name__)
logger.info('Importing class')
t = TestClass()
t.make_call()
t.make_another_call()
logger.info('End')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With