python 日志配置中的“()”是做什么的

What does "()" do in python log config

我在 uvicorn's 源代码中看到了 python 字典日志配置。

在那里,他们将 formatters 定义为

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

    },
    "access": {
        <b>"()"</b>: "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 部分做了什么 python记录器?
  2. ""loggers 部分做了什么 python记录器?

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

"()"键表示需要自定义实例化[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.

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

我在字典的记录器部分没有看到空字符串,但这里是 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 在记录消息时使用自定义格式化程序 to log different levels in different colors. The Python Logging Cookbook has an 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