下面这些有用的处理程序在logging包中提供。注意,StreamHandler
、FileHandler
和 NullHandler
这三个处理程序实际上是在logging模块中定义的,但是已经和其他处理程序一起被记录在这里。
StreamHandler
类,位于核心的 logging
包中,发送日志记录到流,比如 sys.stdout
,sys.stderr
或任意类文件对象(或者,更准确地说,任何支持 write()
和 flush()
方法的对象)。
class logging.StreamHandler(stream=None)
返回一个新的 StreamHandler
类的实例。如果指定 stream 参数,实例会使用它作为日志记录的输出,否则,将使用 sys.stderr
。
emit(record)
如果指定了格式化器,将会被用来格式化记录。然后使用终止符将记录写入流。如果存在异常信息,则使用 traceback.print_exception()
对其进行格式化,并将其附加到流中。
flush()
通过调用其 flush()
方法刷新流。注意 close()
方法是从 Handler
继承而来的,因此没有输出,所以有时可能需要显式的 flush()
调用。
setStream(stream)
如果实例的流与 stream 的值不同,就将其设置为 stream 指定的值。原来的流将会在新的流被设置前刷新。
如果流没有更改,则返回 None;如果流已经更改,则返回原来的流。
FileHandler
类,位于核心的 logging
包中,发送日志记录到一个磁盘上的文件。它从 StreamHandler
继承输出功能。
class logging.FileHandler(filename, mode=‘a’, encoding=None, delay=False)
返回一个新的 FileHandler
类的实例。指定的文件会被打开并用作日志记录的流。如果 mode 参数未指定,则使用 'a’
。如果 encoding 不是 None,会使用其指定的编码打开文件。如果 delay 的值是 True,然后将文件打开延迟到对 emit()
的第一次调用。默认情况下,文件无限增长。
close()
关闭文件。
emit()
输出记录到文件。
NullHandler
类,位于核心的 logging
包中,不会做任何的格式化或者输出。它本质上是一个供库开发人员使用的 no-op 处理程序。
class logging.NullHandler
返回一个新的 NullHandler
类的实例。
emit(record)
该方法不做任何事情。
handler(record)
NullHandler
类
createLock()
这个方法为这个锁返回 None,因为没有需要序列化访问的底层 I/O。
请查看 配置库的日志记录 如何使用 NullHandler
。
WatchedFileHandler
类,位于核心的 logging.handlers
模块,是一个 FileHander
,用于监视它要记录到的文件。如果文件发生更改,则使用文件名关闭并重新打开。
由于使用 newsyslog
和 logrotate
等执行日志文件旋转的程序,可能会发生文件更改。这个处理程序将在Unix/Linux下使用,它将监视文件,看看自上次发出以来是否发生了更改。(如果文件的设备或inode发生了更改,则该文件将被视为已经更改。)如果文件已更改,则关闭旧的文件流,并打开文件以获取新流。
这个处理程序不适合在Windows下使用,因为在Windows下打开的日志文件不能移动或重命名——日志使用独占锁打开文件——因此不需要这样的处理程序。此外,在Windows下不支持 ST_INO
;stat()
总是为这个值返回零。
class logging.handlers.WatchedFileHandler(filename, mode=‘a’, encoding=None, delay=False)
返回一个新的 WatchedFileHandler
类的实例。指定的文件会被打开并用作日志记录的流。如果 mode 参数未指定,则使用 'a’
。如果 encoding 不是 None,会使用其指定的编码打开文件。如果 delay 的值是 True,然后将文件打开延迟到对 emit()
的第一次调用。默认情况下,文件无限增长。
reopenIfNeeded()
检查文件是否已经更改。如果已经更改,会刷新已存在的流并关闭它,然后重新打开文件。通常作为将记录输出到文件的前导。
emit(record)
将记录输出到文件,但是如果文件已更改,则会先调用 reopenIfNeeded()
方法将其重新打开。
BaseRotatingHandler
类,位于核心的 logging.handlers
模块,是旋转文件处理程序 RotatingFileHandler
和 TimeRotatingFileHander
类的基类。你应该不需要实例化这个类,但你应该需要重写他的属性和方法。
class logging.handlers.BaseRotatingHandler(filename, mode, encoding=None, delay=False)
参数与 FileHandler
相同。属性是:
name
如果将此属性设置为可调用的,则 rotation_filename()
方法将委托给该可调用对象。传递给可调用方的参数是传递给 rotation_filename()
的参数。
注意:
在翻转过程中,namer 函数被调用了好几次,所以它应该尽可能地简单和快速。它还应该每次为给定的输入返回相同的输出,否则滚动行为可能不会像预期的那样工作。
rotator
如果将此属性设置为可调用对象,那么 rotate()
方法将委托给该可调用的对象。传递给可调用方的参数是传递给 rotate()
的参数。
rotation_filename(default_name)
在旋转时修改日志文件的文件名。
这样就可以提供自定义文件名。
默认实现调用处理程序的 namer 属性(如果它是可调用的),并将默认名称传递给它。如果属性不可调用(默认为 None),则返回的名称将保持不变。
default_name 参数用于指定日志文件的默认名称。
rotate(source, dest)
当旋转时,选择当前日志。
默认实现调用处理器的 rotator 属性(当其为可调用时),并传递 source 和 dest 参数。如果属性不可调用(默认值为 None),source 将被简单冲命名为 dest 参数的值。
属性存在的原因是为了避免子类化——您可以对 RotatingFileHandler
和TimedRotatingFileHandler
的实例使用相同的可调用项。如果 namer 或 rotator 指定的可调用对象引发异常,则在 emit()
调用期间将以与任何其他异常相同的方式处理该异常,例如,通过处理程序的 handleError()
方法。
如果需要对旋转处理进行更重要的更改,可以覆盖这些方法。
例如,请参见 Using a rotator and namer to customize log rotation processing 。
RotatingFileHandler
类,位于 logging.handlers
模块,支持磁盘日记文件的旋转。
class logging.handlers.RotatingFileHander(filename, mode=‘a’, maxBytes=0, backupCount=0, encoding=None, delay=False)
返回 RotatingFileHandler
类的一个新实例。打开指定的文件并将其用作日志记录的流。如果没有指定模式,则使用 a
。如果编码不是 None
,则使用该编码打开文件。如果 delay 为 None,则将文件打开延迟到对 emit()
的第一个调用。默认情况下,文件无限增长。
您可以使用 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
等。
doRollover()
进行翻滚,就如上面描述的一样。
emit(record)
将记录输出到文件,以满足前面描述的滚动。
TimedRotatingFileHandler
类,位于 logging.handlers
模块,支持按一定的时间间隔旋转磁盘日志文件。
class logging.handlers.TimedRotatingFileHandler(filename, when=‘h’, interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None)
返回 TimedRotatingFileHandler
类的一个新实例。打开指定的文件并将其用作日志记录的流。旋转时,它还设置文件名后缀。旋转是由时间和间隔的乘积决定的。
可以使用 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 个文件,如果在滚动发生时创建了更多的 backupCount 文件,则删除最老的文件。删除逻辑使用间隔来确定要删除哪些文件,因此更改间隔可能会留下旧文件。
如果延迟为真,则将文件打开延迟到对emit()的第一个调用。
如果 atTime 不是 None,那么它一定是一个指定一天中发生翻转的时间的 datetime.time 实例,用于将翻转设置为 午夜 或 某个工作日。注意,在这些情况下,atTime 值被有效地用于计算初始翻转,随后的翻转将通过正常的区间计算来计算。
注意:
初始滚动时间的计算是在初始化处理程序时完成的。只有在发生翻转时才计算随后的翻转时间,只有在发出输出时才计算翻转时间。如果不记住这一点,可能会导致一些混乱。例如,如果将间隔设置为每一分钟,这并不意味着总是会看到日志文件(在文件名中)的时间间隔为一分钟;如果在应用程序执行期间,日志输出的生成频率超过每分钟一次,那么您可能会看到日志文件的时间间隔为一分钟。另一方面,如果日志消息每五分钟才输出一次(比方说),那么文件中就会有与没有输出(因此也没有滚动)的分钟对应的时间间隔。
doRollover()
执行翻滚,如上面描述的那样。
emit(record)
将记录输出到 文件,以满足前面描述的滚动。
SMTPHandler
类,位于 logging.handlers
模块,支持通过SMTP协议发送日志记录消息到电子邮件地址。
class logging.handlers.SMTPHandler(mailhost, fromaddr, toaddrs, subject, credentials=None, secure=None, timeout=1.0)
返回一个 SMTPHandler
类的新实例。这个实例使用 fromaddr、toaddrs 和 subject 进行初始化。toaddrs 应该是一个字符串列表。要指定非标准的SMTP端口,请使用 (host, port)
元组格式做为 mailhost 参数的值。如果想要使用一个字符串,则会使用标准的SMTP端口。如果你的SMTP服务器需要验证,可以指定一个 (username, password)
元组做为 credentials 参数的值。
要指定使用安全的协议(TSL),请给 secure 参数传递一个元组。只有在提供身份验证凭据时才会使用。元组应该是一个空元组、一个只包含密钥文件名称的单值元组,或者一个包含密钥文件名称和证书文件名称的二元组。(这个元组将被传递给smtplib.SMTP.starttls()
方法。)
可以使用 timeout 参数指定超时时间,以便与SMTP服务器通信。
emit(record)
格式化记录并将其发送到指定的地址。
getSubject(record)
如果希望指定与记录相关的主题行,请覆盖此方法。
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
实例来配置SSL设置以供HTTPS连接使用。如果指定了 credentials 参数,它应该是一个由用户名和密码组成的2元组,这个二元组会放在 HTTP 的 Authorization
Header 中用于基本认证。如果指定了 credentials 参数,那么应该将 secure 参数的值设置为 True,以便用户名和密码不会以明文在网络中传输。
mapLogRecord(record)
提供一个基于 record 的字典,它将被进行URL编码并发送到Web服务器。默认实现只返回 record.__dict__
。如果只需要将 LogRecord
的一个子集发送到Web服务器,或者需要对发送到服务器的内容进行更具体的定制,则可以重写此方法。
emit(record)
将 record 做为一个URL编码的字典发送到Web服务器。mapLogRecord
方法用来将要发送的记录转换为字典。
注意:
由于准备将记录发送到Web服务器与一般格式化操作不同,因此使用
setFormatter()
为HTTPHandler
指定格式化程序没有效果。这个处理程序不是调用format()
,而是调用mapLogRecord()
,然后调用urllib.parse.urlencode()
,以适合发送到Web服务器的形式对字典进行编码。
QueueHandler
类,位于 logging.handlers
模块,支持将日志记录消息发送到一个队列,例如 queque
模块或 multiprocessing
模块中实现的队列。
与 QueueListener
类一起,QueueHandler
可用于让处理程序在独立于执行日志记录的线程上执行其工作。这在Web应用程序和其他服务应用程序中非常重要,在这些应用程序中,服务客户机的线程需要尽可能快地响应,而任何可能很慢的操作(例如通过SMTPHandler
发送电子邮件)都是在单独的线程上完成的。
class logging.handlers.QueueHandler(queue)
返回一个 QueueHandler
类的新实例。这个实例使用消息要发送到的队列进行初始化。队列可以是任何类队列(queue-like)对象;它按原样传递给 dequeue()
方法,dequeue()
方法需要知道如何从中获取消息
emit(record)
将准备 LogRecord
的结果排队。
prepare(record)
为排队准备一条记录。此方法返回的对象是已排队的。
基本实现会格式化记录,以便合并消息、参数和异常信息(如果存在的话)。它还从就地删除记录中 unpickleable 的项。
如果希望将记录转换为字典或JSON字符串,或者在保持原始记录不变的情况下发送修改后的记录副本,则可能需要覆盖此方法。
enqueue(record)
使用队列的 put_nowait()
方法将记录加入队列;如果您想使用阻塞行为、超时或自定义队列实现,则可能需要覆盖该方法。
QueueListener
类,位于 logging.handlers
模块中,支持从一个队列中接收日期记录消息,例如 queue
模块或 multiprocessing
模块中实现的队列。消息从内部线程中的队列接收,并在同一线程上传递给一个或多个处理程序进行处理。虽然QueueListener
本身不是一个处理程序,但在这里对它进行了文档说明,因为它与QueueHandler
携手工作。
与 QueueHandler
类一起,QueueListener
可用于让处理程序在独立于执行日志记录的线程上执行其工作。这在Web应用程序和其他服务应用程序中非常重要,在这些应用程序中,服务客户机的线程需要尽可能快地响应,而任何可能很慢的操作(例如通过SMTPHandler
发送电子邮件)都是在单独的线程上完成的。
class logging.handlers.QueueListener(queue, *handlers, respect_handler_level=False)
返回一个 QueueListener
类的新实例。这个实例使用要接收消息的队列和要处理队列中的条目的处理器的列表进行初始化。队列可以是任何类似队列的对象;它按原样传递给 dequeue()
方法,dequeue()
方法需要知道如何从中获取消息。如果 respt_handler_level
为 True,那么在决定是否将消息传递给该处理程序时,将会遵从处理程序的级别(与消息的级别相比);否则,其行为与以前的Python版本相同——总是将每个消息传递给每个处理程序。
dequeue(block)
删除记录并返回它,可以选择阻塞。
基本实现使用 get()
。如果希望使用超时或使用自定义队列实现,可能需要重写此方法。
prepare(record)
准备用于处理的记录。
这个实现只返回传入的记录。如果需要在将记录传递给处理程序之前对记录进行任何自定义编组或操作,则可能需要重写此方法。
handle(record)
处理一条记录。
只轮巡处理程序并为它们提供要处理的记录。传递给处理程序的实际对象是从prepare()
返回的对象。
start()
启动监听器。
启动一个后台线程来监视要处理日志记录的队列。
stop()
停止监听器。
请求线程终止,然后等待它这样做。注意,如果在应用程序退出之前不调用这个函数,队列上可能还会留下一些不会被处理的记录。
enqueue_sentinel()
将一个哨兵值写入队列,以通知侦听器退出。这个实现使用队列的 put_nowait()
方法。如果希望使用超时或使用自定义队列实现,可能需要重写此方法。