Python 标准日志模块使用 Handler 控制日志消息写到不同的目的地,如文件、流、邮件、socket 等。除了StreamHandler、 FileHandler 和 NullHandler 定义在 logging 模块中,其他的 Handler 均定义在 logging.hangdlers 模块中。这些 Handler 是:WatchedFileHandler、RotatingFileHandler、TimedRotatingFileHandler、SocketHandler、DatagramHandler、SysLogHandler、NTEventLogHandler、SMTPHandler、MemoryHandler、HTTPHandler。
RotatingFileHandler 能够管理日志文件的大小,当日志文件的大小达到阈值后,它会重命名日志文件,然后再创建一个新的同名日志文件继续输出。
import logging import logging.handlers handler = logging.handlers.RotatingFileHandler( filename = ‘myapp.log‘, maxBytes = 200, backupCount = 5, ) handler.setFormatter( logging.Formatter( fmt = ‘%(asctime)s [%(threadName)s] (%(filename)s:%(lineno)d) %(levelname)s - %(message)s‘, datefmt = ‘%Y-%m-%d %H:%M:%S‘ ) ) root = logging.getLogger() root.setLevel(logging.DEBUG) root.addHandler(handler) for i in range(20): root.debug(‘The Message(%d/20).‘ % (i + 1))
参数 maxBytes 设定了日志文件大小的阈值,参数 backupCount 设定了备份文件的个数。当日志文件即 myapp.log 的大小达到阈值200字节的时候,RotatingFileHandler 会将 myapp.log 重命名为 myapp.log.1,然后再创建一个新的同名日志文件 myapp.log。当 myapp.log 的大小又达到200字节时,RotatingFileHandler 将会把 myapp.log.1 重命名为 myapp.log.2,再把 myapp.log 重命名为 myapp.log.1,然后再创建一个新的同名日志文件 myapp.log。这样反复直到创建了5个备份文件后,当 myapp.log 的大小再次达到200字节时,RotatingFileHandler 不会将 myapp.log.5 重命名为 myapp.log.6 而是将其删除。
TimedRotatingFileHandler 和 RotatingFileHandler 类似,不过,TimedRotatingFileHandler 没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就自动创建新的日志文件。重命名的过程中,备份日志文件的后缀不是数字,而是当前时间。
import logging import logging.handlers import time handler = logging.handlers.TimedRotatingFileHandler( filename = ‘myapp.log‘, when = ‘M‘, interval = 2, backupCount = 3, ) handler.setFormatter( logging.Formatter( fmt = ‘%(asctime)s [%(threadName)s] (%(filename)s:%(lineno)d) %(levelname)s - %(message)s‘, datefmt = ‘%Y-%m-%d %H:%M:%S‘ ) ) root = logging.getLogger() root.setLevel(logging.DEBUG) root.addHandler(handler) for i in range(20): root.debug(‘The Message(%d/20).‘ % (i + 1)) time.sleep(30)
参数 interval 设定了时间间隔,参数 when 设定了间隔的单位。when 的取值可以是 ‘S‘(秒)、 ‘M‘(分)、 ‘H‘(小时)、 ‘D‘(天)、 ‘W0‘ - ‘W6‘(周一至周六)、 ‘midnight‘(凌晨),当 when 的取值是 ‘W0‘ - ‘W6‘ 或 ‘midnight‘ 时,参数 interval 的取值是被忽略的。
SMTPHandler 能够通过 SMTP 将日志消息发送到邮件服务器中。
import logging import logging.handlers handler = logging.handlers.SMTPHandler( mailhost = (‘smtp.163.com‘, 25), fromaddr = ‘[email protected]‘, toaddrs = ‘[email protected]‘, subject = ‘SMTPHandler Demo‘, credentials = (‘[email protected]‘, ‘123456‘) ) handler.setLevel(logging.CRITICAL) handler.setFormatter( logging.Formatter( fmt = ‘%(asctime)s [%(threadName)s] (%(filename)s:%(lineno)d) %(levelname)s - %(message)s‘, datefmt = ‘%Y-%m-%d %H:%M:%S‘ ) ) root = logging.getLogger() root.addHandler(handler) root.critical(‘This is a critical message‘);
其他 Handler 的用法示例待补充。