logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级、日志保存路径、日志文件回滚等
一、日志等级
日志等级一共分为5个等级,从低到高分别是:debug 、info、warning、error、critical
debug: 输出详细的运行情况,主要用于调试
info: 确认一切按照预期运行,一般用于输出重要运行情况(主体功能是不是按照预期进行)
warning : 警告,一些意想不到的事情发生了(比如:内存空间不存),但是这个软件还能按照预期工作,在不久的将来会出现问题。
error: 发生了错误,软件没能执行一些功能,还能继续执行
critical : 一个严重的错误,表明程序本身可能无法继续运行
这5个等级,也分别对应5种打日志的方法:debug、info、warning、error、critical. 默认的是WARNING,当在WARNING或之上时才能被跟踪
#导入logging模块,#logging是内置模块,不需要安装 import logging groups = [ ['zhangsan', 'lisi'], ['wanger', 'zhaoliu'], ['qiqi', 'polo'] ] for group in groups: #print(group)不使用print,用logging查看日志 logging.debug('group={}'.format(group)) for name in group: #print(each) logging.debug('name={}'.format(name)) # print(groups) logging.info('groups={}'.format(groups)) if type(groups) == list: logging.warning('目前是list,后面不会支持list了') if type(groups) == list: logging.error('不支持list了') ''' WARNING:root:目前是list,后面不会支持list了 ERROR:root:不支持list了 '''
二、日志收集器/输出器,输入到控制台
1)原理
py文件----》日志收集器(自己的笔记本)------》输入处理器----》控制台
py文件----》日志收集器(自己的笔记本)------》文件处理器----》文件
日志收集器:可以自己设置级别
处理器:也可以自己设置级别
最后的日志级别:日志收集器+处理器
2)控制台输出处理器
# 第一步:创建一个日志收集器(笔记本) # 得到root收集器,root日志默认级别是warning,只能收集warning以上级别的日志 root_logger = logging.getLogger() # 设置收集器的收集等级 root_logger.setLevel('DEBUG') # 第二步:handler输入处理器,流信息 stream_handler = logging.StreamHandler() stream_handler.setLevel('DEBUG') # 第三步:把输入处理器添加到收集器上面 root_logger.addHandler(stream_handler) # 输入debug日志 root_logger.debug('debug等级日志!') root_logger.info('info等级日志!') root_logger.warning('warning等级日志!') root_logger.error('error等级日志!') root_logger.critical('critical等级日志!')
![](https://img2020.cnblogs.com/blog/2139604/202009/2139604-20200915160205254-1213901893.png)
3)日志输入到文件
# 第一步:创建一个日志收集器(笔记本) # 得到root收集器,root日志默认级别是warning,只能收集warning以上级别的日志 root_logger = logging.getLogger() # 设置收集器的收集等级 root_logger.setLevel('DEBUG') # 第二步:文件输入处理器 file_handler = logging.FileHandler('log.txt',encoding='utf-8') file_handler.setLevel('WARNING') root_logger.addHandler(file_handler) # 输入debug日志 root_logger.debug('debug等级日志!') root_logger.info('info等级日志!') root_logger.warning('warning等级日志!') root_logger.error('error等级日志!') root_logger.critical('critical等级日志!')
![](https://img2020.cnblogs.com/blog/2139604/202009/2139604-20200915160230109-802906724.png)
三、日志输入格式
logging
--- Python 的日志记录工具:
https://docs.python.org/zh-cn/3/library/logging.html#logging.Handler.setFormatter
%(name)s |
Logger的名字 |
%(levelno)s |
数字形式的日志级别 |
%(levelname)s |
文本形式的日志级别 |
%(pathname)s |
调用日志输出函数的模块的完整路径名,可能没有 |
%(filename)s |
调用日志输出函数的模块的文件名 |
%(module)s |
调用日志输出函数的模块名 |
%(funcName)s |
调用日志输出函数的函数名 |
%(lineno)d |
调用日志输出函数的语句所在的代码行 |
%(created)f |
当前时间,用UNIX标准的表示时间的浮 点数表示 |
%(relativeCreated)d |
输出日志信息时的,自Logger创建以 来的毫秒数 |
%(asctime)s |
字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 |
%(thread)d |
线程ID。可能没有 |
%(threadName)s |
线程名。可能没有 |
%(process)d |
进程ID。可能没有 |
%(message)s |
用户输出的消息 |
# 日志格式及输入
fmt = logging.Formatter('%(asctime)s--%(filename)s--%(lineno)d--%(levelname)s--%(message)s') file_handler.setFormatter(fmt)
# 第一步:创建一个日志收集器(笔记本) # 得到root收集器,root日志默认级别是warning,只能收集warning以上级别的日志 root_logger = logging.getLogger() # 设置收集器的收集等级 root_logger.setLevel('DEBUG') # handler输入处理器,流信息 stream_handler = logging.StreamHandler() stream_handler.setLevel('DEBUG') # 把输入处理器添加到收集器上面 root_logger.addHandler(stream_handler) # 文件输入处理器 file_handler = logging.FileHandler('log.txt',encoding='utf-8') file_handler.setLevel('WARNING') root_logger.addHandler(file_handler) # 日志格式及输入 fmt = logging.Formatter('%(asctime)s--%(filename)s--%(lineno)d--%(levelname)s--%(message)s') file_handler.setFormatter(fmt) # 输入debug日志 root_logger.debug('debug等级日志!') root_logger.info('info等级日志!') root_logger.warning('warning等级日志!') root_logger.error('error等级日志!') root_logger.critical('critical等级日志!')
![](https://img2020.cnblogs.com/blog/2139604/202009/2139604-20200915161403470-2143513372.png)
四、log封装
1)函数封装(项目中用函数封装即可)
import logging def get_logger( name=None, file=None, logger_level='DEBUG', stream_level='DEBUG', file_level='DEBUG', ): '''获取收集器''' logger = logging.getLogger(name) # 设置收集器级别 logger.setLevel(logger_level) # 设置输入管理器 stream_handler = logging.StreamHandler() stream_handler.setLevel(stream_level) logger.addHandler(stream_handler) # 设置格式 fmt_value = '%(asctime)s--%(filename)s--%(lineno)d--%(levelname)s--%(message)s' fmt = logging.Formatter(fmt_value) stream_handler.setFormatter(fmt) if file: file_handler = logging.FileHandler(file,encoding='utf-8') file_handler.setLevel(file_level) logger.addHandler(file_handler) file_handler.setFormatter(fmt) return logger if __name__ == '__main__': logger = get_logger(file='log.txt') logger.info('hello') logger.warning('警告')
2)类封装(不继承)
class LoggerHandler(): def __init__(self, name = None, file = None, logger_level='DEBUG', stream_level='DEBUG', file_level='DEBUG',): '''获取收集器''' logger = logging.getLogger(name) # 设置收集器级别 logger.setLevel(logger_level) # 设置输入管理器 stream_handler = logging.StreamHandler() stream_handler.setLevel(stream_level) logger.addHandler(stream_handler) # 设置格式 fmt_value = '%(asctime)s--%(filename)s--%(lineno)d--%(levelname)s--%(message)s' fmt = logging.Formatter(fmt_value) stream_handler.setFormatter(fmt) if file: file_handler = logging.FileHandler(file, encoding='utf-8') file_handler.setLevel(file_level) logger.addHandler(file_handler) file_handler.setFormatter(fmt) self.logger = logger
3)类封装(继承logger.Logger)
class LoggerHandler2(logging.Logger): def __init__(self, name = None, file = None, logger_level='DEBUG', stream_level='DEBUG', file_level='DEBUG',): super().__init__(name,logger_level) # 设置收集器级别 self.setLevel(logger_level) # 设置输入管理器 stream_handler = logging.StreamHandler() stream_handler.setLevel(stream_level) self.addHandler(stream_handler) # 设置格式 fmt_value = '%(asctime)s--%(filename)s--%(lineno)d--%(levelname)s--%(message)s' fmt = logging.Formatter(fmt_value) stream_handler.setFormatter(fmt) if file: file_handler = logging.FileHandler(file, encoding='utf-8') file_handler.setLevel(file_level) self.addHandler(file_handler) file_handler.setFormatter(fmt) if __name__ == '__main__': logger = LoggerHandler2() logger.info('hello') logger.warning('警告')