【问题标题】:Python logging only log from scriptPython 仅记录来自脚本的日志
【发布时间】:2012-01-06 08:16:47
【问题描述】:

我目前在我的一个简单脚本中使用 Python 日志记录模块,设置如下。

logging.basicConfig(format='%(asctime)s %(message)s', level=logging.INFO, datefmt='%Y-%m-%d %H:%M:%S')
logger = logging.getLogger(__name__)

我的问题是这也会捕获 3rd 方模块,例如请求并从它们输出 info() 日志消息。有什么方法可以抑制这些消息或告诉日志模块只记录我自己的脚本中的消息?

【问题讨论】:

    标签: python logging


    【解决方案1】:

    上面的答案并不正确 - 它只会将来自其他模块的消息设置得更高。

    一个非常快速的方法是使用这段代码:

    import logging.config
    logging.config.dictConfig({
        'version': 1,
        'disable_existing_loggers': True,
    })
    

    您必须在导入所有模块后设置它 - 它会禁用到目前为止创建的所有记录器。这在大多数情况下都会起作用,但是某些模块会在您创建类实例时创建它们的记录器(例如,这将在您的代码中稍后发生)。


    当您根据基本 Python 教程设置记录器时,它们会告诉您使用 logging.basicConfig(...)。这是一个问题,因为这会将处理程序(即日志将被路由到的位置)设置为logging.lastResort,这是从 Python 3.2 开始的 stderr,用于进程中的全局 all 记录器。这意味着您现在已为所有模块启用完整日志记录。

    因此,更好的方法是仅为您的模块创建一个不同的记录器,并为其提供一些自己的处理程序,而不是使用basicConfig()

    有两种方法:

    1) 所有功能:

    import logging
    
    log = logging.getLogger(__name__)
    log.setLevel(logging.DEBUG)
    formatter = logging.Formatter(fmt="%(asctime)s %(levelname)s: %(message)s", 
                              datefmt="%Y-%m-%d - %H:%M:%S")
    ch = logging.StreamHandler(sys.stdout)
    ch.setLevel(logging.DEBUG)
    ch.setFormatter(formatter)
    fh = logging.FileHandler("mylog.log", "w")
    fh.setLevel(logging.DEBUG)
    fh.setFormatter(formatter)
    log.addHandler(ch)
    log.addHandler(fh)
    

    这将为您提供记录器log,然后您可以像log.error("Error found") 一样使用它。它将写入一个名为 mylog.log 的新文件,并且还会记录 sys.stdout。当然,您可以随意更改。

    2) 使用字典:

    import logging
    import logging.config
    
    DEFAULT_LOGGING = {
        'version': 1,
        'formatters': { 
            'standard': {
                'format': '%(asctime)s %(levelname)s: %(message)s',
                'datefmt': '%Y-%m-%d - %H:%M:%S' },
        },
        'handlers': {
            'console':  {'class': 'logging.StreamHandler', 
                         'formatter': "standard", 
                         'level': 'DEBUG', 
                         'stream': sys.stdout},
            'file':     {'class': 'logging.FileHandler', 
                         'formatter': "standard", 
                         'level': 'DEBUG', 
                         'filename': 'live_detector.log','mode': 'w'} 
        },
        'loggers': { 
            __name__:   {'level': 'INFO', 
                         'handlers': ['console', 'file'], 
                         'propagate': False },
        }
    }
    
    logging.config.dictConfig(DEFAULT_LOGGING)
    log = logging.getLogger(__name__)
    

    这将给出与上面相同的结果,但会更长一些,但可能更易于阅读。这也会自动设置'disable_existing_loggers': True。如果你不想这样,你必须添加它并将其设置为 False。

    【讨论】:

    • 这如何为记录器提供一个关于类创建问题的示例?我只是看到提到的问题,而不是解决方案。
    【解决方案2】:

    在模块中使用命名记录器:

    import logging
    logger = logging.getLogger(__name__)
    logger.info("my info")
    logger.error("my error")
    

    您可以将所有其他记录器的日志级别设置为错误并让您的记录器进行调试:

    import logging
    logging.basicConfig(level=logging.ERROR)
    logging.getLogger(my_module.__name__).setLevel(logging.DEBUG)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-16
      • 1970-01-01
      • 2018-04-22
      • 1970-01-01
      • 2017-10-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多