Pyhon日志logging
日志模块:
两种记录日志的方式:
1 使用logging提供的模块级别的函数(logging.basicConfig,logging.debug,logging.info....)
2 使用logging模块的组件(loggers,handlers,filters,formatters)
logging模块的组件包含四部分:
1 logger:可以程序直接调用的接口,app通过调用api来记录日志。log对象,
import logging
logger=logging.getLlogger()
可以用logger.info/debug/error/warning(msg)来说输出日志
2 handler:决定将日志分配至期望的路径
logger.add
3 filter:如果存在多个logger,可以根据名称过滤出指定logger来记录日志
4 formatter:定义日志格式
大致流程:
1 logging.getLogger()获取logger对象
logger=logging.getLogger()
2 创建一个或多个handler,用于执行日志信息的输出流向
#写入本地指定位置
fh=logging.FileHandler('path...')
#用于输出到控制台
ch=logging.StreamHandler()
3 创建一个或多个formatter,执行日志的格式,并分别将formatter绑定到上handler
formatter=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
4 将formatter绑定到handler上
fh.setFormatter(formater)
ch.setFormatter(formater)
4 将handler绑定到logger对象上
logger.addHandler(fh)
logger.addHandler(ch)
5 logger.setLever(logging.DEBUG)设置日志级别
6 最后边可以使用logger对象,记录日志
日志级别:
1 DEBUG 调试界别,一般用于问题的排查,日志信息最为详细
2 INFO 仅仅记录普通信息,日志信息的详细程度仅此于DEBUG
3 WARNING 警告信息,一般这类信息不回影响程序的正常的运行
4 ERROR 错误的信息,出现错误信息时,程序一般已经不能正常工作
5 CRITICAL 严重信息,程序不能运行
默认warning
filter组件使用:
用来过滤logger对象,一个filter可以直接添加到logger对象上,也可以添加到handler对象上
import logging logger_one=logging.getLogger('a.d') logger_two=logging.getLogger('a.r.c') filters=logging.Filter(name='a.d') ch=logging.StreamHandler() formattersK=logging.Formatter('%(asctime)s] - %(filename)s] - %(levelname)s: %(message)s') ch.setFormatter(formattersK) #若两个logger对象的日志级别相同,且都是通过一个handler 可以在这个handler上设置日志级别 ch.setLevel(logging.ERROR) #在handler上放置过滤器 # ch.addFilter(filters) # logger_one.addHandler(ch) # logger_two.addHandler(ch) # 在logger上放置过滤器 logger_one.addFilter(filters) logger_two.addFilter(filters) logger_one.warning('logger_one') logger_two.warning('logger_two')
formatter 组件使用
1 message 日志信息
2 levelname 日志信息等级
3 asctime 字符串形式的日期格式
4 name是logger的名字
5 levelno是数字形式的日志信息等级
6 module 调用日志输出函数的模块名
7 funcname 是调用日志输出函数的函数名字
8 lineno 调用日志出函数的代码行数
日志模块封装:
import logging,time import os cur_path=os.path.dirname(os.path.realpath(__file__)) log_path=os.path.join(os.path.dirname(cur_path),'logs') if not os.path.exists(log_path): os.mkdir(log_path) class Log(): def __init__(self): #文件名 self.logname=os.path.join(log_path,'%s.log'%time.strftime('%Y_%m_%d')) #日志收集器 日志句柄 self.logger=logging.getLogger() self.logger.setLevel(logging.DEBUG) #日志输出格式 self.formatter=logging.Formatter('%(asctime)s] - %(filename)s] - %(levelname)s: %(message)s') def __console(self,level,message): #创建一个FileHandler 用于写到本地 fh=logging.FileHandler(self.logname,'a',encoding='utf-8') fh.setLevel(logging.DEBUG) fh.setFormatter(self.formatter) self.logger.addHandler(fh) #创建一个StreamHandler 用于输出到控制台 ch=logging.StreamHandler() ch.setLevel(logging.DEBUG) ch.setFormatter(self.formatter) self.logger.addHandler(ch) if level == 'info': self.logger.info(message) elif level == 'debug': self.logger.debug(message) elif level == 'warning': self.logger.warning(message) elif level == 'error': self.logger.error(message) self.logger.removeHandler(ch) self.logger.removeHandler(fh) fh.close() def debug(self,message): self.__console('debug',message) def info(self,message): self.__console('info',message) def warning(self,message): self.__console('warning',message) def error(self,message): self.__console('error',message) if __name__ == '__main__': log=Log() log.info('log start') log.info('3333') log.warning('log end') log.debug('log end')