Problem logging errors with Python's logging module
I'm logging an error with python's logging module. I made a logger object inside my class, as follows:
self.my_logger = logging.getLogger('my_logger')
self.my_logger.setLevel(logging.ERROR)
when I try to log an error later in the code, as:
self.my_logger.error("My error")
then I get the error:
AttributeError: FileHandler instance has no attribute 'filters'
The more detailed error log is:
File "/lib/python2.6/logging/__init__.py", line 1047, in error
self._log(ERROR, msg, args, **kwargs)
File "/lib/python2.6/logging/__init__.py", line 1129, in _log
self.handle(record)
File "/lib/python2.6/logging/__init__.py", line 1139, in handle
self.callHandlers(record)
File "/lib/python2.6/logging/__init__.py", line 1176, in callHandlers
hdlr.handle(record)
File "/lib/python2.6/logging/__init__.py", line 658, in handle
rv = self.filter(record)
File "/lib/python2.6/logging/__init__.py", line 558, in filter
for f in self.filters:
AttributeError: FileHandler instance has开发者_JAVA技巧 no attribute 'filters'
Upstream of this, here is how I set the file handler:
if self.log_dir != None:
self.log_filename = os.path.join(self.log_dir, 'run.%s' \
%(time.strftime("%m-%d-%y_%H:%M:%S")))
ch_file = logging.FileHandler(self.log_filename,
delay=True)
ch_file.setLevel(logging.ERROR)
ch_file.setFormatter(formatter)
self.my_logger.addHandler(ch_file)
ch_stream = logging.StreamHandler()
ch_stream.setLevel(logging.INFO)
# add formatter to ch
ch_stream.setFormatter(formatter)
# add ch to logger
self.my_logger.addHandler(ch_stream)
self.my_logger.info("Ready.")
Any idea what is happening here? thanks.
Check that you haven't defined any modules whose names clash with standard ones. The slightly modified script below runs on my system without error. Try it on yours and if it works, double check that you are not redefining any classes with the same names.
import logging
import os
import time
class SomeClass:
def __init__(self):
self.log_dir = os.getcwd()
formatter = logging.Formatter('%(asctime)s %(message)s')
self.my_logger = logging.getLogger('my_logger')
self.my_logger.setLevel(logging.INFO)
if self.log_dir != None:
self.log_filename = os.path.join(self.log_dir, 'run.log')
ch_file = logging.FileHandler(self.log_filename, 'w')
ch_file.setLevel(logging.ERROR)
ch_file.setFormatter(formatter)
self.my_logger.addHandler(ch_file)
ch_stream = logging.StreamHandler()
ch_stream.setLevel(logging.INFO)
# add formatter to ch
ch_stream.setFormatter(formatter)
# add ch to logger
self.my_logger.addHandler(ch_stream)
self.my_logger.info("Ready.")
self.my_logger.error("My error")
def main():
SomeClass()
if __name__ == '__main__':
main()
By the way - I know you didn't ask about this, but it's not recommended practice to store loggers as instance variables - there's no point, as they're singletons anyway. The normal approach for most users is to have a single
logger = logging.getLogger(__name__)
at module level, and use that throughout the module. If you need more granularity, create a child logger of the logger using __name__
as a prefix (e.g. '%s.detail' % __name__
)
精彩评论