“()”在python日志配置中有什么作用

JPG*_*JPG 4 python python-3.x python-logging uvicorn

我在uvicorn源代码中看到了一个 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
    },
}
Run Code Online (Sandbox Code Playgroud)

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

"": {"handlers": ["default"], "level": "INFO"},
^^^^ - see, Empty key
Run Code Online (Sandbox Code Playgroud)

所以,这是我的问题,

  1. 什么是"()"在做格式化蟒蛇记录的部分?
  2. 什么是""在做伐木工人部分蟒蛇记录?

Jak*_*kub 5

This dictionary is used to configure logging with logging.config.dictConfig().

The "()" key indicates that custom instantiation is required [source]:

In all cases below where a ‘configuring dict’ is mentioned, it will be checked for the special '()' key to see if a custom instantiation is required. If so, the mechanism described in User-defined objects below is used to create an instance; otherwise, the context is used to determine what to instantiate.

In the case of the formatter config in the OP's question, the "()" indicates that those classes should be used to instantiate a Formatter.

I do not see the empty string in the loggers section of the dictionary, but here are the related docs:

loggers - the corresponding value will be a dict in which each key is a logger name and each value is a dict describing how to configure the corresponding Logger instance.

The configuring dict is searched for the following keys:

  • level (optional). The level of the logger.
  • propagate (optional). The propagation setting of the logger.
  • filters (optional). A list of ids of the filters for this logger.
  • handlers (optional). A list of ids of the handlers for this logger.

The specified loggers will be configured according to the level, propagation, filters and handlers specified.

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


出于各种原因,人们可能会使用自定义日志格式化程序。uvicorn使用自定义格式化程序以不同颜色记录不同级别。Python Logging Cookbook 有一个使用自定义格式化程序在日志消息中使用 UTC 时间而不是本地时间的示例

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())
Run Code Online (Sandbox Code Playgroud)

这是输出。请注意,在第一行中,使用的是 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
Run Code Online (Sandbox Code Playgroud)