On this page
15.8. logging.config —日志记录配置
Important
此页面仅包含参考信息。有关教程,请参阅
本节介绍用于配置日志记录模块的 API。
15.8.1. 配置Function
以下Function配置日志记录模块。它们位于logging.config模块中。它们的使用是可选的-您可以使用这些Function或pass调用主 API(在logging本身中定义)并定义在logging或logging.handlers中语句的处理程序来配置日志记录模块。
logging.config.
dictConfig
(* config *)
Note
从字典中获取日志记录配置。该字典的内容在下面的配置字典架构中描述。
如果在配置过程中遇到错误,此Function将使用适当的描述性消息引发ValueError,TypeError,AttributeError或ImportError。以下是(可能不完整)会引起错误的条件列表:
level
不是字符串,也不是与实际日志记录级别不对应的字符串。
propagate
值,不是布尔值。没有对应目的地的 ID。
在增量调用期间发现不存在的处理程序 ID。
无效的 Logger 名称。
无法解析为内部或外部对象。
解析由
DictConfigurator
类执行,该类的构造函数pass用于配置的字典传递,并且具有configure()
方法。 logging.config模块具有一个可调用属性dictConfigClass
,该属性最初设置为DictConfigurator
。您可以使用自己合适的实现替换dictConfigClass
的值。dictConfig()调用
dictConfigClass
传递指定的字典,然后对返回的对象调用configure()
方法以使配置生效:def dictConfig(config): dictConfigClass(config).configure()
例如,
DictConfigurator
的子类可以在其自己的init()中调用DictConfigurator.__init__()
,然后设置自定义前缀,这些前缀可在后续的configure()
调用中使用。dictConfigClass
将绑定到这个新的子类,然后可以完全按照默认的非自定义状态调用dictConfig()。
2.7 版的新Function。
logging.config.
fileConfig
(* fname , defaults = None , disable_existing_loggers = True *)- 从名为* fname *的
configparser
格式文件中读取日志配置。文件格式应为配置文件格式中所述。可以从应用程序中多次调用此Function,从而使finally用户可以从各种预先设置的配置中进行选择(如果开发人员提供了一种机制来呈现选择并加载所选的配置)。
- 从名为* fname *的
Parameters
-
- defaults –可以在此参数中指定要传递给 ConfigParser 的默认值。
-
disable_existing_loggers –如果指定为
False
,则启用此调用时存在的 Logger。默认值为True
,因为它以向后兼容的方式启用了旧的行为。此行为是要禁用所有现有 Logger,除非它们或它们的祖先在记录配置中被明确命名。
在 2.6 版中进行了更改:添加了disable_existing_loggers
关键字参数。以前,现有的 Logger 总是被禁用。
logging.config.
listen
(* port = DEFAULT_LOGGING_CONFIG_PORT *)- 在指定端口上启动套接字服务器,并侦听新配置。如果未指定端口,则使用模块的默认
DEFAULT_LOGGING_CONFIG_PORT
。日志配置将作为适合fileConfig()处理的文件发送。返回一个Thread实例,您可以在该实例上调用start()来启动服务器,并且可以在适当的情况下join()。要停止服务器,请调用stopListening()。
- 在指定端口上启动套接字服务器,并侦听新配置。如果未指定端口,则使用模块的默认
要将配置发送到套接字,请读入配置文件,然后以字节串的形式将其发送到套接字,然后以struct.pack('>L', n)
的形式将四字节长度的字符串打包成二进制。
Note
15.8.2. 配置字典架构
描述日志配置需要列出要创建的各种对象以及它们之间的连接。例如,您可以创建一个名为“ console”的处理程序,然后说名为“ startup”的 Logger 会将其消息发送到“ console”处理程序。这些对象不限于logging模块提供的对象,因为您可以编写自己的格式化程序或处理程序类。这些类的参数可能还需要包含sys.stderr
之类的外部对象。下面的Object connections中定义了用于描述这些对象和连接的语法。
15.8.2.1. 词典架构详细信息
传递给dictConfig()的字典必须包含以下键:
-
- version *-设置为代表架构版本的整数值。当前唯一的有效值为 1,但是拥有此密钥可以使架构 Developing,同时仍然保持向后兼容性。
所有其他键都是可选的,但是如果存在,它们将按以下说明进行解释。在下面提到“配置命令”的所有情况下,都将检查它的特殊'()'
键以查看是否需要自定义实例。如果是这样,则以下User-defined objects中描述的机制用于创建实例;否则,上下文用于确定实例化什么。
-
- formatters *-相应的值将是一个字典,其中每个键是一个格式化程序 ID,每个值是一个描述如何配置相应的Formatter实例的字典。
在配置字典中搜索键format
和datefmt
(默认值为None
),并将它们用于构建Formatter实例。
-
- filters *-相应的值将是一个字典,其中每个键是一个过滤器 ID,每个值是一个描述如何配置相应的 Filter 实例的字典。
在配置字典中搜索键name
(默认为空字符串),该键用于构造logging.Filter实例。
-
- handlers *-相应的值将是一个 dict,其中每个键是一个处理程序 id,每个值是一个 dict,用于描述如何配置相应的 Handler 实例。
在配置字典中搜索以下键:
class
(必填)。这是处理程序类的完全限定名称。level
(可选)。处理程序的级别。formatter
(可选)。此处理程序的格式化程序的 ID。filters
(可选)。此处理程序的过滤器 ID 的列表。
所有* other *键都作为关键字参数传递给处理程序的构造函数。例如,给出片段:
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
的处理程序将以sys.stdout
作为基础流实例化为logging.StreamHandler。 ID 为file
的处理程序使用关键字参数filename='logconfig.log', maxBytes=1024, backupCount=3
实例化为logging.handlers.RotatingFileHandler。
-
- loggers *-相应的值将是一个字典,其中每个键是一个 Logger 名称,每个值是一个描述如何配置相应 Logger 实例的字典。
在配置字典中搜索以下键:
level
(可选)。Logger 的级别。propagate
(可选)。Logger 的传播设置。filters
(可选)。此 Logger 的过滤器 ID 的列表。handlers
(可选)。此 Logger 的处理程序的 ID 列表。
指定的 Logger 将根据指定的级别,传播,过滤器和处理程序进行配置。
-
- root *-这将是 rootLogger 的配置。除
propagate
设置不适用外,配置处理将与所有 Logger 相同。
- root *-这将是 rootLogger 的配置。除
-
- incremental *-是否将配置解释为现有配置的增量。该值默认为
False
,这意味着指定的配置将使用与现有fileConfig() API 相同的语义替换现有配置。
- incremental *-是否将配置解释为现有配置的增量。该值默认为
如果指定的值为True
,则按照Incremental Configuration一节中的描述处理配置。
-
- disable_existing_loggers -是否要禁用任何现有的 Logger。此设置镜像fileConfig()中具有相同名称的参数。如果不存在,则此参数默认为
True
。如果 incremental *为True
,则忽略此值。
- disable_existing_loggers -是否要禁用任何现有的 Logger。此设置镜像fileConfig()中具有相同名称的参数。如果不存在,则此参数默认为
15.8.2.2. 增量配置
很难为增量配置提供完全的灵 Active。例如,因为诸如过滤器和格式化程序之类的对象是匿名的,所以一旦构建了配置,就无法在扩充配置时引用此类匿名对象。
此外,一旦配置成功,就没有必要在运行时随意更改 Logger,处理程序,过滤器,格式化程序的对象图;Logger 和处理程序的详细程度可以仅pass设置级别来控制(对于 Logger,还可以设置传播标志)。在多线程环境中,以安全的方式任意更改对象图是有问题的。尽管并非没有可能,但这样做的好处并不值得其增加实施的复杂性。
因此,当配置字典的incremental
键存在且为True
时,系统将完全忽略任何formatters
和filters
条目,并且仅处理handlers
条目中的level
设置以及loggers
和root
条目中的level
和propagate
设置。 。
在配置字典中使用一个值可以使配置作为腌渍字典pass网络发送到套接字侦听器。因此,长时间运行的应用程序的日志记录详细程度可以随着时间而改变,而无需停止和重新启动应用程序。
15.8.2.3. 对象连接
该模式描述了一组记录对象-Logger,处理程序,格式化程序,过滤器-它们在对象图中相互连接。因此,该模式需要表示对象之间的连接。例如,假设配置后,特定的 Logger 便已附加了特定的处理程序。出于讨论的目的,我们可以说 Logger 代表两者之间连接的源,而处理程序代表两者的连接。当然,在已配置的对象中,这由 Logger 代表对处理程序的引用来表示。在配置命令中,这是pass给每个目标对象一个明确标识它的 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 源代码格式更具可读性.)
Logger 的 ID 是 Logger 名称,将以编程方式使用它们来获取对这些 Logger 的引用,例如foo.bar.baz
。格式化程序和过滤器的 ID 可以是任何字符串值(例如上面的brief
,precise
),并且它们是瞬态的,因为它们仅对处理配置字典有意义,并用于确定对象之间的连接,并且当配置调用完成。
上面的代码片段指示名为foo.bar.baz
的 Logger 应附加两个处理程序,这些处理程序由处理程序 ID h1
和h2
进行描述。 h1
的格式化程序由 id brief
描述,h2
的格式化程序由 id precise
描述。
15.8.2.4. 用户定义的对象
该模式支持用于处理程序,过滤器和格式化程序的用户定义对象。 (对于不同的实例,Logger 不需要具有不同的类型,因此在此配置模式中不支持用户定义的 Logger 类.)
用字典描述要配置的对象,并详细说明它们的配置。在某些地方,日志记录系统将能够从上下文中推断出如何实例化对象,但是当要实例化用户定义的对象时,系统将不知道如何执行此操作。为了为用户定义的对象实例化提供完全的灵 Active,用户需要提供一个“工厂”(可调用对象),该对象可pass配置字典进行调用并返回实例化的对象。这是pass在特殊键'()'
下提供了到工厂的绝对导入路径来表示的。这是一个具体的例子:
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 源代码形式显示的brief
和default
格式化程序具有配置子词典:
{
'format' : '%(message)s'
}
and:
{
'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
}
其中包含特殊键'()'
,这意味着需要用户定义的实例化。在这种情况下,将使用指定的工厂可调用对象。如果它是一个实际的可调用对象,则将直接使用它-否则,如果您指定一个字符串(如示例中所示),则将使用常规的导入机制来定位该实际的可调用对象。将使用配置子词典中的 remaining 项目作为关键字参数来调用可调用对象。在上面的示例中,将假定 ID custom
的格式化程序是pass调用返回的:
my.package.customFormatterFactory(bar='baz', spam=99.9, answer=42)
键'()'
已用作特殊键,因为它不是有效的关键字参数名称,因此不会与调用中使用的关键字参数名称冲突。 '()'
还充当助记符,表示相应的值是可调用的。
15.8.2.5. 访问外部对象
有时,某个配置需要引用该配置外部的对象,例如sys.stderr
。如果使用 python 代码构造配置字典,这很简单,但是当pass文本文件(例如 JSON,YAML)提供配置时会出现问题。在文本文件中,没有标准的方法可以将sys.stderr
与 Literals 字符串'sys.stderr'
区分开。为了促进这种区分,配置系统会在字符串值中查找某些特殊前缀,并对其进行特殊处理。例如,如果在配置中将 Literals 字符串'ext://sys.stderr'
作为值提供,则将剥离ext://
并使用常规导入机制处理该值的其余部分。
此类前缀的处理方式类似于协议处理:存在一种通用机制来查找与正则表达式^(?P<prefix>[a-z]+)://(?P<suffix>.*)$
匹配的前缀,从而,如果识别出prefix
,则以前缀相关的方式处理suffix
,处理结果替换字符串值。如果未识别前缀,则字符串值将保持不变。
15.8.2.6. 访问内部对象
除外部对象外,有时还需要引用配置中的对象。配置系统将针对它所了解的内容隐式完成此操作。例如,Logger 或处理程序中level
的字符串值'DEBUG'
将自动转换为值logging.DEBUG
,并且handlers
,filters
和formatter
条目将获取对象 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
Literals 字符串'cfg://handlers.file'
的解析方式类似于带有ext://
前缀的字符串,但查找的是配置本身而不是导入名称空间。该机制允许按点或按索引访问,类似于str.format
提供的方式。因此,给出以下代码段:
handlers:
email:
class: logging.handlers.SMTPHandler
mailhost: localhost
fromaddr: my_app@domain.tld
toaddrs:
- support_team@domain.tld
- dev_team@domain.tld
subject: Houston, we have a problem.
在配置中,字符串'cfg://handlers'
将解析为具有键handlers
的字典,字符串'cfg://handlers.email
将解析为具有handlers
字典中的键email
的字典,依此类推。字符串'cfg://handlers.email.toaddrs[1]
将解析为'dev_team.domain.tld'
,而字符串'cfg://handlers.email.toaddrs[0]'
将解析为值'support_team@domain.tld'
。可以使用'cfg://handlers.email.subject'
或等效地'cfg://handlers.email[subject]'
来访问subject
值。仅当键包含空格或非字母数字字符时,才需要使用后一种形式。如果索引值仅由十进制数字组成,则将try使用相应的整数值进行访问,如果需要,则返回到字符串值。
给定字符串cfg://handlers.myhandler.mykey.123
,它将解析为config_dict['handlers']['myhandler']['mykey']['123']
。如果将字符串指定为cfg://handlers.myhandler.mykey[123]
,则系统将try从config_dict['handlers']['myhandler']['mykey'][123]
检索值,如果失败则回退到config_dict['handlers']['myhandler']['mykey']['123']
。
15.8.2.7. 导入分辨率和自定义 import 商
默认情况下,导入分辨率使用内置的import()函数进行导入。您可能希望用自己的导入机制替换它:如果是这样,则可以替换DictConfigurator
的importer
属性或其超类BaseConfigurator
类。但是,由于需要pass Descriptors 从类访问函数的方式,因此需要小心。如果您使用可调用的 Python 进行导入,并且想要在类级别而不是实例级别定义它,则需要使用staticmethod()进行包装。例如:
from importlib import import_module
from logging.config import BaseConfigurator
BaseConfigurator.importer = staticmethod(import_module)
如果要在配置程序* instance *上设置可调用的 import,则无需使用staticmethod()换行。
15.8.3. 配置文件格式
fileConfig()理解的配置文件格式基于configparser
Function。该文件必须包含称为[loggers]
,[handlers]
和[formatters]
的部分,这些部分pass名称标识文件中定义的每种类型的实体。对于每个此类实体,都有一个单独的部分来标识该实体的配置方式。因此,对于[loggers]
部分中名为log01
的 Logger,相关的配置详细信息保留在[logger_log01]
部分中。同样,在[handlers]
部分中名为hand01
的处理程序将其配置保存在名为[handler_hand01]
的部分中,而在[formatters]
部分中名为form01
的格式化程序的配置将在其名为[formatter_form01]
的部分中指定。根 Logger 配置必须在名为[logger_root]
的部分中指定。
Note
fileConfig() API 比dictConfig() API 旧,并且不提供覆盖日志记录某些方面的Function。例如,您不能配置Filter对象,该对象使用fileConfig()过滤超出简单整数级别的消息。如果需要在日志记录配置中包含Filter的实例,则需要使用dictConfig()。请注意,将来对配置Function的增强将添加到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 必须指定级别和处理程序列表。以下是根 Logger 部分的示例。
[logger_root]
level=NOTSET
handlers=hand01
level
条目可以是DEBUG, INFO, WARNING, ERROR, CRITICAL
或NOTSET
之一。仅对于根 Logger,NOTSET
表示将记录所有消息。在logging
包的名称空间的上下文中对级别值eval()求值。
handlers
条目是处理程序名称的逗号分隔列表,该列表必须出现在[handlers]
部分中。这些名称必须出现在[handlers]
部分中,并且在配置文件中具有相应的部分。
对于除根 Logger 以外的其他 Logger,还需要一些其他信息。下面的示例对此进行了说明。
[logger_parser]
level=DEBUG
handlers=hand01
propagate=1
qualname=compiler.parser
level
和handlers
条目的解释方式与根 Logger 相同,不同的是,如果将非根 Logger 的级别指定为NOTSET
,则系统将咨询层次结构中更高级别的 Logger,以确定 Logger 的有效级别。 propagate
条目设置为 1 表示消息必须从此 Logger 传播到更高级别的处理程序,或设置为 0 表示消息“不”传播到该层次结构的处理程序。 qualname
条目是 Logger 的分层通道名称,即应用程序用来获取 Logger 的名称。
指定处理程序配置的部分如下所示。
[handler_hand01]
class=StreamHandler
level=NOTSET
formatter=form01
args=(sys.stdout,)
class
条目指示处理程序的类(由logging
包的命名空间中的eval()确定)。 level
被解释为 Logger,而NOTSET
被认为是“记录所有内容”。
在 2.6 版中进行了更改:添加了对将处理程序的类解析为点分模块和类名的支持。
formatter
条目指示此处理程序的格式化程序的键名。如果为空白,则使用默认格式器(logging._defaultFormatter
)。如果指定了名称,则该名称必须出现在[formatters]
部分中,并且在配置文件中具有相应的部分。
在logging
包的命名空间的上下文中eval()时,args
条目是处理程序类的构造函数的参数列表。请参阅相关处理程序的构造函数,或参考以下示例,以了解如何构造典型条目。
[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')
[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')
指定格式化程序配置的部分由以下内容代表。
[formatter_form01]
format=F1 %(asctime)s %(levelname)s %(message)s
datefmt=
class=logging.Formatter
format
条目是整体格式字符串,而datefmt
条目是strftime()
兼容的日期/时间格式字符串。如果为空,则该包将替换 ISO8601 格式的日期/时间,这几乎等同于指定日期格式字符串'%Y-%m-%d %H:%M:%S'
。 ISO8601 格式还指定了毫秒,并使用逗号分隔符将其附加到使用上述格式字符串的结果中。 ISO8601 格式的时间示例为2003-01-23 00:29:50,411
。
class
条目是可选的。它指示格式化程序的类的名称(作为点缀的模块和类名称.)此选项对于实例化Formatter子类很有用。 Formatter的子类可以扩展或压缩格式显示异常回溯。
Note
See also
Module logging
日志记录模块的 API 参考。
Module logging.handlers
日志记录模块随附的有用处理程序。