基于日志记录级别的不同实例代表

时间:2020-09-23 10:01:58

标签: python logging

我想记录有关某个实例的信息。但是,我想根据我使用的日志级别显示不同的详细程度。例如:

LOGGER.level
# => 20
LOGGER.info('Car info: %s', Car())
# => [INFO]: Car info: Celica
LOGGER.setLevel(logging.DEBUG)
LOGGER.info('Car info: %s', Car())
# => [INFO]: Car info: {'name': 'Celica', 'year': 1998, 'model': 'GT-Four'}

到目前为止,我想到了以下内容:

import logging

LOGGER = logging.getLogger()
logging.basicConfig(
    format='[%(levelname)s]: %(message)s',
    level=logging.INFO)
    
class Car:
    def __init__(self):
        self.name = 'Celica'
        self.year = 1998
        self.model = 'GT-Four'

    def __repr__(self):
        if LOGGER.level == logging.DEBUG:
            return str(self.__dict__)
            
        return f'{self.name}'

我觉得这有点“习惯”,并且以某种方式进行了硬编码。在LOGGER中使用logging__repr__感觉有些奇怪。这是正确的进行方法还是有更好的方法?

1 个答案:

答案 0 :(得分:1)

是的,在__repr__中包含逻辑是不寻常的-如您所识别的,可能是代码气味。通常,表示逻辑将放在Formatter子类中,但您也可以在filter中进行。这是一个简单的工作示例;您应该能够将基本概念改编为更通用的方案:

import logging

LOGGER = logging.getLogger()

class Car:
    def __init__(self):
        self.name = 'Celica'
        self.year = 1998
        self.model = 'GT-Four'

def filter(record):
    if record.args:
        args = []
        for arg in record.args:
            if isinstance(arg, Car):
                if record.levelno == logging.DEBUG:
                    arg = str(arg.__dict__)
                else:
                    arg = arg.name
            args.append(arg)
        record.args = tuple(args)
    return True

def main():
    LOGGER.setLevel(logging.DEBUG)
    f = logging.Formatter('[%(levelname)-5s]: %(message)s')
    h = logging.StreamHandler()
    h.setFormatter(f)
    LOGGER.addHandler(h)
    LOGGER.addFilter(filter)
    car = Car()
    LOGGER.info('basic : %s', car)
    LOGGER.debug('detail: %s', car)
    LOGGER.debug('no car in this %s', 'message')
    LOGGER.debug('nor in this one')

if __name__ == '__main__':
    main()

运行时,以上脚本将打印:

[INFO ]: basic : Celica                                              
[DEBUG]: detail: {'name': 'Celica', 'year': 1998, 'model': 'GT-Four'}
[DEBUG]: no car in this message                                      
[DEBUG]: nor in this one