首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >过滤日志级别

过滤日志级别
EN

Stack Overflow用户
提问于 2021-09-26 14:57:09
回答 2查看 282关注 0票数 0

我试图将日志级别划分为不同的文件(每个级别一个)。目前,我已经为每个级别定义了一个文件,但是使用当前的配置,上层将被传播到较低的级别。

我的日志配置是:

代码语言:javascript
运行
复制
version: 1

formatters:
  standard:
    format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
  error:
    format: "%(levelname)s <PID %(process)d:%(processName)s> %(name)s.%(funcName)s(): %(message)s"

handlers:
  console:
    class: logging.StreamHandler
    formatter: standard
    level: DEBUG

  debug_file_handler:
    class: logging.handlers.RotatingFileHandler
    formatter: standard
    level: DEBUG
    filename: logs/debug.log
    encoding: utf8
    mode: "w"
    maxBytes: 10485760 # 10MB
    backupCount: 1

  info_file_handler:
    class: logging.handlers.RotatingFileHandler
    formatter: standard
    level: INFO
    filename: logs/info.log
    encoding: utf8
    mode: "w"
    maxBytes: 10485760 # 10MB
    backupCount: 1

  warning_file_handler:
    class: logging.handlers.RotatingFileHandler
    formatter: standard
    level: WARNING
    filename: logs/warning.log
    encoding: utf8
    mode: "w"
    maxBytes: 10485760 # 10MB
    backupCount: 1

  error_file_handler:
    class: logging.handlers.RotatingFileHandler
    formatter: error
    level: ERROR
    filename: logs/error.log
    encoding: utf8
    mode: "w"
    maxBytes: 10485760 # 10MB
    backupCount: 1

  critical_file_handler:
    class: logging.handlers.RotatingFileHandler
    formatter: error
    level: CRITICAL
    filename: logs/critical.log
    encoding: utf8
    mode: "w"
    maxBytes: 10485760 # 10MB
    backupCount: 1

loggers:
  development:
    handlers: [ console, debug_file_handler ]
    propagate: false
  production:
    handlers: [ info_file_handler, warning_file_handler, error_file_handler, critical_file_handler ]
    propagate: false
root:
  handlers: [ debug_file_handler, info_file_handler, warning_file_handler, error_file_handler, critical_file_handler ]

然后加载配置并设置记录器如下:

代码语言:javascript
运行
复制
with open(path_log_config_file, 'r') as config_file:
    config = yaml.safe_load(config_file.read())
    logging.config.dictConfig(config)

logger = logging.getLogger(LOGS_MODE)
logger.setLevel(LOGS_LEVEL)

其中LOGS_MODELOGS_LEVEL是在我的项目中的配置文件中定义的:

代码语言:javascript
运行
复制
# Available loggers: development, production
LOGS_MODE = 'production'
# Available levels: CRITICAL = 50, ERROR = 40, WARNING = 30, INFO = 20, DEBUG = 10
LOGS_LEVEL = 20

当我想使用记录器时:

代码语言:javascript
运行
复制
from src.logger import logger

我已经找到了这些答案,他们提到使用过滤器:#1#2,但是它们都说使用不同的处理程序并为每个处理程序指定级别,但是使用这种方法,在某些情况下,我将不得不导入不同的记录器,而不是只导入一个。这是实现这一目标的唯一途径吗?

致以问候。

更新1:

当我使用YAML文件加载记录器配置时,我找到了这个答案#3

所以我在我的文件logger.py中定义了过滤器

代码语言:javascript
运行
复制
with open(path_log_config_file, 'rt') as config_file:
    config = yaml.safe_load(config_file.read())
    logging.config.dictConfig(config)
    

class InfoFilter(logging.Filter):
    def __init__(self):
        super().__init__()

    def filter(self, record):
        return record.levelno == logging.INFO


class WarningFilter(logging.Filter):
    def __init__(self):
        super().__init__()

    def filter(self, record):
        return record.levelno == logging.WARNING


class ErrorFilter(logging.Filter):
    def __init__(self):
        super().__init__()

    def filter(self, record):
        return record.levelno == logging.ERROR


class CriticalFilter(logging.Filter):
    def __init__(self):
        super().__init__()

    def filter(self, record):
        return record.levelno == logging.CRITICAL


logger = logging.getLogger(LOGS_MODE)
logger.setLevel(LOGS_LEVEL)

在YAML文件中:

代码语言:javascript
运行
复制
filters:
  info_filter:
    (): src.logger.InfoFilter
  warning_filter:
    (): src.logger.WarningFilter
  error_filter:
    (): src.logger.ErrorFilter
  critical_filter:
    (): src.logger.CriticalFilter

handlers:
  console:
    class: logging.StreamHandler
    formatter: standard
    level: DEBUG

  debug_file_handler:
    class: logging.handlers.RotatingFileHandler
    formatter: standard
    level: DEBUG
    filename: logs/debug.log
    encoding: utf8
    mode: "w"
    maxBytes: 10485760 # 10MB
    backupCount: 1

  info_file_handler:
    class: logging.handlers.RotatingFileHandler
    formatter: standard
    level: INFO
    filename: logs/info.log
    encoding: utf8
    mode: "w"
    maxBytes: 10485760 # 10MB
    backupCount: 1
    filters: [ info_filter ]

  warning_file_handler:
    class: logging.handlers.RotatingFileHandler
    formatter: standard
    level: WARNING
    filename: logs/warning.log
    encoding: utf8
    mode: "w"
    maxBytes: 10485760 # 10MB
    backupCount: 1
    filters: [ warning_filter ]

  error_file_handler:
    class: logging.handlers.RotatingFileHandler
    formatter: error
    level: ERROR
    filename: logs/error.log
    encoding: utf8
    mode: "w"
    maxBytes: 10485760 # 10MB
    backupCount: 1
    filters: [ error_filter ]

  critical_file_handler:
    class: logging.handlers.RotatingFileHandler
    formatter: error
    level: CRITICAL
    filename: logs/critical.log
    encoding: utf8
    mode: "w"
    maxBytes: 10485760 # 10MB
    backupCount: 1
    filters: [ critical_filter ]

我现在的问题是在过滤器部分。我不知道如何指定每个类的名称。在response #3中,他使用__main__.,因为他直接运行脚本,而不是作为模块运行,并且没有说明如何使用模块。

阅读用户定义对象文档引用时,我尝试使用ext://,就像在访问外部对象部分中所说的那样,但我得到的错误与使用src.logger.InfoFilter指定层次结构时的错误相同。

代码语言:javascript
运行
复制
    logging.config.dictConfig(config)
  File "/usr/lib/python3.8/logging/config.py", line 808, in dictConfig
    dictConfigClass(config).configure()
  File "/usr/lib/python3.8/logging/config.py", line 553, in configure
    raise ValueError('Unable to configure '
ValueError: Unable to configure filter 'info_filter'
python-BaseException

我的项目树(只显示了重要的部分):

代码语言:javascript
运行
复制
.
├── resources
│   ├── log.yaml
│   └── properties.py
├── src
│   ├── main.py
│   └── logger.py
└── ...
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-28 12:35:56

我提交了另一个答案,因为你的问题随着你的更新1发生了很大的变化。

关于复制的说明:

  • 我重新创造了你的乔木
  • 我的PYTHONPATH只指向根( src/ressources/的父)
  • 我从根目录(当前目录)运行脚本
  • 我在顶层创建了一个logs/目录(否则我得到了ValueError: Unable to configure handler 'critical_file_handler': [Errno 2] No such file or directory: 'C:\\PycharmProjects\\so69336121\\logs\\critical.log')

你遇到的问题是周期性进口造成的。导入logger模块时,它通过加载和YAML文件启动,该文件要求实例化一些src.logger.*Filter对象,但由于文件尚未完全初始化,无法找到这些对象。我建议将有效的代码放入启动时主函数可以调用的函数中。

以下是我所拥有的:

代码语言:javascript
运行
复制
# file: src/logger.py

import logging.config

import yaml  # by `pip install pyyaml`


path_log_config_file = "ressources/log.yml"
LOGS_LEVEL = logging.ERROR
LOGS_MODE = "production"


def setup_logging():
    with open(path_log_config_file, 'rt') as config_file:
        config = yaml.safe_load(config_file.read())
        logging.config.dictConfig(config)

# ... the rest of the file you provided
代码语言:javascript
运行
复制
# file: src/main.py

from src.logger import setup_logging, logger


setup_logging()

logger.debug("DEBUG")
logger.info("INFO")
logger.warning("WARNING")
logger.error("ERROR")
logger.critical("CRITICAL")

然后我发现了一个错误:

代码语言:javascript
运行
复制
ValueError: dictionary doesn't specify a version

通过将这一行添加到YAML文件的顶部解决了问题:

代码语言:javascript
运行
复制
version: 1

cf 文档

然后我得到了一个错误:

代码语言:javascript
运行
复制
ValueError: Unable to configure handler 'console': Unable to set formatter 'standard': 'standard'

因为您的格式化程序没有定义(可能是错误复制粘贴)。给您,将其添加到YAML文件中:

代码语言:javascript
运行
复制
formatters:
  standard:
    format: '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
  error:
    format: 'ERROR %(asctime)s [%(levelname)s] %(name)s: %(message)s'

它运行时没有错误,但没有写入日志。快速调试器断点显示从未调用*Filter.filter方法。我检查了logger对象,实际上它没有附加处理程序。它也可以添加到YAML中:

代码语言:javascript
运行
复制
loggers:
  production:
    handlers: [ debug_file_handler, info_file_handler, warning_file_handler, error_file_handler, critical_file_handler ]
    propagate: False

现在起作用了。

票数 2
EN

Stack Overflow用户

发布于 2021-09-27 06:57:49

我想你误会了。

他们都说要使用不同的处理程序,并为每个处理程序指定级别。

对,是这样。

但是使用这种方法,在某些情况下,我将不得不导入不同的记录器,而不是只导入一个

不,您可以向一个记录器添加任意数量的处理程序。这就是为什么这个方法被称为Logger.addHandler,并且每个记录器对象都有一个处理程序列表(它的.handlers成员)。

您只需要在5个处理程序中安装一个记录器。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69336121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档