logging.handlers
— 日志处理器¶
该软件包中提供了以下有用的处理器。请注意,其中三个处理器(StreamHandler
, FileHandler
和 NullHandler
)实际上是在 logging
模块本身中定义的,但已在此处与其他处理器一起记录。
StreamHandler¶
位于核心 logging
包中的 StreamHandler
类,将日志输出发送到诸如 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¶
位于核心 logging
包中的 FileHandler
类,将日志输出发送到磁盘文件。它从 StreamHandler
继承输出功能。
- class logging.FileHandler(filename, mode='a', encoding=None, delay=False, errors=None)¶
返回
FileHandler
类的新实例。 指定的文件将打开并用作日志记录的流。 如果未指定 mode,则使用'a'
。 如果 encoding 不是None
,则会使用该编码打开文件。 如果 delay 为 true,则文件打开将延迟到首次调用emit()
。 默认情况下,文件会无限增长。 如果指定了 errors,则它用于确定如何处理编码错误。在 3.6 版本中更改:除了字符串值之外,
Path
对象也被接受作为 filename 参数。在 3.9 版本中更改:添加了 errors 参数。
- close()¶
关闭文件。
NullHandler¶
3.1 版本加入。
位于核心 logging
包中的 NullHandler
类,不执行任何格式化或输出。 它本质上是库开发人员使用的“无操作”处理程序。
- 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 版本中更改:除了字符串值之外,
Path
对象也被接受作为 filename 参数。在 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
的实例。如果 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 版本中更改:除了字符串值之外,
Path
对象也被接受作为 filename 参数。在 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 版本中更改:除了字符串值之外,
Path
对象也被接受作为 filename 参数。在 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)¶
将记录的属性字典以二进制格式序列化,并带有长度前缀,然后返回准备好通过套接字传输的数据。此操作的详细信息等效于
data = pickle.dumps(record_attr_dict, 1) datalen = struct.pack('>L', len(data)) return datalen + data
请注意,pickle 并非完全安全。如果您担心安全性,则可能需要覆盖此方法以实现更安全的机制。例如,您可以使用 HMAC 对 pickle 进行签名,然后在接收端验证它们,或者您可以在接收端禁用全局对象的反序列化。
- send(packet)¶
将序列化的字节字符串 packet 发送到套接字。发送的字节字符串的格式如
makePickle()
的文档中所述。此函数允许部分发送,这可能在网络繁忙时发生。
- createSocket()¶
尝试创建套接字;如果失败,则使用指数退避算法。在初始失败时,处理程序将丢弃它试图发送的消息。当同一个实例处理后续消息时,它将不会尝试连接,直到经过一段时间。默认参数是初始延迟为 1 秒,如果在此延迟之后仍无法建立连接,则处理程序每次都会将延迟加倍,直到最大延迟为 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 系统日志。
- class logging.handlers.SysLogHandler(address=('localhost', SYSLOG_UDP_PORT), facility=LOG_USER, socktype=socket.SOCK_DGRAM)¶
返回一个
SysLogHandler
类的新实例,该实例旨在与远程 Unix 机器通信,其地址由 address 指定,形式为(主机, 端口)
元组。如果未指定 address,则使用('localhost', 514)
。该地址用于打开套接字。除了提供(主机, 端口)
元组外,还可以提供字符串形式的地址,例如 ‘/dev/log’。在这种情况下,将使用 Unix 域套接字将消息发送到 syslog。如果未指定 facility,则使用LOG_USER
。打开的套接字类型取决于 socktype 参数,该参数默认为socket.SOCK_DGRAM
,因此会打开一个 UDP 套接字。要打开 TCP 套接字(用于较新的 syslog 守护程序,如 rsyslog),请指定socket.SOCK_STREAM
的值。请注意,如果您的服务器没有监听 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。
- close()¶
关闭到远程主机的套接字。
- createSocket()¶
尝试创建一个套接字,如果它不是数据报套接字,则将其连接到另一端。此方法在处理程序初始化期间调用,但如果另一端此时没有监听,则不认为是错误 - 如果此时没有套接字,则在发出事件时将再次调用该方法。
在 3.11 版本中添加。
- emit(record)¶
格式化记录,然后将其发送到 syslog 服务器。如果存在异常信息,则不会将其发送到服务器。
在 3.2.1 版本中更改: (请参阅:bpo-12168。) 在早期版本中,发送到 syslog 守护程序的消息始终以 NUL 字节结尾,因为这些守护程序的早期版本需要以 NUL 结尾的消息 - 即使它不在相关规范中 (RFC 5424)。这些守护程序的更新版本不需要 NUL 字节,但如果存在则会将其剥离,而更新的版本(更严格地遵守 RFC 5424)会将 NUL 字节作为消息的一部分传递。
为了更轻松地处理所有这些不同的守护程序行为中的 syslog 消息,通过使用类级属性
append_nul
,可以配置是否附加 NUL 字节。此属性默认为True
(保留现有行为),但可以在SysLogHandler
实例上将其设置为False
,以使该实例不附加 NUL 终止符。在 3.3 版本中更改: (请参阅:bpo-12419。) 在早期版本中,没有用于标识消息来源的“ident”或“tag”前缀的机制。现在可以使用类级属性指定此项,默认值为
""
以保留现有行为,但可以在SysLogHandler
实例上覆盖此项,以便该实例将 ident 前缀添加到每个处理的消息。请注意,提供的 ident 必须是文本,而不是字节,并且会按原样添加到消息前面。
- encodePriority(facility, priority)¶
将 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)¶
将日志级别名称映射到 syslog 优先级名称。如果使用自定义级别,或者默认算法不适合您的需求,您可能需要重写此方法。默认算法将
DEBUG
、INFO
、WARNING
、ERROR
和CRITICAL
映射到等效的 syslog 名称,并将所有其他级别名称映射到 “warning”。
NTEventLogHandler¶
位于 logging.handlers
模块中的 NTEventLogHandler
类支持将日志消息发送到本地 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¶
位于 logging.handlers
模块中的 SMTPHandler
类,支持通过 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,它应该是一个包含 userid 和 password 的 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()
方法按原样使用它,该方法需要知道如何向其发送消息。queue 不需要具有任务跟踪 API,这意味着您可以为 queue 使用SimpleQueue
实例。注解
如果您正在使用
multiprocessing
,则应避免使用SimpleQueue
,而应使用multiprocessing.Queue
。- emit(record)¶
将准备好的 LogRecord 的结果加入队列。如果发生异常(例如,因为有界队列已满),则会调用
handleError()
方法来处理该错误。这可能会导致记录被静默丢弃(如果logging.raiseExceptions
为False
)或者将消息打印到sys.stderr
(如果logging.raiseExceptions
为True
)。
- prepare(record)¶
准备记录以加入队列。此方法返回的对象将加入队列。
基本实现格式化记录以合并消息、参数、异常和堆栈信息(如果存在)。它还会就地删除记录中不可腌制的项。具体来说,它使用合并的消息覆盖记录的
msg
和message
属性(通过调用处理程序的format()
方法获得),并将args
、exc_info
和exc_text
属性设置为None
。如果您想将记录转换为字典或 JSON 字符串,或者在保留原始记录完整性的同时发送记录的修改副本,您可能需要覆盖此方法。
注解
基本实现使用参数格式化消息,将
message
和msg
属性设置为格式化后的消息,并将args
和exc_text
属性设置为None
,以允许腌制并防止进一步尝试格式化。这意味着QueueListener
端的处理程序将没有信息来执行自定义格式化,例如异常。您可能希望子类化QueueHandler
并覆盖此方法,例如避免将exc_text
设置为None
。请注意,message
/msg
/args
的更改与确保记录可腌制有关,并且您是否能够避免这样做可能取决于您的args
是否可腌制。(请注意,您可能不仅需要考虑您自己的代码,还需要考虑您使用的任何库中的代码。)
- 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
日志模块的 API 参考。
- 模块
logging.config
日志模块的配置 API。