首页 > 解决方案 > Python Logger 类不打印日志的实现

问题描述

我扩展了下面给出的 python 记录器类:

class CommonLogger(Logger):

    def debug(self, *args):
        self.check_and_log(10, args)

    def info(self, *args):
        self.check_and_log(20, args)

    def warn(self, *args):
        self.check_and_log(30, args)

    def error(self, *args):
        self.check_and_log(40, args)

    def check_and_log(self, level, args):
        if self.isEnabledFor(level):
            log_str = self.convert_list_to_string(args)
            super().log(level, log_str)

    @staticmethod
    def convert_list_to_string(args):
        return ''.join(str(msg) for msg in args)

然后在每个使用它的类中创建一个记录器,如下所示:

self.logger = CommonLogger(logging.getLogger(Constants.LOGGER_NAME))
self.logger.info('starting logger: ' + str(Constants.LOGGER_NAME))

但是当我运行它时,它不会抛出错误 - 但它也不会在控制台上打印任何日志。知道为什么吗?

更新:我将其与打印日志的正常流程进行了比较 - 当它作为 Logger 类的实现创建时,我的logging.handlers似乎没有在 Logger 类中初始化(空列表)。

handlers = {list} <class 'list'> []

在正常流程中 - 处理程序的填写如下:

handlers = {list} <class 'list'>: [<StreamHandler <stdout> (INFO)>, <RotatingFileHandler D:\y\logs\engine.log (INFO)>]
 0 = {StreamHandler} <StreamHandler <stdout> (INFO)>
 1 = {RotatingFileHandler} <RotatingFileHandler D:\y\logs\engine.log (INFO)>
 __len__ = {int} 2

有什么建议么?

标签: pythonlogging

解决方案


这最终解决了我的问题:

class Message(object):
    def __init__(self, fmt, args):
        self.fmt = fmt
        self.args = args

    def __str__(self):
        return self.fmt + ''.join(str(arg) for arg in self.args)


class CommonLoggerAdapter(logging.LoggerAdapter):
    def __init__(self, logger, extra=None):
        super(CommonLoggerAdapter, self).__init__(logger, extra or {})

    def log(self, level, msg, *args, **kwargs):
        if self.isEnabledFor(level):
            msg, kwargs = self.process(msg, kwargs)
            self.logger._log(level, Message(msg, args), (), **kwargs)

显然,使用适配器实现而不是记录器实现效果更好,因为 logging.config 在它们之间共享。如果要使用 Logger 实现,则需要在初始化时执行此操作:

def __init__(name):
    for handler in logging._handlers.values():
        self.addhandler(handler)

这两个选项都有效!希望它也对其他人有所帮助!


推荐阅读