官网
Logger,Handler,Formatter,Filter
- Logger 记录器,暴露了应用程序代码能直接使用的接口。
- Handler 处理器,将(记录器产生的)日志记录发送至合适的目的地。
- Filter 过滤器,提供了更好的粒度控制,它可以决定输出哪些日志记录。
- Formatter 格式化器,指明了最终输出中日志记录的布局。
Logger
Logger是一个树形层级结构,在使用接口debug,info,warn,error,critical之前必须创建Logger实例,即创建一个记录器,如果没有显式的进行创建,则默认创建一个root logger,并应用默认的日志级别(WARN),处理器Handler(StreamHandler,即将日志信息打印输出在标准输出上),和格式化器Formatter(默认的格式即为第一个简单使用程序中输出的格式)。
logger = logging.getLogger(logger_name)
创建Logger实例后,可以使用以下方法进行日志级别设置,增加处理器Handler。
- logger.setLevel(logging.ERROR) # 设置日志级别为ERROR,即只有日志级别大于等于ERROR的日志才会输出
- logger.addHandler(handler_name) # 为Logger实例增加一个处理器
- logger.removeHandler(handler_name) # 为Logger实例删除一个处理器
Handler 处理器
Handler处理器类型有很多种,比较常用的有三个,StreamHandler,FileHandler,NullHandler
创建StreamHandler之后,可以通过使用以下方法设置日志级别,设置格式化器Formatter,增加或删除过滤器Filter。
- ch.setLevel(logging.WARN) # 指定日志级别,低于WARN级别的日志将被忽略
- ch.setFormatter(formatter_name) # 设置一个格式化器formatter
- ch.addFilter(filter_name) # 增加一个过滤器,可以增加多个
- ch.removeFilter(filter_name) # 删除一个过滤器
StreamHandler
创建方法: sh = logging.StreamHandler(stream=None)
NullHandler
NullHandler类位于核心logging包,不做任何的格式化或者输出。
本质上它是个“什么都不做”的handler,由库开发者使用。
Formatter 格式化器
使用Formatter对象设置日志信息最后的规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%S。
创建方法: formatter = logging.Formatter(fmt=None, datefmt=None)
其中,fmt是消息的格式化字符串,datefmt是日期字符串。如果不指明fmt,将使用'%(message)s'。如果不指明datefmt,将使用ISO8601日期格式。
有用的format格式:
格式 描述 %(levelno)s 打印日志级别的数值 %(levelname)s 打印日志级别名称 %(pathname)s 打印当前执行程序的路径 %(filename)s 打印当前执行程序名称 %(funcName)s 打印日志的当前函数 %(lineno)d 打印日志的当前行号 %(asctime)s 打印日志的时间 %(thread)d 打印线程id %(threadName)s 打印线程名称 %(process)d 打印进程ID %(message)s 打印日志信息
eg1:
import logging def fun(): # create logger logger = logging.getLogger('simple_example') logger.setLevel(logging.DEBUG) # create console handler and set level to debug ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) #creat file handler and set level to warning fh=logging.FileHandler(filename='test11.log') fh.setLevel(logging.WARNING) # create formatter formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # add formatter to ch and fh ch.setFormatter(formatter) fh.setFormatter(formatter) # add ch,sh to logger logger.addHandler(ch) logger.addHandler(fh) # 'application' code logger.debug('debug message') logger.info('info message') logger.warn('warn message') logger.error('error message') logger.critical('critical message') if __name__=='__main__': fun()
eg2:
import logging from logging import handlersfrom logging.handlers import SMTPHandler class Logger(object): level_relations = { 'debug':logging.DEBUG, 'info':logging.INFO, 'warning':logging.WARNING, 'error':logging.ERROR, 'crit':logging.CRITICAL } def __init__(self,filename,level='info',when='D',backCount=3,fmt='%(asctime)s - %(pathname)s-%(funcName)s-[line:%(lineno)d] - %(levelname)s: %(message)s'): self.logger = logging.getLogger(filename) format_str = logging.Formatter(fmt) self.logger.setLevel(self.level_relations.get(level)) sh = logging.StreamHandler() sh.setFormatter(format_str) th = handlers.TimedRotatingFileHandler(filename=filename,when=when,backupCount=backCount,encoding='utf-8') th.setFormatter(format_str) self.logger.addHandler(sh) self.logger.addHandler(th) mail_handler = SMTPHandler(mailhost=('smtp.163.com', 25), fromaddr='******@163.com', toaddrs='***@163.com', subject='*****', credentials=('*****@163.com', 'password')) mail_handler.setLevel(logging.ERROR) self.logger.addHandler(mail_handler)
if __name__ == '__main__': log = Logger('all.log',level='debug') log.logger.debug('debug') log.logger.info('info') log.logger.warning('warning') log.logger.error('error') log.logger.critical('critical') Logger('error.log', level='error').logger.error('error')