使用Python的logging模块记录错误出现问题

3

我正在使用Python的logging模块记录错误。 我在我的类中创建了一个日志记录器对象,如下所示:

self.my_logger = logging.getLogger('my_logger')
self.my_logger.setLevel(logging.ERROR)

当我在代码后面尝试记录错误时,代码如下:

self.my_logger.error("My error")

然后我遇到了错误:
AttributeError: FileHandler instance has no attribute 'filters'

更详细的错误日志如下:
  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'

在此之前,我设置文件处理器的方式如下:
 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.")

有什么想法在这里发生了吗?谢谢。

在记录器层次结构中,您进一步添加处理程序的方式出了问题,可能是针对根记录器。您能否展示一下这个设置代码? - Sven Marnach
看起来问题出在FileHandler上。你能发一下你的FileHandler配置吗? - David Wolever
请提供原文以便进行翻译。 - user248237
1个回答

8

请检查您是否定义了与标准模块同名的任何模块。下面略作修改的脚本在我的系统上运行时没有出现错误。请在您的系统上尝试,如果它可以正常工作,请再次检查您是否正在重新定义具有相同名称的任何类。

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

顺便提一下 - 我知道你没有问过这个,但是将日志记录器存储为实例变量并不是推荐的做法 - 没有必要,因为它们本来就是单例。对于大多数用户来说,正常的方法是拥有一个单独的

logger = logging.getLogger(__name__)

在模块级别上使用一个记录器,并在整个模块中使用它。如果需要更细粒度的控制,可以创建一个以__name__为前缀的子记录器(例如'%s.detail' % __name__)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接