logging.config — 日志记录配置

源代码: Lib/logging/config.py


本节介绍用于配置日志记录模块的 API。

配置函数

以下函数用于配置日志记录模块。它们位于 logging.config 模块中。它们的使用是可选的 - 您可以使用这些函数配置日志记录模块,也可以通过调用主 API(在 logging 本身中定义)并定义在 logginglogging.handlers 中声明的处理器来配置。

logging.config.dictConfig(config)

从字典中获取日志记录配置。此字典的内容将在下面的 配置字典模式 中描述。

如果在配置过程中遇到错误,此函数将引发带有适当描述性消息的 ValueErrorTypeErrorAttributeErrorImportError。以下是可能引发错误的条件的(可能不完整)列表:

  • level 不是字符串,或者是一个不对应于实际日志记录级别的字符串。

  • propagate 值不是布尔值。

  • 没有对应目标的 ID。

  • 在增量调用期间找到不存在的处理器 ID。

  • 无效的记录器名称。

  • 无法解析为内部或外部对象。

解析由 DictConfigurator 类执行,其构造函数传递用于配置的字典,并具有 configure() 方法。 logging.config 模块有一个可调用属性 dictConfigClass,它最初设置为 DictConfigurator。您可以用您自己的合适实现替换 dictConfigClass 的值。

dictConfig() 调用 dictConfigClass 并传递指定的字典,然后调用返回对象上的 configure() 方法以使配置生效。

def dictConfig(config):
    dictConfigClass(config).configure()

例如,DictConfigurator 的子类可以在其自己的 __init__() 中调用 DictConfigurator.__init__(),然后设置可在后续 configure() 调用中使用的自定义前缀。 dictConfigClass 将绑定到这个新的子类,然后可以像默认的、未定制的状态一样调用 dictConfig()

3.2 版新增。

logging.config.fileConfig(fname, defaults=None, disable_existing_loggers=True, encoding=None)

configparser 格式的文件中读取日志记录配置。文件的格式应如 配置文件格式 中所述。可以从应用程序中多次调用此函数,允许最终用户从各种预先配置中进行选择(如果开发人员提供了一种机制来呈现选择并加载所选配置)。

如果文件不存在,它将引发 FileNotFoundError,如果文件无效或为空,则引发 RuntimeError

参数:
  • fname – 文件名、类文件对象或从 RawConfigParser 派生的实例。如果传递了 RawConfigParser 派生的实例,则按原样使用它。否则,将实例化一个 ConfigParser,并由它从 fname 中传递的对象读取配置。如果它有一个 readline() 方法,则假定它是一个类文件对象,并使用 read_file() 读取;否则,假定它是一个文件名,并传递给 read()

  • defaults – 要传递给 ConfigParser 的默认值可以在此参数中指定。

  • disable_existing_loggers – 如果指定为 False,则在进行此调用时存在的记录器将保持启用状态。默认值为 True,因为这以向后兼容的方式启用了旧行为。此行为是禁用任何现有的非根记录器,除非它们或其祖先在日志记录配置中被显式命名。

  • encoding – 当 fname 是文件名时,用于打开文件的编码。

在 3.4 版更改: 现在接受 RawConfigParser 子类的实例作为 fname 的值。这有助于

  • 使用配置文件,其中日志记录配置只是整体应用程序配置的一部分。

  • 使用从文件读取的配置,然后在传递给 fileConfig 之前由使用应用程序修改(例如,基于命令行参数或运行时环境的其他方面)。

在 3.10 版更改: 添加了 encoding 参数。

在 3.12 版更改: 如果提供的文件不存在、无效或为空,则会引发异常。

logging.config.listen(port=DEFAULT_LOGGING_CONFIG_PORT, verify=None)

在指定端口上启动套接字服务器,并侦听新配置。如果没有指定端口,则使用模块的默认 DEFAULT_LOGGING_CONFIG_PORT。日志记录配置将作为文件发送,该文件适合由 dictConfig()fileConfig() 处理。返回一个 Thread 实例,您可以在该实例上调用 start() 来启动服务器,并在适当的时候调用 join()。要停止服务器,请调用 stopListening()

verify 参数(如果指定)应该是一个可调用对象,它应该验证通过套接字接收的字节是否有效并且应该被处理。这可以通过加密和/或签名通过套接字发送的内容来完成,以便 verify 可调用对象可以执行签名验证和/或解密。使用单个参数(通过套接字接收的字节)调用 verify 可调用对象,并且应该返回要处理的字节,或者返回 None 以指示应该丢弃这些字节。返回的字节可以与传入的字节相同(例如,仅在完成验证时),或者它们可以完全不同(例如,如果执行了解密)。

要将配置发送到套接字,请读入配置文件,并将其作为字节序列发送到套接字,该字节序列前面是一个四字节长度字符串,该字符串使用 struct.pack('>L', n) 以二进制形式打包。

注意

由于配置的部分内容是通过 eval() 传递的,因此使用此函数可能会使用户面临安全风险。虽然该函数仅绑定到 localhost 上的套接字,因此不接受来自远程计算机的连接,但在某些情况下,可以在调用 listen() 的进程的帐户下运行不受信任的代码。具体来说,如果调用 listen() 的进程在用户无法相互信任的多用户计算机上运行,则恶意用户可以安排在受害用户的进程中运行基本上任意的代码,只需连接到受害用户的 listen() 套接字并发送一个配置,该配置运行攻击者希望在受害用户的进程中执行的任何代码。如果使用默认端口,则这尤其容易做到,但即使使用不同的端口也不难。为了避免发生这种情况的风险,请使用 listen()verify 参数来防止应用无法识别的配置。

在 3.4 版更改: 添加了 verify 参数。

注意

如果要将配置发送到不禁用现有记录器的侦听器,则需要对配置使用 JSON 格式,该格式将使用 dictConfig() 进行配置。此方法允许您在发送的配置中将 disable_existing_loggers 指定为 False

logging.config.stopListening()

停止通过调用 listen() 创建的侦听服务器。这通常在对 listen() 的返回值调用 join() 之前调用。

安全注意事项

日志记录配置功能试图提供便利性,部分原因是它能够将配置文件中的文本转换为日志记录配置中使用的 Python 对象 - 例如,如 用户定义的对象 中所述。但是,这些相同的机制(从用户定义的模块导入可调用对象并使用配置中的参数调用它们)可用于调用您喜欢的任何代码,因此,您应该 *极其谨慎地* 处理来自不受信任来源的配置文件,并在实际加载它们之前,先确保加载它们不会发生任何不良情况。

配置字典架构

描述日志记录配置需要列出要创建的各种对象以及它们之间的连接;例如,您可以创建一个名为“控制台”的处理程序,然后说名为“启动”的记录器会将其消息发送到“控制台”处理程序。这些对象不限于 logging 模块提供的对象,因为您可以编写自己的格式化程序或处理程序类。这些类的参数可能还需要包含外部对象,例如 sys.stderr。描述这些对象和连接的语法在下面的 对象连接 中定义。

字典架构详细信息

传递给 dictConfig() 的字典必须包含以下键

  • version - 设置为表示架构版本的整数值。目前唯一有效的值为 1,但使用此键允许架构在保留向后兼容性的同时进行演进。

所有其他键都是可选的,但如果存在,它们将按照以下描述进行解释。在以下所有提到“配置字典”的情况下,将检查特殊的 '()' 键以查看是否需要自定义实例化。如果是,则使用 用户定义的对象 中描述的机制来创建实例;否则,将使用上下文来确定要实例化的内容。

  • formatters - 相应的值将是一个字典,其中每个键都是一个格式化程序 ID,每个值都是一个描述如何配置相应的 Formatter 实例的字典。

    将在配置字典中搜索以下可选键,这些键对应于传递给创建 Formatter 对象的参数

    • format

    • datefmt

    • style

    • validate (版本 >=3.8 起)

    • defaults (版本 >=3.12 起)

    可选的 class 键指示格式化程序类的名称(作为带点的模块和类名)。实例化参数与 Formatter 相同,因此此键对于实例化 Formatter 的自定义子类最有用。例如,替代类可能会以展开或压缩的格式呈现异常回溯。如果您的格式化程序需要不同的或额外的配置键,则应使用 用户定义的对象

  • filters - 相应的值将是一个字典,其中每个键都是一个过滤器 ID,每个值都是一个描述如何配置相应的 Filter 实例的字典。

    将在配置字典中搜索键 name(默认为空字符串),并使用它来构造 logging.Filter 实例。

  • handlers - 相应的值将是一个字典,其中每个键都是一个处理程序 ID,每个值都是一个描述如何配置相应的 Handler 实例的字典。

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

    • class (必填)。这是处理程序类的完全限定名称。

    • level (可选)。处理程序的级别。

    • formatter (可选)。此处理程序的格式化程序 ID。

    • filters (可选)。此处理程序的过滤器 ID 列表。

      在 3.11 版更改: filters 除了 ID 之外还可以采用过滤器实例。

    所有*其他*键都作为关键字参数传递给处理程序的构造函数。例如,给定代码段

    handlers:
      console:
        class : logging.StreamHandler
        formatter: brief
        level   : INFO
        filters: [allow_foo]
        stream  : ext://sys.stdout
      file:
        class : logging.handlers.RotatingFileHandler
        formatter: precise
        filename: logconfig.log
        maxBytes: 1024
        backupCount: 3
    

    ID 为 console 的处理程序将实例化为 logging.StreamHandler,使用 sys.stdout 作为底层流。ID 为 file 的处理程序将使用关键字参数 filename='logconfig.log', maxBytes=1024, backupCount=3 实例化为 logging.handlers.RotatingFileHandler

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

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

    • level (可选)。记录器的级别。

    • propagate (可选)。记录器的传播设置。

    • filters (可选)。此记录器的过滤器 ID 列表。

      在 3.11 版更改: filters 除了 ID 之外还可以采用过滤器实例。

    • handlers (可选)。此记录器的处理程序 ID 列表。

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

  • root - 这将是根记录器的配置。配置的处理方式与任何记录器相同,只是 propagate 设置将不适用。

  • incremental - 配置是否应解释为对现有配置的增量。此值默认为 False,这意味着指定的配置将使用与现有 fileConfig() API 相同的语义替换现有配置。

    如果指定的值为 True,则将按照 增量配置 一节中的描述处理配置。

  • disable_existing_loggers - 是否要禁用任何现有的非根记录器。此设置反映了 fileConfig() 中同名参数的设置。如果不存在,则此参数默认为 True。如果 incrementalTrue,则忽略此值。

增量配置

很难为增量配置提供完全的灵活性。例如,由于过滤器和格式化程序之类的对象是匿名的,因此一旦设置了配置,在扩充配置时就无法引用此类匿名对象。

此外,在设置配置后,没有必要在运行时任意更改记录器、处理程序、过滤器、格式化程序的对象图;记录器和处理程序的详细程度可以通过设置级别(以及记录器的传播标志)来控制。在多线程环境中以安全的方式任意更改对象图是有问题的;虽然并非不可能,但这样做的好处不值得为实现增加的复杂性。

因此,当配置字典的 incremental 键存在且为 True 时,系统将完全忽略任何 formattersfilters 条目,并且仅处理 handlers 条目中的 level 设置,以及 loggersroot 条目中的 levelpropagate 设置。

使用配置字典中的值可以将配置作为腌制的字典通过网络发送到套接字侦听器。因此,可以随着时间的推移更改长时间运行的应用程序的日志记录详细程度,而无需停止和重新启动应用程序。

对象连接

该模式描述了一组日志记录对象 - 记录器、处理器、格式化器、过滤器 - 它们在对象图中相互连接。因此,该模式需要表示对象之间的连接。例如,假设在配置完成后,一个特定的记录器附加了一个特定的处理器。在本讨论中,我们可以说记录器表示连接的源,而处理器表示连接的目标。当然,在配置的对象中,这是通过记录器持有对处理器的引用来表示的。在配置字典中,这是通过为每个目标对象提供一个唯一标识它的 ID,然后在源对象的配置中使用该 ID 来指示源对象和具有该 ID 的目标对象之间存在连接。

例如,请考虑以下 YAML 代码段

formatters:
  brief:
    # configuration for formatter with id 'brief' goes here
  precise:
    # configuration for formatter with id 'precise' goes here
handlers:
  h1: #This is an id
   # configuration of handler with id 'h1' goes here
   formatter: brief
  h2: #This is another id
   # configuration of handler with id 'h2' goes here
   formatter: precise
loggers:
  foo.bar.baz:
    # other configuration for logger 'foo.bar.baz'
    handlers: [h1, h2]

(注意:这里使用 YAML 是因为它比等效的 Python 源代码形式的字典更具可读性。)

记录器的 ID 是将以编程方式用于获取对这些记录器的引用的记录器名称,例如 foo.bar.baz。格式化器和过滤器的 ID 可以是任何字符串值(例如上面的 briefprecise),并且它们是瞬态的,因为它们仅对处理配置字典和用于确定对象之间的连接有意义,并且在配置调用完成后不会持久化在任何地方。

上面的代码段表明,名为 foo.bar.baz 的记录器应该附加两个处理器,它们由处理器 ID h1h2 描述。h1 的格式化器是由 ID brief 描述的格式化器,h2 的格式化器是由 ID precise 描述的格式化器。

用户定义的对象

该模式支持用于处理器、过滤器和格式化器的用户定义对象。(记录器不需要为不同的实例使用不同的类型,因此此配置模式不支持用户定义的记录器类。)

要配置的对象由描述其配置的字典来描述。在某些情况下,日志记录系统将能够从上下文中推断出如何实例化对象,但是当要实例化用户定义的对象时,系统将不知道如何执行此操作。为了为用户定义的对象实例化提供完全的灵活性,用户需要提供一个“工厂” - 一个可调用对象,它使用配置字典调用并返回实例化的对象。这是通过在特殊键 '()' 下提供工厂的绝对导入路径来实现的。下面是一个具体的例子

formatters:
  brief:
    format: '%(message)s'
  default:
    format: '%(asctime)s %(levelname)-8s %(name)-15s %(message)s'
    datefmt: '%Y-%m-%d %H:%M:%S'
  custom:
      (): my.package.customFormatterFactory
      bar: baz
      spam: 99.9
      answer: 42

上面的 YAML 代码段定义了三个格式化器。第一个格式化器,其 ID 为 brief,是一个标准的 logging.Formatter 实例,具有指定的格式字符串。第二个格式化器,其 ID 为 default,具有更长的格式,并且还显式定义了时间格式,并将生成一个使用这两个格式字符串初始化的 logging.Formatter。以 Python 源代码形式显示,briefdefault 格式化器具有配置子字典

{
  'format' : '%(message)s'
}

{
  'format' : '%(asctime)s %(levelname)-8s %(name)-15s %(message)s',
  'datefmt' : '%Y-%m-%d %H:%M:%S'
}

分别,并且由于这些字典不包含特殊键 '()',因此实例化是从上下文中推断出来的:结果,创建了标准的 logging.Formatter 实例。第三个格式化器的配置子字典,其 ID 为 custom,是

{
  '()' : 'my.package.customFormatterFactory',
  'bar' : 'baz',
  'spam' : 99.9,
  'answer' : 42
}

并且它包含特殊键 '()',这意味着需要用户定义的实例化。在这种情况下,将使用指定的工厂可调用对象。如果它是一个实际的可调用对象,它将被直接使用 - 否则,如果您指定一个字符串(如示例中所示),则将使用正常的导入机制找到实际的可调用对象。将使用配置子字典中的**剩余**项作为关键字参数调用可调用对象。在上面的例子中,ID 为 custom 的格式化器将假定由调用返回

my.package.customFormatterFactory(bar='baz', spam=99.9, answer=42)

警告

上面例子中诸如 barspamanswer 等键的值不应该是配置字典或诸如 cfg://fooext://bar 等引用,因为它们不会被配置机制处理,而是按原样传递给可调用对象。

'()' 已被用作特殊键,因为它不是有效的关键字参数名称,因此不会与调用中使用的关键字参数的名称冲突。'()' 还可以作为助记符,表示相应的值是一个可调用对象。

在 3.11 版中更改: handlersloggersfilters 成员除了 ID 之外还可以接受过滤器实例。

您还可以指定一个特殊键 '.',其值是一个字典,该字典是属性名称到值的映射。如果找到,则在返回用户定义的对象之前,将在其上设置指定的属性。因此,使用以下配置

{
  '()' : 'my.package.customFormatterFactory',
  'bar' : 'baz',
  'spam' : 99.9,
  'answer' : 42,
  '.' {
    'foo': 'bar',
    'baz': 'bozz'
  }
}

返回的格式化器将具有设置为 'bar' 的属性 foo 和设置为 'bozz' 的属性 baz

警告

上面例子中诸如 foobaz 等属性的值不应该是配置字典或诸如 cfg://fooext://bar 等引用,因为它们不会被配置机制处理,而是按原样设置为属性值。

处理器配置顺序

处理程序按其键的字母顺序配置,配置的处理程序将替换架构中(工作副本)handlers 字典中的配置字典。如果您使用 cfg://handlers.foo 之类的构造,则最初 handlers['foo'] 指向名为 foo 的处理程序的配置字典,然后(一旦该处理程序已配置)它指向已配置的处理程序实例。因此,cfg://handlers.foo 可以解析为字典或处理程序实例。通常,最好以依赖处理程序在它们依赖的任何处理程序_之后_配置的方式命名处理程序;这允许在配置依赖于处理程序 foo 的处理程序时使用 cfg://handlers.foo 之类的东西。如果该依赖处理程序被命名为 bar,则会导致问题,因为 bar 的配置会在 foo 之前尝试,并且 foo 尚未配置。但是,如果依赖处理程序被命名为 foobar,它将在 foo 之后配置,结果是 cfg://handlers.foo 将解析为已配置的处理程序 foo,而不是其配置字典。

访问外部对象

有时配置需要引用配置外部的对象,例如 sys.stderr。如果使用 Python 代码构造配置字典,这很简单,但是当通过文本文件(例如 JSON、YAML)提供配置时会出现问题。在文本文件中,没有标准的方法来区分 sys.stderr 和字符串字面量 'sys.stderr'。为了促进这种区分,配置系统会在字符串值中查找某些特殊前缀并对其进行特殊处理。例如,如果在配置中提供字符串字面量 'ext://sys.stderr' 作为值,则 ext:// 将被剥离,其余部分使用正常的导入机制处理。

此类前缀的处理方式类似于协议处理:有一种通用机制来查找与正则表达式 ^(?P<prefix>[a-z]+)://(?P<suffix>.*)$ 匹配的前缀,如果识别到 prefix,则以依赖于前缀的方式处理 suffix,并且处理结果替换字符串值。如果前缀无法识别,则字符串值将保持原样。

访问内部对象

除了外部对象之外,有时还需要引用配置中的对象。这将由配置系统针对它知道的事情隐式完成。例如,记录器或处理程序中 level 的字符串值 'DEBUG' 将自动转换为值 logging.DEBUG,并且 handlersfiltersformatter 条目将采用对象 ID 并解析为相应的目标对象。

但是,对于 logging 模块不知道的用户定义对象,需要更通用的机制。例如,考虑 logging.handlers.MemoryHandler,它接受一个 target 参数,该参数是要委托到的另一个处理程序。由于系统已经知道这个类,所以在配置中,给定的 target 只需要是相关目标处理程序的对象 ID,系统将从 ID 解析为处理程序。但是,如果用户定义了一个具有 alternate 处理程序的 my.package.MyHandler,则配置系统将不知道 alternate 引用了一个处理程序。为了解决这个问题,一个通用的解析系统允许用户指定

handlers:
  file:
    # configuration of file handler goes here

  custom:
    (): my.package.MyHandler
    alternate: cfg://handlers.file

字符串字面量 'cfg://handlers.file' 将以类似于带有 ext:// 前缀的字符串的方式解析,但会在配置本身而不是导入命名空间中查找。该机制允许通过点或索引进行访问,其方式类似于 str.format 提供的方式。因此,给定以下代码段

handlers:
  email:
    class: logging.handlers.SMTPHandler
    mailhost: localhost
    fromaddr: [email protected]
    toaddrs:
      - [email protected]
      - [email protected]
    subject: Houston, we have a problem.

在配置中,字符串 'cfg://handlers' 将解析为键为 handlers 的字典,字符串 'cfg://handlers.email' 将解析为 handlers 字典中键为 email 的字典,依此类推。字符串 'cfg://handlers.email.toaddrs[1]' 将解析为 '[email protected]',字符串 'cfg://handlers.email.toaddrs[0]' 将解析为值 '[email protected]'。可以使用 'cfg://handlers.email.subject' 或等效的 'cfg://handlers.email[subject]' 访问 subject 值。仅当键包含空格或非字母数字字符时才需要使用后一种形式。如果索引值仅由十进制数字组成,则将尝试使用相应的整数值进行访问,如果需要,将回退到字符串值。

给定一个字符串 cfg://handlers.myhandler.mykey.123,这将解析为 config_dict['handlers']['myhandler']['mykey']['123']。如果字符串指定为 cfg://handlers.myhandler.mykey[123],系统将尝试从 config_dict['handlers']['myhandler']['mykey'][123] 检索值,如果失败则回退到 config_dict['handlers']['myhandler']['mykey']['123']

导入解析和自定义导入器

默认情况下,导入解析使用内置的 __import__() 函数来执行导入。您可能希望将其替换为您自己的导入机制:如果是这样,您可以替换 DictConfigurator 或其超类 BaseConfigurator 类的 importer 属性。但是,您需要注意,因为函数是通过描述符从类访问的。如果您使用 Python 可调用对象进行导入,并且希望在类级别而不是实例级别定义它,则需要使用 staticmethod() 包装它。例如

from importlib import import_module
from logging.config import BaseConfigurator

BaseConfigurator.importer = staticmethod(import_module)

如果在配置器_实例_上设置导入可调用对象,则不需要使用 staticmethod() 包装。

配置 QueueHandler 和 QueueListener

如果您想配置 QueueHandler,请注意,这通常与 QueueListener 一起使用,您可以同时配置两者。配置完成后,QueueListener 实例将作为创建的处理程序的 listener 属性可用,而该属性又可以使用 getHandlerByName() 并传递您在配置中为 QueueHandler 使用的名称来供您使用。下面的示例 YAML 代码段显示了用于配置这对的字典架构。

handlers:
  qhand:
    class: logging.handlers.QueueHandler
    queue: my.module.queue_factory
    listener: my.package.CustomListener
    handlers:
      - hand_name_1
      - hand_name_2
      ...

queuelistener 键是可选的。

如果存在 queue 键,则对应的值可以是以下之一

  • queue.Queue 或其子类的实际实例。当然,这只有在您在代码中构造或修改配置字典时才有可能。

  • 一个解析为可调用对象的字符串,该字符串在不带参数调用时返回要使用的 queue.Queue 实例。该可调用对象可以是 queue.Queue 子类或返回合适队列实例的函数,例如 my.module.queue_factory()

  • 一个带有 '()' 键的字典,该字典以 用户定义的对象 中讨论的常用方式构造。此构造的结果应为 queue.Queue 实例。

如果缺少 queue 键,则会创建一个标准的无界 queue.Queue 实例并使用它。

如果存在 listener 键,则对应的值可以是以下之一

  • logging.handlers.QueueListener 的子类。当然,这只有在您在代码中构造或修改配置字典时才有可能。

  • 一个解析为 QueueListener 子类的类的字符串,例如 'my.package.CustomListener'

  • 一个带有 '()' 键的字典,该字典以 用户定义的对象 中讨论的常用方式构造。此构造的结果应为与 QueueListener 初始化程序具有相同签名的可调用对象。

如果缺少 listener 键,则使用 logging.handlers.QueueListener

handlers 键下的值是配置中其他处理程序的名称(未在上面的代码段中显示),这些名称将传递给队列侦听器。

任何自定义队列处理程序和侦听器类都需要使用与 QueueHandlerQueueListener 相同的初始化签名来定义。

3.12 版新增。

配置文件格式

fileConfig() 理解的配置文件格式基于 configparser 功能。该文件必须包含名为 [loggers][handlers][formatters] 的部分,这些部分按名称标识文件中定义的每种类型的实体。对于每个此类实体,都有一个单独的部分标识如何配置该实体。因此,对于 [loggers] 部分中名为 log01 的记录器,相关的配置详细信息保存在 [logger_log01] 部分中。类似地,[handlers] 部分中名为 hand01 的处理程序会将其配置保存在名为 [handler_hand01] 的部分中,而 [formatters] 部分中名为 form01 的格式化程序会将其配置指定在名为 [formatter_form01] 的部分中。根记录器配置必须在名为 [logger_root] 的部分中指定。

注意

fileConfig() API 比 dictConfig() API 更旧,并且不提供涵盖日志记录某些方面的功能。例如,您无法使用 fileConfig() 配置 Filter 对象,这些对象提供超出简单整数级别的消息过滤。如果需要在日志记录配置中包含 Filter 的实例,则需要使用 dictConfig()。请注意,配置功能的未来增强将添加到 dictConfig() 中,因此在方便的时候,值得考虑过渡到这个更新的 API。

下面给出了文件中这些部分的示例。

[loggers]
keys=root,log02,log03,log04,log05,log06,log07

[handlers]
keys=hand01,hand02,hand03,hand04,hand05,hand06,hand07,hand08,hand09

[formatters]
keys=form01,form02,form03,form04,form05,form06,form07,form08,form09

根记录器必须指定一个级别和一个处理程序列表。下面给出了根记录器部分的示例。

[logger_root]
level=NOTSET
handlers=hand01

level 条目可以是 DEBUG、INFO、WARNING、ERROR、CRITICALNOTSET 之一。仅对于根记录器,NOTSET 表示将记录所有消息。级别值在 logging 包的命名空间中进行 评估

handlers 条目是以逗号分隔的处理程序名称列表,这些名称必须出现在 [handlers] 部分中。这些名称必须出现在 [handlers] 部分中,并在配置文件中具有相应的节。

对于根记录器以外的记录器,需要一些额外的信息。以下示例对此进行了说明。

[logger_parser]
level=DEBUG
handlers=hand01
propagate=1
qualname=compiler.parser

levelhandlers 条目的解释与根记录器相同,不同之处在于,如果非根记录器的级别指定为 NOTSET,则系统会查询层次结构中更高的记录器,以确定该记录器的有效级别。propagate 条目设置为 1 表示消息必须从此记录器传播到记录器层次结构中更高的处理程序,设置为 0 表示消息**不**传播到层次结构中更高的处理程序。qualname 条目是记录器的分层通道名称,也就是说应用程序用来获取记录器的名称。

指定处理程序配置的部分如下例所示。

[handler_hand01]
class=StreamHandler
level=NOTSET
formatter=form01
args=(sys.stdout,)

class 条目指示处理程序的类(由 logging 包命名空间中的 eval() 确定)。level 的解释与记录器相同,NOTSET 表示“记录所有内容”。

formatter 条目指示此处理程序的格式化程序的键名。如果为空,则使用默认格式化程序 (logging._defaultFormatter)。如果指定了名称,则该名称必须出现在 [formatters] 部分中,并在配置文件中具有相应的节。

args 条目在 logging 包的命名空间中进行 评估 时,是处理程序类构造函数的参数列表。有关如何构造典型条目的信息,请参阅相关处理程序的构造函数或以下示例。如果未提供,则默认为 ()

可选的 kwargs 条目在 logging 包的命名空间中进行 评估 时,是处理程序类构造函数的关键字参数字典。如果未提供,则默认为 {}

[handler_hand02]
class=FileHandler
level=DEBUG
formatter=form02
args=('python.log', 'w')

[handler_hand03]
class=handlers.SocketHandler
level=INFO
formatter=form03
args=('localhost', handlers.DEFAULT_TCP_LOGGING_PORT)

[handler_hand04]
class=handlers.DatagramHandler
level=WARN
formatter=form04
args=('localhost', handlers.DEFAULT_UDP_LOGGING_PORT)

[handler_hand05]
class=handlers.SysLogHandler
level=ERROR
formatter=form05
args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER)

[handler_hand06]
class=handlers.NTEventLogHandler
level=CRITICAL
formatter=form06
args=('Python Application', '', 'Application')

[handler_hand07]
class=handlers.SMTPHandler
level=WARN
formatter=form07
args=('localhost', 'from@abc', ['user1@abc', 'user2@xyz'], 'Logger Subject')
kwargs={'timeout': 10.0}

[handler_hand08]
class=handlers.MemoryHandler
level=NOTSET
formatter=form08
target=
args=(10, ERROR)

[handler_hand09]
class=handlers.HTTPHandler
level=NOTSET
formatter=form09
args=('localhost:9022', '/log', 'GET')
kwargs={'secure': True}

指定格式化程序配置的部分如下例所示。

[formatter_form01]
format=F1 %(asctime)s %(levelname)s %(message)s %(customfield)s
datefmt=
style=%
validate=True
defaults={'customfield': 'defaultvalue'}
class=logging.Formatter

格式化程序配置的参数与字典架构 formatters 部分 中的键相同。

defaults 条目在 logging 包的命名空间中进行 评估 时,是自定义格式字段的默认值字典。如果未提供,则默认为 None

注意

由于使用了如上所述的 eval(),因此使用 listen() 通过套接字发送和接收配置可能会带来安全风险。风险仅限于多个互不信任的用户在同一台机器上运行代码的情况;有关更多信息,请参阅 listen() 文档。

另请参阅

模块 logging

日志记录模块的 API 参考。

模块 logging.handlers

日志记录模块中包含的有用处理程序。