开发者

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__)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜