【问题标题】:How to use .yaml file for logging specific level only如何使用 .yaml 文件仅记录特定级别
【发布时间】:2021-11-15 19:24:21
【问题描述】:

我正在处理与 python logging specific level onlylogging with filters 相同的问题,唯一的例外是我使用的是 .yaml 文件。

我查看了documentation,上面写着:

fileConfig() API 比 dictConfig() API 更老,并且没有 提供涵盖日志记录某些方面的功能。为了 例如,您不能配置过滤器对象,这些对象提供 过滤超出简单整数级别的消息,使用 文件配置()。如果您需要在日志记录中包含过滤器实例 配置,您将需要使用 dictConfig()。请注意,未来 配置功能的增强将被添加到 dictConfig(),所以值得考虑过渡到这个新的 方便时使用 API。

我检查了install filter on logging level in python using dictConfigWhere is a complete example of logging.config.dictConfig?

我最新的 python 文件是这样的:

import logging
import logging.config
import yaml

with open('logging.yaml', 'rt') as f:
    config = yaml.safe_load(f.read())
logging.config.dictConfig(config)

logger = logging.getLogger('module1')

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warning('warn message')
logger.error('error message')
logger.critical('critical message')

logging.yaml 文件如下所示:

version: 1
formatters:
   simple:
     format: '{asctime} : {name} : {levelname} : {message}'
     style: '{'
handlers:
 console:
    class: logging.StreamHandler
    level: DEBUG
    formatter: simple
    stream: ext://sys.stdout
loggers:
   module1:
     level: DEBUG
     handlers: [console]
     propogate: no
root:
    level: DEBUG
    handlers: [console]

不明白如何修改 logging.yaml 文件,以便我只能在控制台中查看 INFO 并将 CRITICAL、ERROR、WARNING 保存到 logfile.log

【问题讨论】:

    标签: python-3.x python-logging


    【解决方案1】:

    恐怕您必须创建自己的过滤器。

    尝试将级别设置为INFO,将显示INFO 及以上。日志模块中没有过滤器允许您仅过滤掉特定级别。

    幸运的是,过滤器可以轻松创建,因为它们的唯一要求是 Filter 对象或任何返回布尔值的可调用对象。

    在您的情况下,向您的控制台处理程序添加以下过滤器:

    handler.addFilter(lambda record: record.levelname == "INFO")

    【讨论】:

    • 我认为我们必须使用dictConfig 而不是fileConfig。更新了问题。
    • 如果您不想同时使用“dict config”和“script config”,您可以将用户定义的对象与dictConfig 一起使用:docs.python.org/3/library/…
    • @blueray 仍然无关紧要。您需要一个只取出信息的自定义过滤器。欢迎您创建一个类并使用 yaml 配置。
    【解决方案2】:

    在这里。

    我希望能够通过修改logging.yaml 文件来配置过滤器。不幸的是,我不得不创建过滤类(在我的例子中是 infoFiltercriticalFilter)。

    以下代码在终端中记录 INFO,在文件中记录 WARNING、ERROR 或 CRITICAL。

    Python 代码:

    import logging
    import os
    import logging.config
    import yaml
    
    DEFAULT_LEVEL = logging.DEBUG
    
    class infoFilter(logging.Filter):
        def filter(self, log_record):
            return log_record.levelno == logging.INFO
    
    class warningerrorcriticalFilter(logging.Filter):
        def filter(self, log_record):
    
            if log_record.levelno in {logging.WARNING, logging.ERROR, logging.CRITICAL}:
                return True
            else:
                return False
    
    def log_setup(log_cfg_path='config.yaml'):
        if os.path.exists(log_cfg_path):
            with open(log_cfg_path, 'r') as f:
                try:
                    config = yaml.safe_load(f.read())
                    logging.config.dictConfig(config)
                except Exception as e:
                    print('Error with file, using Default logging')
                    logging.basicConfig(level=DEFAULT_LEVEL)
    
        else:
            logging.basicConfig(level=DEFAULT_LEVEL)
            print('Config file not found, using Default logging')
    
    log_setup()
    
    logger = logging.getLogger('dev')
    logger.debug('debug message')
    logger.info('info message')
    logger.warning('warn message')
    logger.error("error message")
    logger.critical('critical message')
    

    config.yaml 文件:

    version: 1
    
    formatters:
      extended:
        format: '%(asctime)-20s :: %(levelname)-8s :: [%(process)d]%(processName)s :: %(threadName)s[%(thread)d] :: %(pathname)s :: %(lineno)d :: %(message)s'
      simple:
        format: "%(asctime)s :: %(name)s :: %(message)s"
    
    filters:
      show_only_info:
        (): __main__.infoFilter
      show_only_warningerrorcritical:
        (): __main__.warningerrorcriticalFilter
    
    handlers:
      console:
        class: logging.StreamHandler
        level: DEBUG
        formatter: simple
        stream: ext://sys.stdout
        filters: [show_only_info]
    
      file_handler:
        class: logging.FileHandler
        filename: my_app.log
        formatter: extended
        level: DEBUG
        filters: [show_only_warningerrorcritical]
    
    loggers:
      dev:
        handlers: [console, file_handler]
        propagate: false
      prod:
        handlers: [file_handler]
    
    root:
      level: DEBUG
      handlers: [console]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-21
      • 2013-06-11
      • 2022-10-16
      • 1970-01-01
      相关资源
      最近更新 更多