如何使用 .yaml 文件仅记录特定级别

How to use .yaml file for logging specific level only

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

我检查了 documentation,它说:

The fileConfig() API is older than the dictConfig() API and does not provide functionality to cover certain aspects of logging. For example, you cannot configure Filter objects, which provide for filtering of messages beyond simple integer levels, using fileConfig(). If you need to have instances of Filter in your logging configuration, you will need to use dictConfig(). Note that future enhancements to configuration functionality will be added to dictConfig(), so it’s worth considering transitioning to this newer API when it’s convenient to do so.

我检查过install filter on logging level in python using dictConfig and Where 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

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

尝试将级别设置为 INFO,将显示 INFO 及更高级别。日志记录模块中没有过滤器,只允许您过滤出特定级别。

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

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

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

OP 在这里。

我希望我能够通过修改 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]