logging.handlers — 日志处理程序

源代码: Lib/logging/handlers.py


该软件包中提供了以下有用的处理程序。请注意,其中三个处理程序(StreamHandlerFileHandlerNullHandler)实际上是在 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() 对其进行格式化并附加到流中。

flush()

通过调用其 flush() 方法刷新流。请注意,close() 方法是从 Handler 继承的,因此不执行任何输出,因此有时可能需要显式调用 flush()

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()

关闭文件。

emit(record)

将记录输出到文件。

请注意,如果文件是在退出时由于日志记录关闭而关闭的,并且文件模式为“w”,则不会发出记录(参见 bpo-42378)。

NullHandler

3.1 版新增。

NullHandler 类位于核心 logging 包中,不执行任何格式化或输出。它本质上是一个“无操作”处理程序,供库开发者使用。

class logging.NullHandler

返回 NullHandler 类的新实例。

emit(record)

此方法不执行任何操作。

handle(record)

此方法不执行任何操作。

createLock()

此方法返回 None 作为锁,因为没有需要序列化访问的底层 I/O。

有关如何使用 NullHandler 的更多信息,请参阅 为库配置日志记录

WatchedFileHandler

WatchedFileHandler 类位于 logging.handlers 模块中,是一个 FileHandler,它会监视其正在记录到的文件。如果文件发生更改,它将关闭并使用文件名重新打开。

文件更改可能是由于使用了诸如 newsysloglogrotate 之类的程序而发生的,这些程序执行日志文件轮换。此处理程序旨在在 Unix/Linux 下使用,它会监视文件以查看自上次发出以来是否已更改。(如果文件的设备或 inode 已更改,则认为该文件已更改。)如果文件已更改,则关闭旧文件流,并打开该文件以获取新流。

此处理程序不适用于 Windows,因为在 Windows 下,打开的日志文件无法移动或重命名 - 日志记录使用独占锁打开文件 - 因此不需要此类处理程序。此外,Windows 不支持 ST_INOstat() 始终为此值返回零。

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 模块中,是轮换文件处理程序 RotatingFileHandlerTimedRotatingFileHandler 的基类。您应该不需要实例化此类,但它具有您可能需要覆盖的属性和方法。

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 版新增。

rotator

如果此属性设置为可调用对象,则 rotate() 方法会委托给此可调用对象。传递给可调用对象的参数与传递给 rotate() 的参数相同。

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 版新增。

这些属性存在的原因是为了避免您必须创建子类 - 您可以对 RotatingFileHandlerTimedRotatingFileHandler 的实例使用相同的可调用对象。如果 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,则它确定如何处理编码错误。

您可以使用 maxBytesbackupCount 值来允许文件在预定大小 滚动。当即将超过大小时,文件将关闭,并静默打开一个新文件以供输出。只要当前日志文件的长度接近 maxBytes,就会发生滚动;但如果 maxBytesbackupCount 中的任何一个为零,则永远不会发生滚动,因此您通常希望将 backupCount 设置为至少 1,并且 maxBytes 为非零值。当 backupCount 不为零时,系统将通过在文件名后面附加扩展名“.1”、“.2”等来保存旧日志文件。例如,如果 backupCount 为 5 且基本文件名是 app.log,则您将获得 app.logapp.log.1app.log.2,直到 app.log.5。正在写入的文件始终是 app.log。当此文件填满时,它将关闭并重命名为 app.log.1,如果文件 app.log.1app.log.2 等存在,则它们将分别重命名为 app.log.2app.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() 函数。

handleError()

处理在 emit() 期间发生的错误。最可能的原因是连接断开。关闭套接字,以便我们可以在下一个事件上重试。

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

critcritical

LOG_CRIT

debug

LOG_DEBUG

emergpanic

LOG_EMERG

errerror

LOG_ERR

info

LOG_INFO

notice

LOG_NOTICE

warnwarning

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)

将日志记录级别名称映射到系统日志优先级名称。如果您使用的是自定义级别,或者默认算法不适合您的需求,则可能需要覆盖此方法。默认算法将 DEBUGINFOWARNINGERRORCRITICAL 映射到等效的系统日志名称,并将所有其他级别名称映射到“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__() 中设置为一个字典,其中包含 DEBUGINFOWARNINGERRORCRITICAL 的映射。如果您使用自己的级别,则需要重写此方法或在处理程序的 *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* 参数。

close()

调用 flush(),将目标设置为 None 并清空缓冲区。

flush()

对于 MemoryHandler 实例,刷新意味着仅将缓冲的记录发送到目标(如果有)。当缓冲的记录发送到目标时,缓冲区也会被清除。如果需要不同的行为,请重写此方法。

setTarget(target)

设置此处理程序的目标处理程序。

shouldFlush(record)

检查缓冲区是否已满或记录是否在 *flushLevel* 或更高等级。

HTTPHandler

HTTPHandler 类位于 logging.handlers 模块中,支持使用 GETPOST 语义将日志消息发送到 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 模块中,支持将日志消息发送到队列,例如在 queuemultiprocessing 模块中实现的队列。

QueueHandler 类与 QueueListener 类一起使用,可以让处理程序在与执行日志记录的线程不同的线程上执行其工作。这在 Web 应用程序和其他服务应用程序中非常重要,在这些应用程序中,为客户端提供服务的线程需要尽快响应,而任何潜在的慢速操作(例如通过 SMTPHandler 发送电子邮件)都在单独的线程上完成。

class logging.handlers.QueueHandler(queue)

返回 QueueHandler 类的新实例。该实例使用要向其发送消息的队列进行初始化。*queue* 可以是任何类似队列的对象;它由 enqueue() 方法按原样使用,该方法需要知道如何向其发送消息。队列并 *不需要* 具有任务跟踪 API,这意味着您可以将 SimpleQueue 实例用于 *queue*。

注意

如果您正在使用 multiprocessing,则应避免使用 SimpleQueue,而应使用 multiprocessing.Queue

emit(record)

将准备 LogRecord 的结果放入队列。如果发生异常(例如,因为有界队列已满),则调用 handleError() 方法来处理错误。这可能会导致记录被静默丢弃(如果 logging.raiseExceptionsFalse)或将消息打印到 sys.stderr(如果 logging.raiseExceptionsTrue)。

prepare(record)

准备要排队的记录。此方法返回的对象已入队。

基本实现格式化记录以合并消息、参数、异常和堆栈信息(如果存在)。它还从记录中就地删除不可pickle的项目。具体来说,它使用合并的消息(通过调用处理程序的 format() 方法获得)覆盖记录的 msgmessage 属性,并将 argsexc_infoexc_text 属性设置为 None

如果要将记录转换为字典或 JSON 字符串,或者在保留原始记录的同时发送修改后的记录副本,则可能需要覆盖此方法。

注意

基本实现使用参数格式化消息,将 messagemsg 属性设置为格式化的消息,并将 argsexc_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 模块中,支持从队列接收日志消息,例如在 queuemultiprocessing 模块中实现的那些消息。消息从内部线程中的队列接收,并在同一线程上传递给一个或多个处理程序进行处理。虽然 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_levelTrue,则在决定是否将消息传递给处理程序时,将考虑处理程序的级别(与消息的级别相比);否则,行为与以前的 Python 版本一样 - 始终将每条消息传递给每个处理程序。

版本 3.5 中的变化: 添加了 respect_handler_level 参数。

dequeue(block)

将记录出列并返回,可以选择阻塞。

基本实现使用 get()。如果要使用超时或使用自定义队列实现,则可能需要重写此方法。

prepare(record)

准备要处理的记录。

此实现只返回传入的记录。如果需要在将记录传递给处理程序之前对其进行任何自定义编组或操作,则可能需要重写此方法。

handle(record)

处理记录。

这只是循环遍历处理程序,为它们提供要处理的记录。实际传递给处理程序的对象是从 prepare() 返回的对象。

start()

启动监听器。

这将启动一个后台线程来监视队列中要处理的 LogRecords。

stop()

停止监听器。

这将要求线程终止,然后等待它这样做。请注意,如果在应用程序退出之前没有调用此方法,则队列中可能还会有一些记录,这些记录将不会被处理。

enqueue_sentinel()

向队列写入一个标记,以告诉监听器退出。此实现使用 put_nowait()。如果要使用超时或使用自定义队列实现,则可能需要重写此方法。

3.3 版新增。

另请参阅

模块 logging

logging 模块的 API 参考。

模块 logging.config

logging 模块的配置 API。