3

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 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.

3
  • Something went worng with how you added handlers to a logger further up in the logger hierarchy, presumably for the root logger. Could you show us this setup code as well? Commented Dec 3, 2010 at 16:13
  • It looks like the problem lies in the FileHandler. Can you post your FileHandler config? Commented Dec 3, 2010 at 16:16
  • posted it in edited post. thanks Commented Dec 3, 2010 at 18:19

1 Answer 1

8

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.