【问题标题】:What does "()" do in python log config“()”在python日志配置中做了什么
【发布时间】:2020-11-07 08:45:33
【问题描述】:

我在uvicorn's源代码中看到了一个python dict日志配置。

在这方面,他们将格式化程序定义为

{
    "default": {
        "()": "uvicorn.logging.DefaultFormatter",
        "fmt": "%(levelprefix)s %(asctime)s %(message)s",
        "datefmt": "%Y-%m-%d %H:%M:%S",

    },
    "access": {
        "()": "uvicorn.logging.AccessFormatter",
        "fmt": '%(levelprefix)s %(asctime)s :: %(client_addr)s - "%(request_line)s" %(status_code)s',
        "use_colors": True
    },
}

另外,我们可以看到,他们定义了一个空记录器(不知道我应该怎么称呼它),

"": {"handlers": ["default"], "level": "INFO"},
^^^^ - see, Empty key

所以,这是我的问题,

  1. formatters 部分中的 "()" 有什么作用?
  2. loggers 部分 python logger 中的 "" 做了什么?

【问题讨论】:

    标签: python python-3.x python-logging uvicorn


    【解决方案1】:

    此字典用于配置 logging.config.dictConfig() 的日志记录。

    "()" 键表示需要自定义实例化 [source]:

    在下面提到“配置字典”的所有情况下,将检查特殊的“()”键,以查看是否需要自定义实例化。如果是这样,则使用下面User-defined objects 中描述的机制来创建实例;否则,上下文用于确定要实例化的内容。

    对于 OP 问题中的格式化程序配置,"()" 表示应该使用这些类来实例化 Formatter

    我在字典的记录器部分没有看到空字符串,但这里是related docs

    loggers - 对应的值将是一个字典,其中每个键是一个记录器名称,每个值是一个描述如何配置相应记录器实例的字典。

    在配置字典中搜索以下键:

    • level(可选)。记录器的级别。
    • propagate(可选)。记录器的传播设置。
    • filters(可选)。此记录器的过滤器 ID 列表。
    • handlers(可选)。此记录器的处理程序的 ID 列表。

    指定的记录器将根据指定的级别、传播、过滤器和处理程序进行配置。

    所以loggers 字典中的"" 键将实例化一个名称为"" 的记录器,例如logging.getLogger("")


    出于各种原因,人们可能会使用自定义日志格式化程序。 uvicorn 使用自定义格式化程序 to log different levels in different colors。 Python Logging Cookbook 在日志消息中使用example of using a custom formatter to use UTC times 而不是本地时间。

    import logging
    import time
    
    class UTCFormatter(logging.Formatter):
        converter = time.gmtime
    
    LOGGING = {
        ...
        'formatters': {
            'utc': {
                '()': UTCFormatter,
                'format': '%(asctime)s %(message)s',
            },
            'local': {
                'format': '%(asctime)s %(message)s',
            }
        },
        ...
    }
    
    if __name__ == '__main__':
        logging.config.dictConfig(LOGGING)
        logging.warning('The local time is %s', time.asctime())
    

    这是输出。请注意,在第一行中,使用的是 UTC 时间而不是本地时间,因为使用了 UTCFormatter

    2015-10-17 12:53:29,501 The local time is Sat Oct 17 13:53:29 2015
    2015-10-17 13:53:29,501 The local time is Sat Oct 17 13:53:29 2015
    

    【讨论】:

    • 太棒了!!谢谢。如果您添加一个示例来说明 普通格式化程序自定义格式化程序 有何不同,那就太好了。
    • 好主意——从 python 日志记录食谱中添加了一个示例。
    • 对于utc 格式化程序,不应该是fmt 而不是format?因为,fmt 用于UTCFormatter__init__() 方法中(固有地来自logging.Formatter
    • 好问题,配置字典模式表明"format" 是正确的键。它必须先转换为 fmt arg,然后才能传递给 Formatter 对象。
    猜你喜欢
    • 1970-01-01
    • 2016-02-26
    • 2017-10-31
    • 1970-01-01
    • 2019-01-13
    • 2020-10-13
    • 2018-12-04
    • 2011-03-10
    • 1970-01-01
    相关资源
    最近更新 更多