python logging 重复写日志问题

python logging 重复写日志问题

用Python的logging模块记录日志时,遇到了重复记录日志的问题,第一条记录写一次,第二条记录写两次,第三条记录写三次。。。很头疼,这样记日志可不行。网上搜索到了原因与解决方案:

原因:没有移除handler
解决:在日志记录完之后removeHandler

修改前示例代码:

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

深度解析:

Google之后,大概搞明白了,就是你第二次调用log的时候,根据getLogger(name)里的name获取同一个logger,而这个logger里已经有了第一次你添加的handler,第二次调用又添加了一个handler,所以,这个logger里有了两个同样的handler,以此类推,调用几次就会有几个handler。。

所以这里有以下几个解决办法:

  1. 每次创建不同name的logger,每次都是新logger,不会有添加多个handler的问题。(ps:这个办法太笨,不过我之前就是这么干的。。)
  2. 像上面一样每次记录完日志之后,调用removeHandler()把这个logger里的handler移除掉。
  3. 在log方法里做判断,如果这个logger已有handler,则不再添加handler。
  4. 与方法2一样,不过把用pop把logger的handler列表中的handler移除。

下面是方法3与方法4的代码示例:

方法3:

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

方法4:

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

这几种方法都亲试可行,个人觉得方法3判断更加优雅,你觉得呢?

  • 35
    点赞
  • 68
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
### 回答1: Pythonlogging 模块提供了一种方便的方法来记录应用程序中的信息,包括错误、警告、调试信息等。如果你的应用程序在多个地方使用 logging 模块来记录信息,可能会导致日志文件中出现重复的信息。 为了防止这种情况,可以通过以下几种方式来避免重复生成日志: 1. 设置日志记录器的级别。使用不同的日志级别来记录不同类型的信息。在创建日志记录器时,可以设置其级别。如果某个日志记录器的级别设置为 DEBUG,那么所有 DEBUG 及以上级别的信息都会被记录下来。如果将日志级别设置为 WARNING,则只会记录 WARNING、ERROR 和 CRITICAL 级别的信息。这样,就可以避免重复记录同样级别的信息。 2. 避免重复设置日志处理器。在使用 logging 模块时,通常会创建多个日志处理器。如果多个处理器都记录相同的信息,就会导致日志文件中出现重复的信息。为了避免这种情况,可以在代码中检查是否已经创建了相同类型的处理器,如果已经创建,则不需要再创建。 3. 避免重复添加日志处理器。在某些情况下,可能需要将同一种类型的处理器添加到多个日志记录器中。如果多个日志记录器都添加了同样的处理器,就会导致重复记录信息。为了避免这种情况,可以在代码中检查是否已经将处理器添加到了相应的日志记录器中,如果已经添加,则不需要再添加。 综上所述,可以通过设置日志记录器的级别、避免重复设置日志处理器和避免重复添加日志处理器等方式来避免重复生成日志。 ### 回答2: Pythonlogging模块在使用过程中,可能会出现重复生成日志的情况。主要有以下几种可能原因: 1. 多次调用`logging.basicConfig()`方法:`basicConfig()`方法用于设置日志的基本配置,如果在代码中多次调用这个方法,会导致重复生成日志。解决方法是只在代码中调用一次`basicConfig()`,或者使用`logging.getLogger()`方法来获取logger对象,再进行设置。 2. 多次添加了相同的日志处理器:如果在代码中多次添加了相同的处理器(如FileHandler、StreamHandler等),会导致重复生成日志。解决方法是在添加处理器之前,先检查是否已经添加过相同类型的处理器,避免重复添加。 3. 日志级别设置不当:如果在代码中设置了多个处理器,并且给每个处理器设置了相同的日志级别,就会导致重复生成日志。这是因为每个处理器都会接收到同样级别的日志消息。解决方法是根据需求,为每个处理器设置不同的日志级别,避免重复记录。 4. 多线程环境下的竞争条件:在多线程环境下,如果多个线程同时调用日志记录方法,可能会导致消息重复记录。这是因为多个线程同时操作日志记录器。解决方法是使用线程安全的日志记录器,如`logging.getLogger()`返回的logger对象就是线程安全的。 综上所述,要避免Pythonlogging模块重复生成日志,需要注意在代码中的使用方式,避免多次调用`basicConfig()`方法、重复添加处理器和设置相同的日志级别,同时在多线程环境下使用线程安全的日志记录器。 ### 回答3: 在Python中, logging模块提供了记录日志的功能。当出现重复生成日志的情况时,一般是由于以下原因: 1. 多次调用了logging模块的配置函数:在程序中多次调用配置logging的函数,会导致重复生成log。为避免重复生成log,在程序的入口处或配置模块中应只调用一次配置函数。 2. 多次添加了相同的日志处理器:在配置logging模块时,如果多次添加了相同的日志处理器,比如多次调用`addHandler()`函数,则会导致相同的日志信息被多次记录,从而重复生成log。为避免此问题,应仅在配置函数中添加一次处理器。 3. 日志级别设置不合理:如果设置的日志级别过低,比如DEBUG级别,会将所有级别的日志都记录下来,从而导致重复生成log。应根据需求设置适当的日志级别,只记录需要的信息。 4. 并发多线程或多进程日志:如果多个线程或进程同时入同一个log文件,可能会导致日志信息重复。为避免此问题,可以在日志时使用线程锁或文件锁,以确保每次入的日志不会重复。 总之,避免重复生成log的关键是正确地配置logging模块、合理设置日志级别,并注意线程或进程之间的并发入。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值