python - 如何只记录某个级别名称的python日志记录

标签 python python-3.x python-logging

[loggers]
keys=root

[handlers]
keys=consoleHandler,errorHandler,debugHandler

[formatters]
keys=errorFormatter,debugFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler,errorHandler,debugHandler
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=debugFormatter
args=(sys.stdout,)

[handler_errorHandler]
class=FileHandler
level=ERROR
formatter=errorFormatter
args=('errors.log',)

[handler_debugHandler]
class=FileHandler
level=DEBUG
formatter=debugFormatter
args=('debugs.log',)

[formatter_errorFormatter]
style={
format=
    {asctime} - {name} - {levelname} - line {lineno} - {message}
datefmt=%d/%m/%y - %H:%M:%S

[formatter_debugFormatter]
style={
format={asctime} - {name} - {levelname} - {message}
datefmt=%d/%m/%y - %H:%M:%S

如果我有一个像上面那样的配置文件,我如何访问 debugHandler 以便我可以像 debugHandler.addFilter(my_custom_filter) 那样做?

我实际上是在尝试将 DEBUG 消息发送到 debugs.log 并将 ERROR 消息发送到 errors.log,但目前 ERROR 消息也被发送到我不想要的 debugs.log。现在,基于 this StackOverflow post ,这是可以通过过滤器实现的,但为了添加过滤器,我需要一个 logging.Handler 对象,但我不知道如何获取它。

提前致谢:~)

最佳答案

是的,您需要在 debug_handler 上添加过滤器,但是您不能通过 fileConfig 添加过滤器.

来自文档:

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.

所以考虑使用 dictConfig (没有任何理由让您不切换到 dictConfig,无论您的配置如何,因为它更好、更新、更灵活,并且将添加所有 future 的好东西).

所以你的配置,转换为 dictConfig 看起来像这样(可以按原样粘贴和测试):

import logging
from logging import config

class FileFilter:
    """Allow only LogRecords whose severity levels are below ERROR."""

    def __call__(self, log):
        if log.levelno < logging.ERROR:
            return 1
        else:
            return 0


logging_config = {
    'version': 1,
    'formatters': {
        'error_formatter': {
            'format': '{asctime} - {name} - {levelname} - line {lineno} - {message}',
            'style': '{',
            'datefmt': '%d/%m/%y - %H:%M:%S',
        },
        'debug_formatter': {
            'format': '{asctime} - {name} - {levelname} - {message}',
            'style': '{',
            'datefmt': '%d/%m/%y - %H:%M:%S',
        },
    },
    'filters': {
        'file_filter': {
            '()': FileFilter,
        },
    },
    'handlers': {
        'console_handler': {
            'class': 'logging.StreamHandler',
            'formatter': 'debug_formatter',
        },
        'error_handler': {
            'class': 'logging.FileHandler',
            'formatter': 'debug_formatter',
            'level': 'ERROR',
            'filename': 'errors.log',
        },
        'debug_handler': {
            'class': 'logging.FileHandler',
            'formatter': 'debug_formatter',
            'filters': ['file_filter'],
            'filename': 'debug.log',
        },
    },
    'root': {
        'level': 'DEBUG',
        'handlers': ['console_handler', 'error_handler', 'debug_handler'],
    },
}

config.dictConfig(logging_config)

logger = logging.getLogger(__name__)

# these get logged to the console and only to the debugs.log file
# if you want just the debug messages logged to the file, adjust the filter
logger.debug('this is a debug message')
logger.info('this is an info message')
logger.warning('this is a warning message')

# this get logged to the console and only to the errors.log file
logger.error('this is an error message')
logger.critical('this is a critical message')

输出:

27/09/19 - 07:52:44 - __main__ - DEBUG - this is a debug message  # also to debug.log
27/09/19 - 07:52:44 - __main__ - INFO - this is an info message  # also to debug.log
27/09/19 - 07:52:44 - __main__ - WARNING - this is a warning message  # also to debug.log
27/09/19 - 07:52:44 - __main__ - ERROR - this is an error message  # also to errors.log but not to debug.log
27/09/19 - 07:52:44 - __main__ - CRITICAL - this is a critical message  # also to errors.log but not to debug.log

如果您出于某种神秘原因(我看不到任何原因)坚持使用较旧的 API,fileConfig,请参阅 this answer它使用自定义格式化程序,实现相同的目的,但没有过滤器。

关于python - 如何只记录某个级别名称的python日志记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58123869/

相关文章:

python - 数字错误 "sequence item 0: expected str instance, type found"

python - 将自定义数据传递给 request_futures 中的异常

python - 删除所有*不*在其列中包含任何 NaN 的行

python - 如何在 Pytest 中使用 fixture 的覆盖参数?

python - 使用 Google Cloud Stackdriver 在 Kubernetes Engine 上记录 Python 代码的重复日志条目

python - 登录 Python 脚本不起作用 : results in empty log files

python - 如何将自定义日志级别添加到 Python 的日志记录工具

Python 替换 >20GB 文本文件中的一行

python - 如何在 Selenium Python 中正确格式化元素?

Python - tkinter 的默认窗口引用是什么?