如何仅记录特定级别的python日志记录

时间:2019-09-26 19:53:59

标签: 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对象,但我不知道该如何获取。

预先感谢:〜)

1 个答案:

答案 0 :(得分:0)

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

从文档中

  

fileConfig()API早于dictConfig()API,但没有   提供涵盖日志记录某些方面的功能。对于   例如,您无法配置过滤器对象   使用以下方法过滤超出简单整数级别的消息   fileConfig()。如果您需要在日志中包含过滤器实例   配置,您将需要使用dictConfig()。注意未来   配置功能的增强功能将添加到   dictConfig(),因此值得考虑过渡到此较新版本   方便时使用API​​。

因此,请考虑使用dictConfig(无论您采用哪种配置,都没有理由不切换到dictConfig,因为它更好,更新,更灵活,并且所有未来的好东西都会被添加)。

因此,过渡到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,该API使用了自定义格式程序,该格式程序可以实现相同的功能,而没有过滤器