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* 为 true,则文件打开将延迟到第一次调用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 为 true,则文件打开将延迟到第一次调用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()
的参数。注意
在滚动期间,namer 函数会被调用多次,因此它应该尽可能简单快速。它还应该在每次调用时为给定的输入返回相同的输出,否则滚动行为可能无法按预期工作。
同样值得注意的是,在使用 namer 时应注意保留文件名中用于轮换的某些属性。例如,
RotatingFileHandler
期望有一组日志文件,其名称包含连续的整数,以便轮换按预期工作,而TimedRotatingFileHandler
通过确定要删除的最旧文件来删除旧日志文件(基于传递给处理程序初始化器的backupCount
参数)。为此,文件名应该可以使用文件名的日期/时间部分进行排序,并且 namer 需要遵守这一点。(如果需要一个不遵守此方案的 namer,则需要在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
的实例使用相同的可调用对象。如果 namer 或 rotator 可调用对象引发异常,则将以与 emit()
调用期间的任何其他异常相同的方式处理,即通过处理程序的 handleError()
方法处理。
如果需要对轮换处理进行更重大的更改,则可以覆盖这些方法。
有关示例,请参阅 使用 rotator 和 namer 自定义日志轮换处理。
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 为 true,则文件打开会推迟到第一次调用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)¶
将记录输出到文件,并根据前面描述的方式处理翻转。
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* 参数为 true,则将使用 UTC 时间;否则将使用本地时间。
如果 *backupCount* 不为零,则最多将保留 *backupCount* 个文件,如果在翻转时创建的文件数量超过此数量,则将删除最旧的文件。删除逻辑使用间隔来确定要删除的文件,因此更改间隔可能会导致旧文件保留下来。
如果 *delay* 为 true,则文件打开将延迟到第一次调用
emit()
。如果 *atTime* 不为
None
,则它必须是一个datetime.time
实例,用于指定发生翻转的当天时间,适用于设置为“午夜”或“特定工作日”翻转的情况。请注意,在这些情况下,*atTime* 值实际上用于计算*初始*翻转,而后续翻转将通过正常的间隔计算来计算。如果指定了 *errors*,则使用它来确定如何处理编码错误。
注意
初始翻转时间的计算是在处理程序初始化时完成的。后续翻转时间的计算仅在发生翻转时进行,而翻转仅在发出输出时发生。如果这一点没有牢记,可能会导致一些混淆。例如,如果设置了“每分钟”的间隔,这并不意味着您总是会看到文件名中时间间隔为一分钟的日志文件;如果在应用程序执行期间,日志输出的生成频率高于每分钟一次,*那么*您可以预期看到时间间隔为一分钟的日志文件。另一方面,如果日志消息仅每五分钟输出一次(例如),则文件时间中将存在与没有输出(因此没有翻转)的分钟相对应的间隔。
在 3.4 版更改: 添加了 *atTime* 参数。
在 3.6 版更改: 除了字符串值之外,*filename* 参数现在也接受
Path
对象。在 3.9 版更改: 添加了 *errors* 参数。
- doRollover()¶
如上所述,执行翻转操作。
- emit(record)¶
将记录输出到文件,并根据上述描述处理翻转。
- getFilesToDelete()¶
返回应作为翻转的一部分删除的文件名列表。这些是由处理程序写入的最旧备份日志文件的绝对路径。
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)¶
以二进制格式对记录的属性字典进行 Pickle 操作,并添加长度前缀,使其准备好通过套接字传输。此操作的详细信息等效于
data = pickle.dumps(record_attr_dict, 1) datalen = struct.pack('>L', len(data)) return datalen + data
请注意,Pickle 并不完全安全。如果您担心安全性,您可能需要重写此方法以实现更安全的机制。例如,您可以使用 HMAC 对 Pickle 进行签名,然后在接收端对其进行验证,或者您可以在接收端禁用全局对象的 unpickle 操作。
- send(packet)¶
将 Pickle 处理后的字节字符串 *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()¶
对记录的属性字典进行 Pickle 操作,并将其以二进制格式写入套接字。如果套接字出现错误,则静默丢弃数据包。要在接收端将记录 unpickle 为
LogRecord
,请使用makeLogRecord()
函数。
- makeSocket()¶
SocketHandler
的工厂方法在此处被重写以创建 UDP 套接字(socket.SOCK_DGRAM
)。
- send(s)¶
将 Pickle 处理后的字节字符串发送到套接字。发送的字节字符串的格式如
SocketHandler.makePickle()
的文档中所述。
SysLogHandler¶
SysLogHandler
类位于 logging.handlers
模块中,支持将日志消息发送到远程或本地 Unix 系统日志。
- class logging.handlers.SysLogHandler(address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER, socktype=socket.SOCK_DGRAM)¶
返回
SysLogHandler
类的新实例,该实例旨在与地址由 *address* 以(host, port)
元组形式给出的远程 Unix 机器进行通信。如果未指定 *address*,则使用('localhost', 514)
。该地址用于打开套接字。提供(host, port)
元组的替代方法是提供一个字符串形式的地址,例如“/dev/log”。在这种情况下,将使用 Unix 域套接字将消息发送到系统日志。如果未指定 *facility*,则使用LOG_USER
。打开的套接字类型取决于 *socktype* 参数,该参数默认为socket.SOCK_DGRAM
,因此会打开 UDP 套接字。要打开 TCP 套接字(用于较新的系统日志守护程序,例如 rsyslog),请指定socket.SOCK_STREAM
值。请注意,如果您的服务器未侦听 UDP 端口 514,则
SysLogHandler
可能看起来不起作用。在这种情况下,请检查您应该为域套接字使用什么地址 - 这取决于系统。例如,在 Linux 上,它通常是“/dev/log”,但在 OS/X 上,它是“/var/run/syslog”。您需要检查您的平台并使用适当的地址(如果您的应用程序需要在多个平台上运行,则可能需要在运行时执行此检查)。在 Windows 上,您几乎必须使用 UDP 选项。注意
在 macOS 12.x(Monterey)上,Apple 更改了其系统日志守护程序的行为 - 它不再侦听域套接字。因此,您不能期望
SysLogHandler
在此系统上工作。有关更多信息,请参阅 gh-91070。
3.2 版更改: 添加了 socktype。
- close()¶
关闭到远程主机的套接字。
- createSocket()¶
尝试创建一个套接字,如果它不是数据报套接字,则将其连接到另一端。此方法在处理程序初始化期间调用,但如果另一端此时未监听,则不被视为错误 - 如果此时没有套接字,则在发出事件时将再次调用该方法。
3.11 版新增。
- emit(record)¶
记录被格式化,然后发送到系统日志服务器。如果存在异常信息,则不会将其发送到服务器。
3.2.1 版更改: (参见:bpo-12168。)在早期版本中,发送到系统日志守护程序的消息始终以 NUL 字节终止,因为这些守护程序的早期版本需要以 NUL 终止的消息 - 即使它不在相关规范中(RFC 5424)。这些守护程序的更新版本不需要 NUL 字节,但如果存在则将其剥离,而更新的守护程序(更严格地遵循 RFC 5424)则将 NUL 字节作为消息的一部分传递。
为了在面对所有这些不同的守护程序行为时更容易处理系统日志消息,附加 NUL 字节已可通过使用类级别属性
append_nul
进行配置。这默认为True
(保留现有行为),但可以在SysLogHandler
实例上设置为False
,以便该实例不附加 NUL 终止符。3.3 版更改: (参见:bpo-12419。)在早期版本中,没有用于标识消息来源的“标识符”或“标签”前缀的工具。现在可以使用类级别属性指定它,默认为
""
以保留现有行为,但可以在SysLogHandler
实例上覆盖它,以便该实例将标识符添加到每个处理的消息之前。请注意,提供的标识符必须是文本,而不是字节,并且按原样添加到消息之前。
- 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
user
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)¶
将日志记录级别名称映射到系统日志优先级名称。如果您使用的是自定义级别,或者默认算法不适合您的需求,则可能需要覆盖此方法。默认算法将
DEBUG
、INFO
、WARNING
、ERROR
和CRITICAL
映射到等效的系统日志名称,并将所有其他级别名称映射到“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* 参数使用 (host, port) 元组格式。如果使用字符串,则使用标准 SMTP 端口。如果您的 SMTP 服务器需要身份验证,则可以为 *credentials* 参数指定一个 (username, password) 元组。要指定使用安全协议 (TLS),请将一个元组传递给 *secure* 参数。这仅在提供身份验证凭据时使用。该元组应该是空元组,或者是一个包含密钥文件名值的单值元组,或者是一个包含密钥文件名和证书文件名的双值元组。(此元组将传递给
smtplib.SMTP.starttls()
方法。)可以使用 *timeout* 参数为与 SMTP 服务器的通信指定超时时间。
在 3.3 版更改: 添加了 *timeout* 参数。
- emit(record)¶
格式化记录并将其发送到指定的收件人。
- getSubject(record)¶
如果要指定依赖于记录的主题行,请重写此方法。
MemoryHandler¶
MemoryHandler
类位于 logging.handlers
模块中,支持在内存中缓冲日志记录,并定期将其刷新到 *目标* 处理程序。每当缓冲区已满,或者看到某个严重程度或更高级别的事件时,就会发生刷新。
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¶
HTTPHandler
类位于 logging.handlers
模块中,支持使用 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 版新增。
QueueHandler
类位于 logging.handlers
模块中,支持将日志消息发送到队列,例如在 queue
或 multiprocessing
模块中实现的队列。
QueueHandler
类与 QueueListener
类一起使用,可以让处理程序在与执行日志记录的线程不同的线程上执行其工作。这在 Web 应用程序和其他服务应用程序中非常重要,在这些应用程序中,为客户端提供服务的线程需要尽快响应,而任何潜在的慢速操作(例如通过 SMTPHandler
发送电子邮件)都在单独的线程上完成。
- class logging.handlers.QueueHandler(queue)¶
返回
QueueHandler
类的新实例。该实例使用要向其发送消息的队列进行初始化。*queue* 可以是任何类似队列的对象;它由enqueue()
方法按原样使用,该方法需要知道如何向其发送消息。队列并 *不需要* 具有任务跟踪 API,这意味着您可以将SimpleQueue
实例用于 *queue*。注意
如果您正在使用
multiprocessing
,则应避免使用SimpleQueue
,而应使用multiprocessing.Queue
。- 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 版新增。
QueueListener
类位于 logging.handlers
模块中,支持从队列接收日志消息,例如在 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
参数。- dequeue(block)¶
将记录出列并返回,可以选择阻塞。
基本实现使用
get()
。如果要使用超时或使用自定义队列实现,则可能需要重写此方法。
- prepare(record)¶
准备要处理的记录。
此实现只返回传入的记录。如果需要在将记录传递给处理程序之前对其进行任何自定义编组或操作,则可能需要重写此方法。
- start()¶
启动监听器。
这将启动一个后台线程来监视队列中要处理的 LogRecords。
- stop()¶
停止监听器。
这将要求线程终止,然后等待它这样做。请注意,如果在应用程序退出之前没有调用此方法,则队列中可能还会有一些记录,这些记录将不会被处理。
- enqueue_sentinel()¶
向队列写入一个标记,以告诉监听器退出。此实现使用
put_nowait()
。如果要使用超时或使用自定义队列实现,则可能需要重写此方法。3.3 版新增。
另请参阅
- 模块
logging
logging 模块的 API 参考。
- 模块
logging.config
logging 模块的配置 API。