欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

python logging 重复写日志问题

程序员文章站 2022-05-21 16:43:43
原文链接:https://blog.csdn.net/huilan_same/article/details/51858817 ......

原文链接:https://blog.csdn.net/huilan_same/article/details/51858817 

在用logging模块写日志的时候,遇到了日志重复打印的问题。即在同一个脚本中第一次调用,正常显示,第二次调用,则显示了重复的两条,以此类推,非常头疼。

网上找到原因:没有删除前一次调用的handle对象

示例

import logging


def log(message):
    logger = logging.getLogger('testlog')

    streamhandler = logging.StreamHandler()
    streamhandler.setLevel(logging.ERROR)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
    streamhandler.setFormatter(formatter)

    logger.addHandler(streamhandler)
    logger.error(message)

if __name__ == '__main__':
    log('hi')
    log('hi too')
    log('hi three')

输出结果:

2016-07-08 09:17:29,740 - ERROR - testlog - hi 
2016-07-08 09:17:29,740 - ERROR - testlog - hi too 
2016-07-08 09:17:29,740 - ERROR - testlog - hi too 
2016-07-08 09:17:29,740 - ERROR - testlog - hi three 
2016-07-08 09:17:29,740 - ERROR - testlog - hi three 
2016-07-08 09:17:29,740 - ERROR - testlog - hi three

 

修改后的代码:

import logging


def log(message):
    logger = logging.getLogger('testlog')

    streamhandler = logging.StreamHandler()
    streamhandler.setLevel(logging.ERROR)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
    streamhandler.setFormatter(formatter)

    logger.addHandler(streamhandler)
    logger.error(message)

    #  添加下面一句,在记录日志之后移除句柄
    logger.removeHandler(streamhandler)

if __name__ == '__main__':
    log('hi')
    log('hi too')
    log('hi three')

修改后显示结果:

2016-07-08 09:32:28,206 - ERROR - testlog - hi 
2016-07-08 09:32:28,206 - ERROR - testlog - hi too 
2016-07-08 09:32:28,206 - ERROR - testlog - hi three

深度解析

第二次调用log的时候,根据getLogger(name)里的name获取一个logger对象,而这个logger对象里已经有了第一次添加的handler,第二次又添加了一个handler,所以logger对象里有两个相同的handler,以此类推,调用几次就有几个handler。

 

解决方法:1.每次调用都修改getLogger(name) 中的name

                  2.使用removeHandler(handlername)

                  3.在log方法里做判断,是否已经存在handler

                  4.使用pop函数把handle列表中的handler删除

 

方法三:

import logging


def log(message):
    logger = logging.getLogger('testlog')

    #  这里进行判断,如果logger.handlers列表为空,则添加,否则,直接去写日志
    if not logger.handlers:
        streamhandler = logging.StreamHandler()
        streamhandler.setLevel(logging.ERROR)
        formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
        streamhandler.setFormatter(formatter)
        logger.addHandler(streamhandler)

    logger.error(message)


if __name__ == '__main__':
    log('hi')
    log('hi too')
    log('hi three')

方法四:

import logging


def log(message):
    logger = logging.getLogger('testlog')

    streamhandler = logging.StreamHandler()
    streamhandler.setLevel(logging.ERROR)
    formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
    streamhandler.setFormatter(formatter)

    logger.addHandler(streamhandler)

    logger.error(message)

    #  用pop方法把logger.handlers列表中的handler移除,注意如果你add了多个handler,这里需多次pop,或者可以直接为handlers列表赋空值
    logger.handlers.pop()
    # logger.handler = []


if __name__ == '__main__':
    log('hi')
    log('hi too')
    log('hi three')