Python 中的 logging 模块主要作用是可以跟踪代码运行时的事件生成日志,当程出现错误时可以查看日志并定位问题。
日志记录的重要性:
在本地调试程序时,如果程序出现了错误,一般都是通过debug模式或print()输出到控制台去查找定位问题。但是如果程序开发完成部署到生产环境,这时候只能看到程序的运行结果,然而代码运行时却出现了本地未出现过的错误;这时如果没有记录log的话,只能一步步调试去尝试复现问题,这样即浪费时间也有很大的概率无法迅速定位到问题。所以日志记录是非常重要的。
logging包含的日志级别及说明:
DEBUG:输出详细运行情况,主要用于调试
INFO:确认一切按预期运行,一般用于输出重要运行情况
WARNING:一些意想不到的事情发生了(比如:‘警告:内存空间不足’),,但是程序还能按预期工作。
ERROR:发生了错误,程序没能执行一些功能,还可以继续执行
CRITICAL:严重的错误,表面程序本身可能无法运行
来看下是如何使用的:
import logging#导入logging模块
logger=logging.getLogger()#c初始化收集器
logger.debug('debug等级日志')
logger.info('info等级日志')
logger.warning('warning等级日志')
logger.error('erro等级日志')
logger.critical('critical等级日志')
结果:
WARNING:root:warning等级日志
ERROR:root:erro等级日志
CRITICAL:root:critical等级日志
可以看到只输出了warning级别及以上级别的日志;debug,info级别的日志都没有输出,因为logging默认是warning级别,debug info级别被过滤了。
如果输出debug级别的日志可以通过logging.basicConfig全局配置去指定级别:
import logging#导入logging模块
logging.basicConfig(level=logging.DEBUG)#全局配置
logger=logging.getLogger()#c初始化收集器
logger.debug('debug等级日志')
logger.info('info等级日志')
logger.warning('warning等级日志')
logger.error('erro等级日志')
logger.critical('critical等级日志')
结果:
DEBUG:root:debug等级日志
INFO:root:info等级日志
WARNING:root:warning等级日志
ERROR:root:erro等级日志
CRITICAL:root:critical等级日志
但是这种的日志输出格式肯定不是我们想要的;没有显示一些重要的信息,比如运行时间、模块名称、代码的行号,日志级别等这些信息。如下部分参数:
%(name)s:收集器名称,默认是root
%(levelno)s:打印日志级别的数值
%(levelname)s:打印日志级别的名称
%(pathname)s:打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s:打印当前执行程序名
%(funcName)s:打印日志的当前函数
%(lineno)s:打印日志的当前行号
%(asctime)s:打印日志的时间
%(thread)d:打印线程ID
%(threadName)s:打印线程名称
%(process)d:打印进程ID
%(message)s:打印日志信息
在basicConfig中配置format输出格式,常用格式如下
import logging
logging.basicConfig(level=logging.DEBUG,format='%(asctime)s--%(filename)s--%(lineno)d--%(levelname)s:%(message)s')
logger=logging.getLogger()
logger.debug('debug等级日志')
logger.info('info等级日志')
logger.warning('warning等级日志')
logger.error('erro等级日志')
logger.critical('critical等级日志')
结果:
2020-05-29 14:16:45,861--demo.py--43--DEBUG:debug等级日志
2020-05-29 14:16:45,861--demo.py--44--INFO:info等级日志
2020-05-29 14:16:45,861--demo.py--45--WARNING:warning等级日志
2020-05-29 14:16:45,861--demo.py--46--ERROR:erro等级日志
2020-05-29 14:16:45,861--demo.py--47--CRITICAL:critical等级日志
但是使用basicConfig配置日志等级,有时候会不符合我们的应用场景,所以可以自己创建;
1.实例化一个收集器 logger=logging.getLogger()
2.设置收集器的日志等级 logger.setLevel(’ ')
3.实例化一个处理器handler=logging.StreamHandler(),处理器类型有很多种,比较常用的有,StreamHandler,FileHandler
4.设置处理器日志级别,handler.setLevel(’ ')
5.把输出处理器添加到收集器上面,logger.addHandler(handler)
StreamHandler输出处理器,输出到控制台:
import logging
logger=logging.getLogger()
logger.setLevel('DEBUG')
handler=logging.StreamHandler()
handler.setLevel('DEBUG')
logger.addHandler(handler)
logger.debug('debug等级')
logger.info('info等级日志')
logger.warning('warning等级日志')
logger.error('erro等级日志')
logger.critical('critical等级日志')
结果:
debug等级
info等级日志
warning等级日志
erro等级日志
critical等级日志
其输入日志等级的原理跟上面一致,输出当前设置的日志等级及以上等级的日志,如果把等级设置成error,那么输出结果就是:
erro等级日志
critical等级日志
set.Level()里面填写的日志等级一定要用大写字母,不如报错:
import logging
logger=logging.getLogger()
logger.setLevel('error')
str_stream=logging.StreamHandler()
str_stream.setLevel('error')
logger.addHandler(str_stream)
logger.error('erro等级日志')
结果:
ValueError: Unknown level: 'error'
FileHandler()文件输出处理器,输出日志内容到文件,需要传参,看下源码:
需要传文件名称,写入模式默认为a。
如下:
import logging
logger=logging.getLogger()
logger.setLevel('ERROR')
file_handler=logging.FileHandler('data.txt',encoding='utf-8')
file_handler.setLevel('ERROR')
logger.addHandler(file_handler)
logger.debug('debug等级')
logger.info('info等级日志')
logger.warning('warning等级日志')
logger.error('erro等级日志')
logger.critical('critical等级日志')
结果:
在当前文件目录下会创建一个data.txt文件,内容为
erro等级日志
critical等级日志
设置日志输出格式使用logging.Formatter(‘%s–%d…’),通过setFormatter加到处理器,如下完整代码:
import logging
logger=logging.getLogger()#初始化收集器
logger.setLevel('DEBUG')#收集器设置等级
fmt = logging.Formatter('%(asctime)s--%(filename)s--hanghao:%(lineno)d--%(levelname)s:%(message)s')#日志输出格式
file_handler=logging.FileHandler('data.txt',encoding='utf-8')#文件输出处理器
file_handler.setLevel('ERROR')#处理器设置等级
logger.addHandler(file_handler)#处理器加到收集器
stream_handler=logging.StreamHandler()#输出处理器
stream_handler.setLevel('INFO')
logger.addHandler(stream_handler)#添加到处理器
file_handler.setFormatter(fmt)#日志格式加到处理器
str_stream.setFormatter(fmt)
logger.debug('debug等级')
logger.info('info等级日志')
logger.warning('warning等级日志')
logger.error('erro等级日志')
logger.critical('critical等级日志')
共两个处理器,一个输出日志到文件,一个输出日志到控制台,但是处理器的日志等级是不
一样的,所以输出结果也会不同,如下:
str_stream输出日志结果:
2020-05-29 15:05:18,326--demo.py--hanghao:62--INFO:info等级日志
2020-05-29 15:05:18,326--demo.py--hanghao:63--WARNING:warning等级日志
2020-05-29 15:05:18,327--demo.py--hanghao:64--ERROR:erro等级日志
2020-05-29 15:05:18,328--demo.py--hanghao:65--CRITICAL:critical等级日志
file_handler输出日志结果:
创建data.txt文件,内容如下
2020-05-29 15:10:04,805--demo.py--hanghao:64--ERROR:erro等级日志
2020-05-29 15:10:04,805--demo.py--hanghao:65--CRITICAL:critical等级日志