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

版权声明:随意转载。 https://blog.csdn.net/xihuanqiqi/article/details/78085300
如题,如果在初始化日志配置之前就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起来之前,就可以杜绝这种情况啦,美滋滋。

以上



猜你喜欢

转载自blog.csdn.net/xihuanqiqi/article/details/78085300