python 初始化logging配置之前就logging.error会重复日志的解决方案

如题,如果在初始化日志配置之前就logging了下,初始化之后,任何日志都是双份的呢。

# coding=utf-8
import logging

# 这是第一次日志,没设置日志的各个参数
logging.error("1")


def init_logging():
    """
        初始化logging环境
        hdlr = TimedRotatingFileHandler(filename, "D", 1, 10)
        表示:设置每天自动切换到一个文件下保存,一共保存10天的数据...
        hdlr = TimedRotatingFileHandler(filename, "D", 1, 0)
        表示:设置每天自动切换到一个文件下保存,保存无限天数...
        “S”: Seconds
        “M”: Minutes
        “H”: Hours
        “D”: Days
         1 : 表示单位...
         10: 表示保存的单位....
    """
    import sys
    import logging.handlers
    from logging.handlers import TimedRotatingFileHandler

    root = logging.getLogger()
    level = logging.INFO
    filename = "/Users/ouyang/PycharmProjects/myApp/log/chanzai.log"

    formatter =logging.Formatter('%(asctime)s %(filename)s-%(lineno)d [%(levelname)s] %(message)s')

    hdlr = TimedRotatingFileHandler(filename, "midnight", 1, 15)
    hdlr.setFormatter(formatter)
    root.addHandler(hdlr)
    root.setLevel(level)
    # 同时输出到屏幕,便于实施观察
    handle2 = logging.StreamHandler(sys.stdout)
    handle2.setFormatter(formatter)
    root.addHandler(handle2)

# 初始化日志配置
init_logging()

# 第二次日志
logging.error("2")
logging.info("3”)

# 结果:
ERROR:root:1
ERROR:root:2
2017-09-18 16:13:21,612 tmp.py-46 [ERROR] 2
INFO:root:3
2017-09-18 16:13:21,612 tmp.py-47 [INFO] 3

如果直接: 
import loggig
Logging.error(1)
python帮我们做了什么?
def error(msg, *args, **kwargs):
    """
    Log a message with severity 'ERROR' on the root logger.
    """
    if len(root.handlers) == 0:
        basicConfig()
    root.error(msg, *args, **kwargs)
因为一开始  len(logging.root.handlers) == 0,跳进:
def basicConfig(**kwargs):
    """
    Do basic configuration for the logging system.

    This function does nothing if the root logger already has handlers
    configured. It is a convenience method intended for use by simple scripts
    to do one-shot configuration of the logging package.

    The default behaviour is to create a StreamHandler which writes to
    sys.stderr, set a formatter using the BASIC_FORMAT format string, and
    add the handler to the root logger.

    A number of optional keyword arguments may be specified, which can alter
    the default behaviour.

    filename  Specifies that a FileHandler be created, using the specified
              filename, rather than a StreamHandler.
    filemode  Specifies the mode to open the file, if filename is specified
              (if filemode is unspecified, it defaults to 'a').
    format    Use the specified format string for the handler.
    datefmt   Use the specified date/time format.
    level     Set the root logger level to the specified level.
    stream    Use the specified stream to initialize the StreamHandler. Note
              that this argument is incompatible with 'filename' - if both
              are present, 'stream' is ignored.

    Note that you could specify a stream created using open(filename, mode)
    rather than passing the filename and mode in. However, it should be
    remembered that StreamHandler does not close its stream (since it may be
    using sys.stdout or sys.stderr), whereas FileHandler closes its stream
    when the handler is closed.
    """
    # Add thread safety in case someone mistakenly calls
    # basicConfig() from multiple threads
    _acquireLock()
    try:
        if len(root.handlers) == 0:
            filename = kwargs.get("filename")
            if filename:
                mode = kwargs.get("filemode", 'a')
                hdlr = FileHandler(filename, mode)
            else:
                stream = kwargs.get("stream")
                hdlr = StreamHandler(stream)
            fs = kwargs.get("format", BASIC_FORMAT)
            dfs = kwargs.get("datefmt", None)
            fmt = Formatter(fs, dfs)
            hdlr.setFormatter(fmt)
            root.addHandler(hdlr)
            level = kwargs.get("level")
            if level is not None:
                root.setLevel(level)
    finally:
        _releaseLock()
关键,倒数第6行的:

 root.addHandler(hdlr)

所以root这个logger多了一个handler。。。
我们看看tmp.py里面的代码,然后之后再初始化,我们多了两个handler: 
root.addHandler(hdlr)
root.addHandler(handle2)
抛开那个输出到控制台的handler2,每次看日志都能看到两条。
所以解决方案很简单,初始化logging的时候位置放在最前面即可。比如的tornado项目,把logging_init()放到项目run起来之前,就可以杜绝这种情况啦,美滋滋。

以上



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值