python的logging模块提供了标准日志接口。
级别
- debug()
- info()
- waring()
- error()
- critical()
日志的用途
记录访问信息,用于分析
记录系统信息
使用方法
import logging
logging.warning('密码输入错误三次')
logging.critical('服务器关闭')
# 默认输出到屏幕,默认用户是root
WARNING:root:密码输入错误三次
CRITICAL:root:服务器关闭
把日志输出到文件
logging.basicConfig(filename='log_test.log',
level=logging.WARNING,
format = '%(asctime)s %(message)s',
datefmt='%Y-%m-%d %I:%M:%S %p')
# level 只记录此等级及以上等级的日志
logging.debug('This message should go to the log file')
logging.warning('密码输入错误三次')
logging.critical('服务器关闭')
format参数
%(levelno)s: 打印日志级别的数值
%(levelname)s: 打印日志级别名称
%(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s: 打印当前执行程序名
%(funcName)s: 打印日志的当前函数
%(lineno)d: 打印日志的当前行号
%(asctime)s: 打印日志的时间
%(thread)d: 打印线程ID
%(threadName)s: 打印线程名称
%(process)d: 打印进程ID
%(message)s: 打印日志信息
同时向文件和屏幕输出日志信息
Python使用logging模块记录日志涉及四个主要的类:
- logger:提供了应用程序可以直接使用的接口
- handler:将(logger创建的)日志记录发送到合适的输出
- filter:提供了细度设备来决定输出哪条日志记录
- formatter:决定日志记录的最终输出格式
logger
每个程序在输出信息之前都要获得一个Logger。通常对应了程序的模块名。
LOG = logging.getLogger('chat.gui')
可以绑定handler和filters
Logger.setLevel(lel):指定最低日志等级,默认为debug
Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter
Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
handler
负责发送相关信息到指定的目的地。可以把信息输出到控制台、文件、网络等。
Handler.setLevel(lel):设置处理信息级别
Handler.setFormatter():设置输出格式
Handler.addFilter(filt)、.removeFilter(filt):添加或删除指定的filter
每个Logger可以添加多个Handler。
常见的Handler
- logging.StreamHandler:使用这个Handler可以向类似与sys.stdout或者sys.stderr的任何文件对象(file object)输出信息。
- logging.FileHandler:与StreamHandler类似,用于向一个文件输出日志信息,会帮你打开这个文件。
- logging.handlers.RotatingFileHandler:类似于FileHandler,但他可以管理文件大小。当文件到达一定大小之后,会自动将当前日志文件改名,然后创建一个新的同名日志文件继续输出。比如日志文件是chat.log。当chat.log达到指定大小之后,RotatingFileHandler自动把文件名改成chat.log.1如果chat.log.1已存在改成chat.log.2以此类推,最后重新创建chat.log。继续输出日志信息。它的函数是
RotatingFileHandler(filename[,mode[,maxBytes[,backupCount]]])
- logging.handlers.TimedRotatingFileHandler:与RotatingFileHandler类似,不过,他没有通过判断文件大小来决定何时重新创建日志文件,而是间隔一定时间就自动创建新的日志文件。重命名过程与RotatingFileHandler类似,新的文件不是附加数字,而是当前时间。它的函数是:
TimedRotatingFileHandler(filename[,when[,interval[,backupCount]]])
interval是时间间隔。
when参数是一个字符串。表示时间间隔的单位,不区分大小写。它有以下取值:
- S秒
- M分
- H小时
- D天
- W每星期(interval == 0 时,代表星期一)
- midnight每天凌晨
formatter
日志的formatter是一个独立的组件,可以跟handler组合
fh = logging.FileHandler('access.log')
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
filter
对日志内容进行过滤
class IgnorBackupLogFilter(logging.Filter):
"""忽略带db backup的日志"""
def filter(self,record):
return "db backup" not in record.getMessage()
# filter函数返回bool值,logger根据此值决定是否输出日志
# 然后把这个filter添加到logger中
logger.addFilter(IgnorBackupLogFilter())
同时输出到屏幕、文件带filter的完整例子
import logging
class IgnorBackupLogFilter(logging.Filter):
def filter(self,record):
return "db backup" not in record.getMessage()
# console handler
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
# file handler
fh = logging.FileHandler('mysql.log')
fh.setLevel(logging.WARNING)
# formatter
console_formatter = logging.Formatter('%(asctime)s - %(message)s')
file_formatterch = logging.Formatter('%(asctime)s - %(message)s - %(pathname)s')
ch.setFormatter(console_formatter)
fh.setFormatter(file_formatterch)
logger = logging.getLogger('Mysql')
logger.setLevel(logging.DEBUG) # logger优先级高于其他输出途径
logger.addFilter(IgnorBackupLogFilter())
logger.addHandler(ch)
logger.addHandler(fh)
logger.info('asdasd')
logger.warning('db backup')
日志自动截断例子
import logging
from logging import handlers
# file handler
# 每十个字节截断一次
fh1 = logging.handlers.RotatingFileHandler('web.log',maxBytes=10,backupCount=3)
# 每3秒截断一次
fh2 = logging.handlers.TimedRotatingFileHandler('web2.log',when='S',interval=3)
fh1.setLevel(logging.WARNING)
logger = logging.getLogger('Mysql')
logger.setLevel(logging.DEBUG) # logger优先级高于其他输出途径
logger.addHandler(fh1)
logger.addHandler(fh2)
logger.warning('1234567890')