14. python日志打印重复问题解决(3种思路)

一、 代码如下

# -*-coding:utf8-*-
import logging
class MyLogging(object):
    def __new__(cls, level='DEBUG', **channels):
        """
        :param level:  日志输出等级--->str
        :param channels: ---> 日志输出渠道--->dict,如: {'file':'my_log.log','console':''}
        :return:
        """
        # 1.  创建自己的日志收集器
        my_log = logging.getLogger("my_log")
        # 2. 设置收集的日志等级,设置为INFO,即,输出等级为INFO以及等级高于INFO等级的日志
        levels = ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']
        level_u = level.upper()
        if level_u in levels:
            my_log.setLevel(level_u)
        # 3. 设置输出渠道
        expect_channels = ['console', 'file']
        for channel in channels:
            chanel_l = channel.lower()
            if chanel_l in expect_channels:
                if chanel_l == 'console':
                    c_l = logging.StreamHandler()
                    c_l.setLevel(level_u)  # 设定输出到控制台的log等级
                    my_log.addHandler(c_l)
                else:
                    f_l = logging.FileHandler(filename=channels[channel], encoding="utf8")
                    f_l.setLevel(level_u)  # 设定输出到控制台的log信息等级
                    my_log.addHandler(f_l)

        # 4. 日志格式设置
        # 工作中常用格式,可以实现:输出日志的打印时间,那个模块的哪一个行输出的,输出的体制规则时什么,以及输入的日志内容
        formatter = '%(asctime)s--->[%(filename)s--->%(funcName)s-->line:%(lineno)d] - %(levelname)s: %(message)s'
        ft = logging.Formatter(formatter)
        c_l.setFormatter(ft)
        f_l.setFormatter(ft)
        return my_log


my_log = MyLogging('DEBUG', **{'file': 'my_log1.log', 'console': ''})
my_log2 = MyLogging('DEBUG', **{'file': 'my_log2.log', 'console': ''})

# 5. 日志输出
my_log.error("error")
my_log.critical("critical")

二、 问题截图显示

在这里插入图片描述

三、 原因:

 打断点,查看调试窗口数据内容如下:

在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  **在进行日志打印时,也就是在调用info,debug等方法时,先回进入这么一个流程:根据getLogger(name)里的name获取Logger,而我们代码中创建的logging.getLogger(name)中name都等于my_log,所以在第一次MyLogging实例化时,就已经添加了StreamHandle,第二次实例时,name还是my_log,那么handler这个logger就又有了一个同样的handler,所以就会打印多次**

四、解决方案

方案1: 只创建一个日志对象 ---- 人工控制

在这里插入图片描述

方案2: log实例时,name不一样

       (修改__new__方法,参数增加name) -----  人为控制

在这里插入图片描述
在这里插入图片描述

方案3: __new__方法中做处理,只允许创建一个Logger对象

在这里插入图片描述
结果运行:
在这里插入图片描述


版权声明:本文为weixin_41256550原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。