logging.config.dictConfig 的完整示例在哪里?

Posted

技术标签:

【中文标题】logging.config.dictConfig 的完整示例在哪里?【英文标题】:Where is a complete example of logging.config.dictConfig? 【发布时间】:2011-11-22 09:31:55 【问题描述】:

我想使用dictConfig,但文档有点抽象。我在哪里可以找到与dictConfig 一起使用的字典的具体、可复制+粘贴示例?

【问题讨论】:

【参考方案1】:

这里怎么样!对应的文档参考是configuration-dictionary-schema

LOGGING_CONFIG =  
    'version': 1,
    'disable_existing_loggers': True,
    'formatters':  
        'standard':  
            'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
        ,
    ,
    'handlers':  
        'default':  
            'level': 'INFO',
            'formatter': 'standard',
            'class': 'logging.StreamHandler',
            'stream': 'ext://sys.stdout',  # Default is stderr
        ,
    ,
    'loggers':  
        '':   # root logger
            'handlers': ['default'],
            'level': 'WARNING',
            'propagate': False
        ,
        'my.packg':  
            'handlers': ['default'],
            'level': 'INFO',
            'propagate': False
        ,
        '__main__':   # if __name__ == '__main__'
            'handlers': ['default'],
            'level': 'DEBUG',
            'propagate': False
        ,
     

用法:

import logging.config

# Run once at startup:
logging.config.dictConfig(LOGGING_CONFIG)

# Include in each module:
log = logging.getLogger(__name__)
log.debug("Logging is configured.")

如果您看到来自第三方包的日志过多,请务必在导入第三方包之前使用logging.config.dictConfig(LOGGING_CONFIG) 运行此配置。

要使用日志过滤器向每条日志消息添加额外的自定义信息,请考虑this answer。

【讨论】:

还有一个替代位置可以指定root 记录器:在字典的顶层。它在docs 中有描述,当两者都存在时优先于['loggers'][''],但在我看来,['loggers'][''] 更合乎逻辑。另见讨论here python logging.config 文档中所有那些简洁、漂亮的 YAML sn-ps 无法直接阅读。无赖。 这不是 django 特有的吗?如果我使用不同的框架(Flask、Bottle 等),或者甚至不使用 Web 应用程序怎么办? 这感觉就像'disable_existing_loggers': False 的作弊因为你可能没有配置它整块布,但可能重用已经存在的东西.. 如果你将它设置为 True 那么我不'似乎没有任何输出。 可恢复的错误怎么样?错误不应出现在标准输出中。仅用于程序输出。【参考方案2】:

在 logging cookbook examples 中声明了一个 logging.config.dictConfig() dictionary schema 的更新示例。从该食谱链接向上滚动以查看 dictConfig() 的用法。

这是一个使用 StreamHandler 和 RotatingFileHandler 以及自定义 formatdatefmt 记录到标准输出和“日志”子目录的示例用例。

    导入模块并建立到“logs”子目录的跨平台绝对路径

    from os.path import abspath, dirname, join
    import logging
    from logging.config import dictConfig
    base_dir = abspath(dirname(__file__))
    logs_target = join(base_dir + "\logs", "python_logs.log")
    

    根据dictionary schema 文档建立架构。

    logging_schema = 
        # Always 1. Schema versioning may be added in a future release of logging
        "version": 1,
        # "Name of formatter" : Formatter Config Dict
        "formatters": 
            # Formatter Name
            "standard": 
                # class is always "logging.Formatter"
                "class": "logging.Formatter",
                # Optional: logging output format
                "format": "%(asctime)s\t%(levelname)s\t%(filename)s\t%(message)s",
                # Optional: asctime format
                "datefmt": "%d %b %y %H:%M:%S"
            
        ,
        # Handlers use the formatter names declared above
        "handlers": 
            # Name of handler
            "console": 
                # The class of logger. A mixture of logging.config.dictConfig() and
                # logger class-specific keyword arguments (kwargs) are passed in here. 
                "class": "logging.StreamHandler",
                # This is the formatter name declared above
                "formatter": "standard",
                "level": "INFO",
                # The default is stderr
                "stream": "ext://sys.stdout"
            ,
            # Same as the StreamHandler example above, but with different
            # handler-specific kwargs.
            "file":   
                "class": "logging.handlers.RotatingFileHandler",
                "formatter": "standard",
                "level": "INFO",
                "filename": logs_target,
                "mode": "a",
                "encoding": "utf-8",
                "maxBytes": 500000,
                "backupCount": 4
            
        ,
        # Loggers use the handler names declared above
        "loggers" : 
            "__main__":   # if __name__ == "__main__"
                # Use a list even if one handler is used
                "handlers": ["console", "file"],
                "level": "INFO",
                "propagate": False
            
        ,
        # Just a standalone kwarg for the root logger
        "root" : 
            "level": "INFO",
            "handlers": ["file"]
        
    
    

    使用字典架构配置logging

    dictConfig(logging_schema)
    

    尝试一些测试用例,看看是否一切正常

    if __name__ == "__main__":
        logging.info("testing an info log entry")
        logging.warning("testing a warning log entry")
    

【讨论】:

如果想跨多个模块使用模式,这将如何工作?我认为它是在使用它的模块中声明的?【参考方案3】:

接受的答案很好!但是,如果可以从不那么复杂的东西开始呢?日志模块是非常强大的东西,文档有点压倒性,尤其是对于新手。但是一开始你不需要配置格式化程序和处理程序。当你弄清楚你想要什么时,你可以添加它。

例如:

import logging.config

DEFAULT_LOGGING = 
    'version': 1,
    'disable_existing_loggers': False,
    'loggers': 
        '': 
            'level': 'INFO',
        ,
        'another.module': 
            'level': 'DEBUG',
        ,
    


logging.config.dictConfig(DEFAULT_LOGGING)

logging.info('Hello, log')

【讨论】:

这是更相关/更有用的例子,至少在我的情况下。是最后一个logging.info('Hello, log') 让我觉得很开心。文档中的混乱之处在于,使用 dictConfig 我们不再需要执行 getLogger 或任何这些操作。 @theotheo 你能解释一下空键 '': 'level': 'INFO'... 以及为什么没有它就不能工作(例如,将空白值更改为有效值时,例如 standard @MikeWilliamson:不过,如果您想要多个具有不同名称的记录器,仍然调用getLogger() 会很有用。这些记录器中的每一个都从根记录器继承配置。 @MikeWilliamson getLogger 始终是可选的。当直接使用logging.info() 方法时,使用根记录器,而使用getLogger(),您可以拥有不同的记录器,具有不同的名称和级别。【参考方案4】:

流处理程序、文件处理程序、旋转文件处理程序和 SMTP 处理程序的示例

from logging.config import dictConfig

LOGGING_CONFIG = 
    'version': 1,
    'loggers': 
        '':   # root logger
            'level': 'NOTSET',
            'handlers': ['debug_console_handler', 'info_rotating_file_handler', 'error_file_handler', 'critical_mail_handler'],
        ,
        'my.package':  
            'level': 'WARNING',
            'propagate': False,
            'handlers': ['info_rotating_file_handler', 'error_file_handler' ],
        ,
    ,
    'handlers': 
        'debug_console_handler': 
            'level': 'DEBUG',
            'formatter': 'info',
            'class': 'logging.StreamHandler',
            'stream': 'ext://sys.stdout',
        ,
        'info_rotating_file_handler': 
            'level': 'INFO',
            'formatter': 'info',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'info.log',
            'mode': 'a',
            'maxBytes': 1048576,
            'backupCount': 10
        ,
        'error_file_handler': 
            'level': 'WARNING',
            'formatter': 'error',
            'class': 'logging.FileHandler',
            'filename': 'error.log',
            'mode': 'a',
        ,
        'critical_mail_handler': 
            'level': 'CRITICAL',
            'formatter': 'error',
            'class': 'logging.handlers.SMTPHandler',
            'mailhost' : 'localhost',
            'fromaddr': 'monitoring@domain.com',
            'toaddrs': ['dev@domain.com', 'qa@domain.com'],
            'subject': 'Critical error with application name'
        
    ,
    'formatters': 
        'info': 
            'format': '%(asctime)s-%(levelname)s-%(name)s::%(module)s|%(lineno)s:: %(message)s'
        ,
        'error': 
            'format': '%(asctime)s-%(levelname)s-%(name)s-%(process)d::%(module)s|%(lineno)s:: %(message)s'
        ,
    ,



dictConfig(LOGGING_CONFIG)

【讨论】:

【参考方案5】:

我在下面找到Django v1.11.15 默认配置,希望对您有所帮助

DEFAULT_LOGGING = 
    'version': 1,
    'disable_existing_loggers': False,
    'filters': 
        'require_debug_false': 
            '()': 'django.utils.log.RequireDebugFalse',
        ,
        'require_debug_true': 
            '()': 'django.utils.log.RequireDebugTrue',
        ,
    ,
    'formatters': 
        'django.server': 
            '()': 'django.utils.log.ServerFormatter',
            'format': '[%(server_time)s] %(message)s',
        
    ,
    'handlers': 
        'console': 
            'level': 'INFO',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
        ,
        'django.server': 
            'level': 'INFO',
            'class': 'logging.StreamHandler',
            'formatter': 'django.server',
        ,
        'mail_admins': 
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        
    ,
    'loggers': 
        'django': 
            'handlers': ['console', 'mail_admins'],
            'level': 'INFO',
        ,
        'django.server': 
            'handlers': ['django.server'],
            'level': 'INFO',
            'propagate': False,
        ,
    

【讨论】:

这个例子很好,但我认为要在公认的答案之外脱颖而出,一些解释会有所帮助。

以上是关于logging.config.dictConfig 的完整示例在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

python logging模块配置方法浅析

ATM-lib-common

如何在 dask 分布式工作人员上设置日志记录?