logging.handlers
— 日志处理程序¶
包中提供了以下有用的处理程序。请注意,其中三个处理程序(StreamHandler
、FileHandler
和 NullHandler
)实际上是在 logging
模块本身中定义的,但已在此处与其他处理程序一起记录。
StreamHandler¶
StreamHandler
类位于核心 logging
包中,将日志输出发送到诸如 sys.stdout、sys.stderr 或任何类文件对象(或更确切地说,任何支持 write()
和 flush()
方法的对象)的流中。
- class logging.StreamHandler(stream=None)¶
返回
StreamHandler
类的新实例。如果指定了 stream,则实例将使用它进行日志输出;否则,将使用 sys.stderr。- emit(record)¶
如果指定了格式化器,则使用它来格式化记录。然后将记录写入流,后跟
terminator
。如果存在异常信息,则使用traceback.print_exception()
格式化并附加到流中。
- setStream(stream)¶
如果流不同,则将实例的流设置为指定值。在设置新流之前,会刷新旧流。
- 参数:
stream – 处理程序应使用的流。
- 返回:
如果流已更改,则返回旧流,否则返回
None
。
在 3.7 版本加入。
- terminator¶
将格式化记录写入流时用作终止符的字符串。默认值为
'\n'
。如果您不想要换行符终止,可以将处理程序实例的
terminator
属性设置为空字符串。在早期版本中,终止符硬编码为
'\n'
。在 3.2 版本加入。
FileHandler¶
FileHandler
类位于核心 logging
包中,将日志输出发送到磁盘文件。它继承了 StreamHandler
的输出功能。
- class logging.FileHandler(filename, mode='a', encoding=None, delay=False, errors=None)¶
返回
FileHandler
类的新实例。打开指定的文件并将其用作日志记录的流。如果未指定 mode,则使用'a'
。如果 encoding 不是None
,则使用该编码打开文件。如果 delay 为真,则文件打开会推迟到第一次调用emit()
。默认情况下,文件无限增长。如果指定了 errors,则用于确定如何处理编码错误。版本 3.6 中的更改: 除了字符串值之外,filename 参数也接受
Path
对象。版本 3.9 中的更改: 添加了 errors 参数。
- close()¶
关闭文件。
NullHandler¶
在 3.1 版本加入。
NullHandler
类位于核心 logging
包中,不执行任何格式化或输出。它本质上是一个“无操作”处理程序,供库开发人员使用。
- class logging.NullHandler¶
返回
NullHandler
类的新实例。- emit(record)¶
此方法不执行任何操作。
- handle(record)¶
此方法不执行任何操作。
- createLock()¶
此方法为锁返回
None
,因为没有需要序列化访问的基础 I/O。
有关如何使用 NullHandler
的更多信息,请参见 为库配置日志记录。
WatchedFileHandler¶
WatchedFileHandler
类位于 logging.handlers
模块中,它是一个 FileHandler
,用于监视其正在记录的文件。如果文件发生更改,它将使用文件名关闭并重新打开文件。
由于使用 newsyslog 和 logrotate 等程序执行日志文件轮换,文件可能会发生更改。此处理程序旨在用于 Unix/Linux 环境下,监视文件以查看自上次发出以来是否已更改。(如果文件的设备或 inode 发生更改,则认为文件已更改。)如果文件已更改,则关闭旧文件流,并打开文件以获取新流。
此处理程序不适用于 Windows,因为在 Windows 下无法移动或重命名打开的日志文件 - 日志记录以独占锁打开文件 - 因此不需要这样的处理程序。此外,Windows 不支持 ST_INO;stat()
始终为此值返回零。
- class logging.handlers.WatchedFileHandler(filename, mode='a', encoding=None, delay=False, errors=None)¶
返回
WatchedFileHandler
类的新实例。打开指定的文件并将其用作日志记录的流。如果未指定 mode,则使用'a'
。如果 encoding 不是None
,则使用该编码打开文件。如果 delay 为真,则文件打开会推迟到第一次调用emit()
。默认情况下,文件无限增长。如果提供了 errors,它将确定如何处理编码错误。版本 3.6 中的更改: 除了字符串值之外,filename 参数也接受
Path
对象。版本 3.9 中的更改: 添加了 errors 参数。
- reopenIfNeeded()¶
检查文件是否已更改。如果已更改,则刷新并关闭现有流,然后重新打开文件,通常作为将记录输出到文件的前奏。
在 3.6 版本加入。
- emit(record)¶
将记录输出到文件,但首先调用
reopenIfNeeded()
以在文件更改时重新打开文件。
BaseRotatingHandler¶
BaseRotatingHandler
类位于 logging.handlers
模块中,是轮转文件处理程序 RotatingFileHandler
和 TimedRotatingFileHandler
的基类。您不需要实例化此类别,但它具有您可能需要覆盖的属性和方法。
- class logging.handlers.BaseRotatingHandler(filename, mode, encoding=None, delay=False, errors=None)¶
参数与
FileHandler
相同。属性为- namer¶
如果此属性设置为可调用对象,则
rotation_filename()
方法会委托给此可调用对象。传递给可调用对象的参数是传递给rotation_filename()
的参数。备注
在轮转过程中,命名器函数会被多次调用,因此它应该尽可能简单和快速。它还应该在给定输入的情况下每次返回相同的输出,否则轮转行为可能无法按预期工作。
值得注意的是,在使用命名器时应注意保留文件名中用于轮转的某些属性。例如,
RotatingFileHandler
期望有一组日志文件,其名称包含连续的整数,以便轮转按预期工作,而TimedRotatingFileHandler
通过确定要删除的最旧文件来删除旧日志文件(基于传递给处理程序初始化器的backupCount
参数)。为此,文件名应该可以使用文件名的日期/时间部分进行排序,并且命名器需要遵守这一点。(如果需要不遵守此方案的命名器,则需要在TimedRotatingFileHandler
的子类中使用它,该子类会覆盖getFilesToDelete()
方法以适应自定义命名方案。)在 3.3 版本加入。
- rotation_filename(default_name)¶
轮转时修改日志文件的文件名。
提供此功能是为了可以提供自定义文件名。
默认实现调用处理程序的“namer”属性(如果它是可调用对象),将默认名称传递给它。如果属性不可调用(默认为
None
),则返回名称不变。- 参数:
default_name – 日志文件的默认名称。
在 3.3 版本加入。
- rotate(source, dest)¶
轮转时,轮转当前日志。
默认实现调用处理程序的“rotator”属性(如果它是可调用对象),将源和目标参数传递给它。如果属性不可调用(默认为
None
),则简单地将源重命名为目标。- 参数:
source – 源文件名。这通常是基本文件名,例如 'test.log'。
dest – 目标文件名。这通常是源文件轮转到的目标,例如 'test.log.1'。
在 3.3 版本加入。
属性存在的原因是,您无需进行子类化 - 您可以将相同的可调用对象用于 RotatingFileHandler
和 TimedRotatingFileHandler
的实例。如果命名器或轮转器可调用对象引发异常,则将以与 emit()
调用期间的任何其他异常相同的方式处理此异常,即通过处理程序的 handleError()
方法。
如果您需要对轮转处理进行更显著的更改,则可以覆盖这些方法。
有关示例,请参阅 使用轮转器和命名器自定义日志轮转处理。
RotatingFileHandler¶
RotatingFileHandler
类位于 logging.handlers
模块中,支持磁盘日志文件的轮转。
- class logging.handlers.RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=False, errors=None)¶
返回
RotatingFileHandler
类的新实例。打开指定的文件并将其用作日志记录的流。如果未指定 mode,则使用'a'
。如果 encoding 不是None
,则使用该编码打开文件。如果 delay 为真,则文件打开会推迟到第一次调用emit()
。默认情况下,文件无限增长。如果提供了 errors,它将确定如何处理编码错误。您可以使用 maxBytes 和 backupCount 值来允许文件在预定大小处 轮转。当即将超出大小时,文件将被关闭并静默打开一个新文件以进行输出。当当前日志文件的长度接近 maxBytes 时,就会发生轮转;但如果 maxBytes 或 backupCount 中任一为零,则永远不会发生轮转,因此您通常希望将 backupCount 设置为至少 1,并具有非零的 maxBytes。当 backupCount 非零时,系统将通过向文件名附加扩展名 '.1'、'.2' 等来保存旧日志文件。例如,如果 backupCount 为 5,基本文件名为
app.log
,您将得到app.log
、app.log.1
、app.log.2
,直至app.log.5
。正在写入的文件始终是app.log
。当此文件填满时,它将被关闭并重命名为app.log.1
,如果文件app.log.1
、app.log.2
等存在,则它们将分别重命名为app.log.2
、app.log.3
等。版本 3.6 中的更改: 除了字符串值之外,filename 参数也接受
Path
对象。版本 3.9 中的更改: 添加了 errors 参数。
- doRollover()¶
执行如上所述的轮转。
- emit(record)¶
将记录输出到文件,并按前面所述处理轮转。
- shouldRollover(record)¶
检查提供的记录是否会导致文件超出配置的大小限制。
TimedRotatingFileHandler¶
TimedRotatingFileHandler
类位于 logging.handlers
模块中,支持以特定时间间隔轮转磁盘日志文件。
- class logging.handlers.TimedRotatingFileHandler(filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None, errors=None)¶
返回
TimedRotatingFileHandler
类的新实例。打开指定文件并将其用作日志记录流。轮转时还会设置文件名后缀。轮转基于 when 和 interval 的乘积进行。您可以使用 when 指定 interval 的类型。可能的值列表如下。请注意,它们不区分大小写。
值
间隔类型
atTime 的使用方式/时间
'S'
秒
忽略
'M'
分钟
忽略
'H'
小时
忽略
'D'
天
忽略
'W0'-'W6'
工作日 (0=星期一)
用于计算初始轮转时间
'midnight'
如果未指定 atTime,则在午夜轮转;否则在 atTime 时间轮转
用于计算初始轮转时间
使用基于工作日的轮转时,星期一指定“W0”,星期二指定“W1”,依此类推,直到星期日指定“W6”。在这种情况下,不使用为 interval 传递的值。
系统将通过向文件名附加扩展名来保存旧日志文件。扩展名基于日期和时间,使用 strftime 格式
%Y-%m-%d_%H-%M-%S
或其前导部分,具体取决于轮转间隔。首次计算下一个轮转时间(创建处理程序时)时,使用现有日志文件的最后修改时间,或者使用当前时间来计算下次轮转何时发生。
如果 utc 参数为真,则使用 UTC 时间;否则使用本地时间。
如果 backupCount 非零,则最多保留 backupCount 个文件,如果轮转时创建更多文件,则删除最旧的文件。删除逻辑使用间隔来确定要删除哪些文件,因此更改间隔可能会留下旧文件。
如果 delay 为真,则文件打开会推迟到第一次调用
emit()
。如果 atTime 不是
None
,则它必须是datetime.time
实例,用于指定在轮转设置为“午夜”或“特定工作日”发生时,轮转发生的具体时间。请注意,在这些情况下,atTime 值实际上用于计算 初始 轮转,后续轮转将通过正常的间隔计算进行计算。如果指定了 errors,则用于确定如何处理编码错误。
备注
初始轮转时间的计算在处理程序初始化时完成。后续轮转时间的计算仅在轮转发生时完成,而轮转仅在发出输出时发生。如果不记住这一点,可能会导致一些混淆。例如,如果将间隔设置为“每分钟”,这并不意味着您总是会看到日志文件(文件名中)的时间间隔为一分钟;如果在应用程序执行期间,日志输出生成频率高于每分钟一次,那么 您可以期望看到日志文件的时间间隔为一分钟。另一方面,如果日志消息每五分钟才输出一次(例如),则文件时间中会出现间隙,对应于没有输出(因此没有轮转)的分钟。
版本 3.4 中的更改: 添加了 atTime 参数。
版本 3.6 中的更改: 除了字符串值之外,filename 参数也接受
Path
对象。版本 3.9 中的更改: 添加了 errors 参数。
- doRollover()¶
执行如上所述的轮转。
- emit(record)¶
将记录输出到文件,并按上述方式处理轮转。
- getFilesToDelete()¶
返回一个文件名列表,这些文件应作为轮转的一部分删除。这些
- shouldRollover(record)¶
查看是否已过去足够的时间进行轮转,如果已过去,则计算下一个轮转时间。
SocketHandler¶
SocketHandler
类位于 logging.handlers
模块中,将日志输出发送到网络套接字。基类使用 TCP 套接字。
- class logging.handlers.SocketHandler(host, port)¶
返回
SocketHandler
类的新实例,用于与远程机器通信,其地址由 host 和 port 给出。版本 3.4 中的更改: 如果
port
指定为None
,则使用host
中的值创建 Unix 域套接字 - 否则,创建 TCP 套接字。- close()¶
关闭套接字。
- emit()¶
将记录的属性字典序列化为二进制格式并写入套接字。如果套接字出现错误,则静默丢弃数据包。如果连接先前已丢失,则重新建立连接。要在接收端将记录反序列化为
LogRecord
,请使用makeLogRecord()
函数。
- makeSocket()¶
这是一个工厂方法,允许子类定义它们想要的精确套接字类型。默认实现创建一个 TCP 套接字 (
socket.SOCK_STREAM
)。
- makePickle(record)¶
将记录的属性字典序列化为二进制格式,并带有长度前缀,然后返回它以准备通过套接字传输。此操作的详细信息等效于
data = pickle.dumps(record_attr_dict, 1) datalen = struct.pack('>L', len(data)) return datalen + data
请注意,pickle 并非完全安全。如果您担心安全性,您可能希望覆盖此方法以实现更安全的机制。例如,您可以使用 HMAC 签署 pickle 并在接收端验证它们,或者您可以禁用接收端全局对象的反序列化。
- send(packet)¶
将序列化的字节字符串 packet 发送到套接字。发送的字节字符串的格式如
makePickle()
的文档中所述。此函数允许部分发送,这可能在网络繁忙时发生。
- createSocket()¶
尝试创建套接字;失败时,使用指数退避算法。初始失败时,处理程序将丢弃它尝试发送的消息。当后续消息由同一实例处理时,它不会尝试连接,直到经过一段时间。默认参数是:初始延迟为一秒,如果延迟后仍无法建立连接,处理程序将每次将延迟加倍,最多 30 秒。
此行为由以下处理程序属性控制
retryStart
(初始延迟,默认为 1.0 秒)。retryFactor
(乘数,默认为 2.0)。retryMax
(最大延迟,默认为 30.0 秒)。
这意味着如果远程侦听器在处理程序使用 后 启动,您可能会丢失消息(因为处理程序在延迟过去之前甚至不会尝试连接,而只是在延迟期间静默丢弃消息)。
DatagramHandler¶
DatagramHandler
类位于 logging.handlers
模块中,它继承自 SocketHandler
以支持通过 UDP 套接字发送日志消息。
- class logging.handlers.DatagramHandler(host, port)¶
返回
DatagramHandler
类的新实例,旨在与地址由 host 和 port 给出的远程机器通信。备注
由于 UDP 不是流式协议,因此此处理程序的实例与 host 之间没有持久连接。因此,在使用网络套接字时,每次记录事件时都可能需要进行 DNS 查找,这会给系统带来一些延迟。如果这影响了您,您可以自己进行查找,并使用查找到的 IP 地址而不是主机名来初始化此处理程序。
版本 3.4 中的更改: 如果
port
指定为None
,则使用host
中的值创建 Unix 域套接字 - 否则,创建 UDP 套接字。- emit()¶
将记录的属性字典序列化为二进制格式并写入套接字。如果套接字出现错误,则静默丢弃数据包。要在接收端将记录反序列化为
LogRecord
,请使用makeLogRecord()
函数。
- makeSocket()¶
SocketHandler
的工厂方法在此处被覆盖以创建 UDP 套接字 (socket.SOCK_DGRAM
)。
- send(s)¶
将序列化的字节字符串发送到套接字。发送的字节字符串的格式如
SocketHandler.makePickle()
的文档中所述。
SysLogHandler¶
SysLogHandler
类位于 logging.handlers
模块中,支持将日志消息发送到远程或本地 Unix syslog。
- class logging.handlers.SysLogHandler(address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER, socktype=socket.SOCK_DGRAM, timeout=None)¶
返回
SysLogHandler
类的新实例,旨在与远程 Unix 机器通信,其地址以(host, port)
元组的形式由 address 给出。如果未指定 address,则使用('localhost', 514)
。地址用于打开套接字。提供(host, port)
元组的替代方法是提供一个字符串作为地址,例如 '/dev/log'。在这种情况下,Unix 域套接字用于将消息发送到 syslog。如果未指定 facility,则使用LOG_USER
。打开的套接字类型取决于 socktype 参数,该参数默认为socket.SOCK_DGRAM
,从而打开一个 UDP 套接字。要打开 TCP 套接字(用于较新的 syslog 守护进程,例如 rsyslog),请指定socket.SOCK_STREAM
的值。如果指定了 timeout,它将为套接字操作设置超时(以秒为单位)。这有助于防止在 syslog 服务器无法访问时程序无限期挂起。默认情况下,timeout 为None
,表示不应用超时。请注意,如果您的服务器未侦听 UDP 端口 514,
SysLogHandler
可能无法工作。在这种情况下,请检查您应该用于域套接字的地址 - 它取决于系统。例如,在 Linux 上通常是 '/dev/log',但在 OS/X 上是 '/var/run/syslog'。您需要检查您的平台并使用适当的地址(如果您的应用程序需要在多个平台上运行,您可能需要在运行时进行此检查)。在 Windows 上,您几乎必须使用 UDP 选项。备注
在 macOS 12.x (Monterey) 上,Apple 更改了其 syslog 守护进程的行为 - 它不再侦听域套接字。因此,您不能期望
SysLogHandler
在此系统上工作。有关更多信息,请参见 gh-91070。
版本 3.2 中的更改: 添加了 socktype。
版本 3.14 中的更改: 添加了 timeout。
- close()¶
关闭与远程主机的套接字。
- createSocket()¶
尝试创建套接字,如果它不是数据报套接字,则将其连接到另一端。此方法在处理程序初始化期间调用,但如果另一端此时未侦听,则不视为错误 - 如果此时没有套接字,则在发出事件时会再次调用此方法。
在 3.11 版本中新增。
- emit(record)¶
记录被格式化,然后发送到 syslog 服务器。如果存在异常信息,则 不 发送到服务器。
版本 3.2.1 中的更改: (参见:bpo-12168。)在早期版本中,发送到 syslog 守护进程的消息始终以 NUL 字节终止,因为这些守护进程的早期版本期望 NUL 终止的消息 - 即使它不在相关规范 (RFC 5424) 中。这些守护进程的较新版本不期望 NUL 字节,但如果存在则将其剥离,甚至更新的守护进程(更严格遵守 RFC 5424)将 NUL 字节作为消息的一部分传递。
为了更容易地处理所有这些不同的守护进程行为,NUL 字节的附加已通过使用类级属性
append_nul
变为可配置。此属性默认为True
(保留现有行为),但可以在SysLogHandler
实例上设置为False
,以便该实例 不 附加 NUL 终止符。版本 3.3 中的更改: (参见:bpo-12419。)在早期版本中,没有“ident”或“tag”前缀来标识消息源的功能。现在可以使用类级属性指定,该属性默认为
""
以保留现有行为,但可以在SysLogHandler
实例上覆盖,以便该实例将 ident 前置到处理的每条消息。请注意,提供的 ident 必须是文本,而不是字节,并且完全按原样前置到消息中。
- encodePriority(facility, priority)¶
将设施和优先级编码为整数。您可以传入字符串或整数 - 如果传入字符串,则使用内部映射字典将其转换为整数。
符号
LOG_
值在SysLogHandler
中定义,并反映sys/syslog.h
头文件中定义的值。优先级
名称 (字符串)
符号值
alert
LOG_ALERT
crit
或critical
LOG_CRIT
debug
LOG_DEBUG
emerg
或panic
LOG_EMERG
err
或error
LOG_ERR
info
LOG_INFO
notice
LOG_NOTICE
warn
或warning
LOG_WARNING
设施
名称 (字符串)
符号值
auth
LOG_AUTH
authpriv
LOG_AUTHPRIV
cron
LOG_CRON
daemon
LOG_DAEMON
ftp
LOG_FTP
kern
LOG_KERN
lpr
LOG_LPR
mail
LOG_MAIL
news
LOG_NEWS
syslog
LOG_SYSLOG
用户
LOG_USER
uucp
LOG_UUCP
local0
LOG_LOCAL0
local1
LOG_LOCAL1
local2
LOG_LOCAL2
local3
LOG_LOCAL3
local4
LOG_LOCAL4
local5
LOG_LOCAL5
local6
LOG_LOCAL6
local7
LOG_LOCAL7
- mapPriority(levelname)¶
将日志级别名称映射到 syslog 优先级名称。如果您正在使用自定义级别,或者默认算法不适合您的需求,您可能需要覆盖此方法。默认算法将
DEBUG
、INFO
、WARNING
、ERROR
和CRITICAL
映射到等效的 syslog 名称,并将所有其他级别名称映射到“warning”。
NTEventLogHandler¶
NTEventLogHandler
类位于 logging.handlers
模块中,支持将日志消息发送到本地 Windows NT、Windows 2000 或 Windows XP 事件日志。在使用它之前,您需要安装 Mark Hammond 的 Python Win32 扩展。
- class logging.handlers.NTEventLogHandler(appname, dllname=None, logtype='Application')¶
返回
NTEventLogHandler
类的新实例。appname 用于定义应用程序名称,因为它出现在事件日志中。使用此名称创建适当的注册表项。dllname 应提供包含消息定义的 .dll 或 .exe 的完全限定路径名,以保存在日志中(如果未指定,则使用'win32service.pyd'
- 这随 Win32 扩展安装,并包含一些基本的占位符消息定义。请注意,使用这些占位符将使您的事件日志变大,因为整个消息源都保存在日志中。如果您想要更精简的日志,则必须传入您自己的 .dll 或 .exe 的名称,其中包含您想要在事件日志中使用的消息定义)。logtype 是'Application'
、'System'
或'Security'
之一,默认为'Application'
。- close()¶
此时,您可以从注册表中删除应用程序名称作为事件日志条目的来源。但是,如果这样做,您将无法按预期在事件日志查看器中看到事件 - 它需要能够访问注册表才能获取 .dll 名称。当前版本不执行此操作。
- emit(record)¶
确定消息 ID、事件类别和事件类型,然后在 NT 事件日志中记录消息。
- getEventCategory(record)¶
返回记录的事件类别。如果您想指定自己的类别,请覆盖此项。此版本返回 0。
- getEventType(record)¶
返回记录的事件类型。如果您想指定自己的类型,请覆盖此项。此版本使用处理程序的 typemap 属性进行映射,该属性在
__init__()
中设置为一个字典,其中包含DEBUG
、INFO
、WARNING
、ERROR
和CRITICAL
的映射。如果您使用自己的级别,您需要覆盖此方法或在处理程序的 typemap 属性中放置一个合适的字典。
- getMessageID(record)¶
返回记录的消息 ID。如果您使用自己的消息,可以通过将传递给日志记录器的 msg 作为 ID 而不是格式字符串来完成此操作。然后,在这里,您可以使用字典查找来获取消息 ID。此版本返回 1,这是
win32service.pyd
中的基本消息 ID。
SMTPHandler¶
SMTPHandler
类位于 logging.handlers
模块中,支持通过 SMTP 将日志消息发送到电子邮件地址。
- class logging.handlers.SMTPHandler(mailhost, fromaddr, toaddrs, subject, credentials=None, secure=None, timeout=1.0)¶
返回
SMTPHandler
类的新实例。实例使用电子邮件的发件人地址、收件人地址和主题行进行初始化。toaddrs 应该是一个字符串列表。要指定非标准 SMTP 端口,请对 mailhost 参数使用 (主机, 端口) 元组格式。如果您使用字符串,则使用标准 SMTP 端口。如果您的 SMTP 服务器需要身份验证,您可以为 credentials 参数指定一个 (用户名, 密码) 元组。要指定使用安全协议 (TLS),请将一个元组传递给 secure 参数。这仅在提供身份验证凭据时使用。该元组应该是一个空元组,或一个包含密钥文件名称的单值元组,或一个包含密钥文件和证书文件名称的 2 值元组。(此元组将传递给
smtplib.SMTP.starttls()
方法。)可以使用 timeout 参数为与 SMTP 服务器的通信指定超时。
版本 3.3 中的更改: 添加了 timeout 参数。
- emit(record)¶
格式化记录并将其发送到指定的收件人。
- getSubject(record)¶
如果您想指定一个取决于记录的主题行,请覆盖此方法。
MemoryHandler¶
位于 logging.handlers
模块中的 MemoryHandler
类支持在内存中缓冲日志记录,并定期将它们刷新到目标处理程序。当缓冲区已满,或者当检测到某个严重级别或更高级别的事件时,就会发生刷新。
MemoryHandler
是更通用的 BufferingHandler
的子类,后者是一个抽象类。它在内存中缓冲日志记录。每当记录添加到缓冲区时,都会通过调用 shouldFlush()
进行检查,以查看是否应刷新缓冲区。如果应该刷新,则期望 flush()
执行刷新操作。
- class logging.handlers.BufferingHandler(capacity)¶
使用指定容量的缓冲区初始化处理程序。这里,capacity 表示缓冲的日志记录数量。
- emit(record)¶
将记录追加到缓冲区。如果
shouldFlush()
返回 true,则调用flush()
来处理缓冲区。
- flush()¶
对于
BufferingHandler
实例,刷新意味着将缓冲区设置为空列表。可以覆盖此方法以实现更有用的刷新行为。
- shouldFlush(record)¶
如果缓冲区达到容量,则返回
True
。可以覆盖此方法以实现自定义刷新策略。
- class logging.handlers.MemoryHandler(capacity, flushLevel=ERROR, target=None, flushOnClose=True)¶
返回
MemoryHandler
类的新实例。实例使用缓冲区大小 capacity(缓冲的记录数量)进行初始化。如果未指定 flushLevel,则使用ERROR
。如果未指定 target,则在此处理程序执行任何有用操作之前,需要使用setTarget()
设置目标。如果 flushOnClose 指定为False
,则在处理程序关闭时不刷新缓冲区。如果未指定或指定为True
,则在处理程序关闭时会发生刷新缓冲区的先前行为。3.6 版本变更: 添加了 flushOnClose 参数。
- flush()¶
对于
MemoryHandler
实例,刷新意味着只是将缓冲的记录发送到目标(如果存在)。当缓冲的记录发送到目标时,缓冲区也会被清除。如果需要不同的行为,请覆盖此方法。
- setTarget(target)¶
为此处理程序设置目标处理程序。
- shouldFlush(record)¶
检查缓冲区是否已满或记录级别是否达到 flushLevel 或更高。
HTTPHandler¶
位于 logging.handlers
模块中的 HTTPHandler
类支持使用 GET
或 POST
语义将日志消息发送到 Web 服务器。
- class logging.handlers.HTTPHandler(host, url, method='GET', secure=False, credentials=None, context=None)¶
返回
HTTPHandler
类的新实例。host 可以是host:port
形式,如果您需要使用特定端口号。如果未指定 method,则使用GET
。如果 secure 为 true,则将使用 HTTPS 连接。context 参数可以设置为ssl.SSLContext
实例,以配置用于 HTTPS 连接的 SSL 设置。如果指定了 credentials,它应该是一个包含用户 ID 和密码的 2 元组,将使用基本身份验证将其放入 HTTP“Authorization”标头中。如果指定凭据,您还应该指定 secure=True,以便您的用户 ID 和密码不会以明文形式在网络上传输。3.5 版本变更: 添加了 context 参数。
- mapLogRecord(record)¶
根据
record
提供一个字典,该字典将被 URL 编码并发送到 Web 服务器。默认实现只返回record.__dict__
。如果例如只将LogRecord
的子集发送到 Web 服务器,或者需要更具体的服务器发送内容自定义,则可以覆盖此方法。
- emit(record)¶
将记录作为 URL 编码字典发送到 Web 服务器。使用
mapLogRecord()
方法将记录转换为要发送的字典。
备注
由于准备记录以将其发送到 Web 服务器与通用格式化操作不同,因此使用
setFormatter()
为HTTPHandler
指定Formatter
无效。此处理程序不是调用format()
,而是调用mapLogRecord()
,然后调用urllib.parse.urlencode()
来编码字典,使其适合发送到 Web 服务器。
QueueHandler¶
在 3.2 版本加入。
位于 logging.handlers
模块中的 QueueHandler
类支持将日志消息发送到队列,例如在 queue
或 multiprocessing
模块中实现的队列。
与 QueueListener
类一起,QueueHandler
可用于让处理程序在其自己的线程中执行工作,而不是在执行日志记录的线程中。这在 Web 应用程序和其他服务应用程序中非常重要,在这些应用程序中,为客户端提供服务的线程需要尽快响应,而任何可能缓慢的操作(例如通过 SMTPHandler
发送电子邮件)都在单独的线程中完成。
- class logging.handlers.QueueHandler(queue)¶
返回
QueueHandler
类的新实例。实例使用要发送消息的队列进行初始化。queue 可以是任何类似队列的对象;它由enqueue()
方法按原样使用,该方法需要知道如何向其发送消息。队列不需要具有任务跟踪 API,这意味着您可以使用SimpleQueue
实例作为 queue。备注
如果您正在使用
multiprocessing
,您应该避免使用SimpleQueue
,而应使用multiprocessing.Queue
。警告
multiprocessing
模块使用通过get_logger()
创建和访问的内部记录器。multiprocessing.Queue
将在项目入队时记录DEBUG
级别消息。如果这些日志消息由使用相同multiprocessing.Queue
实例的QueueHandler
处理,将导致死锁或无限递归。- emit(record)¶
将准备 LogRecord 的结果入队。如果发生异常(例如,因为有界队列已满),则调用
handleError()
方法来处理错误。这可能导致记录被静默丢弃(如果logging.raiseExceptions
为False
)或在sys.stderr
上打印消息(如果logging.raiseExceptions
为True
)。
- prepare(record)¶
准备记录以进行排队。此方法返回的对象将入队。
基本实现格式化记录以合并消息、参数、异常和堆栈信息(如果存在)。它还在原地从记录中删除不可 pickle 的项。具体来说,它用合并后的消息(通过调用处理程序的
format()
方法获得)覆盖记录的msg
和message
属性,并将args
、exc_info
和exc_text
属性设置为None
。如果您想将记录转换为字典或 JSON 字符串,或者发送记录的修改副本同时保持原始记录不变,则可能需要覆盖此方法。
备注
基本实现使用参数格式化消息,将
message
和msg
属性设置为格式化后的消息,并将args
和exc_text
属性设置为None
,以允许 pickle 化并防止进一步的格式化尝试。这意味着QueueListener
端的处理程序将没有信息来执行自定义格式化,例如异常。您可能希望子类化QueueHandler
并覆盖此方法以例如避免将exc_text
设置为None
。请注意,message
/msg
/args
的更改与确保记录可 pickle 化有关,您可能能够或不能避免这样做,具体取决于您的args
是否可 pickle 化。(请注意,您可能不仅要考虑自己的代码,还要考虑您使用的任何库中的代码。)
- enqueue(record)¶
使用
put_nowait()
将记录入队;如果您想使用阻塞行为、超时或自定义队列实现,则可能需要覆盖此方法。
- listener¶
当通过使用
dictConfig()
配置创建时,此属性将包含一个QueueListener
实例,用于此处理程序。否则,它将为None
。3.12 新版功能.
QueueListener¶
在 3.2 版本加入。
位于 logging.handlers
模块中的 QueueListener
类支持从队列接收日志消息,例如在 queue
或 multiprocessing
模块中实现的队列。消息在内部线程中从队列接收,并在同一线程上传递给一个或多个处理程序进行处理。虽然 QueueListener
本身不是处理程序,但此处对其进行文档化,因为它与 QueueHandler
协同工作。
与 QueueHandler
类一起,QueueListener
可用于让处理程序在其自己的线程中执行工作,而不是在执行日志记录的线程中。这在 Web 应用程序和其他服务应用程序中非常重要,在这些应用程序中,为客户端提供服务的线程需要尽快响应,而任何可能缓慢的操作(例如通过 SMTPHandler
发送电子邮件)都在单独的线程中完成。
- class logging.handlers.QueueListener(queue, *handlers, respect_handler_level=False)¶
返回
QueueListener
类的新实例。实例使用要发送消息的队列和将处理队列上条目的处理程序列表进行初始化。队列可以是任何类似队列的对象;它按原样传递给dequeue()
方法,该方法需要知道如何从中获取消息。队列不需要具有任务跟踪 API(尽管如果可用则会使用),这意味着您可以使用SimpleQueue
实例作为 queue。备注
如果您正在使用
multiprocessing
,您应该避免使用SimpleQueue
,而应使用multiprocessing.Queue
。如果
respect_handler_level
为True
,则在决定是否将消息传递给处理程序时,会遵守处理程序的级别(与消息的级别进行比较);否则,行为与以前的 Python 版本中相同——始终将每条消息传递给每个处理程序。3.5 版本变更: 添加了
respect_handler_level
参数。3.14 版本变更:
QueueListener
现在可以通过with
用作上下文管理器。进入上下文时,监听器启动。退出上下文时,监听器停止。__enter__()
返回QueueListener
对象。- dequeue(block)¶
出队一条记录并返回它,可选地阻塞。
基本实现使用
get()
。如果您想使用超时或使用自定义队列实现,则可能需要覆盖此方法。
- prepare(record)¶
准备记录以进行处理。
此实现只返回传入的记录。如果您需要在将记录传递给处理程序之前对其进行任何自定义编组或操作,则可能需要覆盖此方法。
- start()¶
启动监听器。
这会启动一个后台线程来监视队列以处理 LogRecords。
3.14 版本变更: 如果调用时监听器已在运行,则会引发
RuntimeError
。
- stop()¶
停止监听器。
这会要求线程终止,然后等待它这样做。请注意,如果您在应用程序退出之前不调用此方法,队列上可能仍然会留下一些记录,这些记录将不会被处理。
- enqueue_sentinel()¶
向队列写入一个哨兵,以告知监听器退出。此实现使用
put_nowait()
。如果您想使用超时或使用自定义队列实现,则可能需要覆盖此方法。在 3.3 版本加入。
参见
- 模块
logging
logging 模块的 API 参考。
- 模块
logging.config
日志模块的配置 API。