作为一个初学编程的小伙子,常常调试代码用print,print的好处是直接就能看出代码的问题,和运行的情况,但是比较麻烦的是在运行完成之后要把print全波注释掉,或者删除,这很影响美观,而且比较麻烦,尤其在代码比较多的情况下,往往看到print的结果后就头疼不已:这一行打印了什么,这一行又是什么结果。所幸的是python和其他语言一样,有一个强大的日志模块——logging模块
日志的作用
1.可以直观看出程序运行结果,此程序之外,也可以生成一个日志文件供开发者查看,一旦程序出了问题,自己编写的程序,在查看自己的日志后都能第一时间发现错误所在。
2.在用户端,用户使用时产生的日志,可以分析出用户的爱好,时间,习惯以及其他,有很好的商业价值。
3.logging模块可以分层次也可以说分等级导出日志,开发人员不需要在看日志的时候查看大量的调试信息,只要查看错误所在就可以了。
日志等级
logging模块高于print的原因之一是可以分日志等级,日志等级分为:
等级 | 使用 |
---|---|
DEBUG >>> 10 | 调试,一般用于代码调试,问题诊断 |
INFO >>> 20 | 信息,一般用于预知运行的情况 |
WARNING >>> 30 | 警告,这时程序还没有出现问题,用于预警将要出现的问题,比如内存占用过大等等 |
ERROR >>> 40 | 错误,程序此时已经不能运行,出现了一个错误 |
CRITICAL >>>50 | 严重错误,程序不能运行出现了一个严重错误 |
在开发的时候用debug调试,然后用info记录程序的运行情况,用warning预警信息,用error记录错误信息,更严重迫不得已用critical。
这里的日志等级是 CRITICAL > ERROR > WARNING > INFO > DEBUG 在查看日志的时候可以使用logging.xxx来设置日志等级
实例:
import logging
logging.basicConfig(level=logging.NOTSET)
#上面用level=logging.NOTSET设置显示日志最低等级为0
logging.debug('这里新建一个debug日志,级别为10')
logging.info('这里新建一个info日志,级别为20')
logging.warning('这里新建一个warning日志,级别为30')
logging.error('这里新建一个error日志,级别为40')
logging.critical('这里新建一个critical日志,级别为50')
结果
DEBUG:root:这里新建一个debug日志,级别为10
INFO:root:这里新建一个info日志,级别为20
WARNING:root:这里新建一个warning日志,级别为30
ERROR:root:这里新建一个error日志,级别为40
CRITICAL:root:这里新建一个critical日志,级别为50
如果我们不想看到debug调试信息我们可以把日志等级调高:
import logging
logging.basicConfig(level=logging.INFO)
#上面设置的日志等级比debug高所以不会显示出debug日志
logging.debug('这里新建一个debug日志,级别为10')
logging.info('这里新建一个info日志,级别为20')
logging.warning('这里新建一个warning日志,级别为30')
logging.error('这里新建一个error日志,级别为40')
logging.critical('这里新建一个critical日志,级别为50')
结果:
INFO:root:这里新建一个info日志,级别为20
WARNING:root:这里新建一个warning日志,级别为30
ERROR:root:这里新建一个error日志,级别为40
CRITICAL:root:这里新建一个critical日志,级别为50
日志格式
logging模块优于print之二,可以自定义设置日志的格式,还可以设置输出为一个文件,集体关键字如下:
关键字 | 用法 |
---|---|
filename | 文件名关键字,可以将日志输出到以filename为关键字的文件中 |
filemode | 文件写入方式,可以设置追加a,或者写入w |
format | 按照format格式化输出日志 |
datefmt | 时间格式输出日志 |
level | 设置日志的级别 |
用法实例:
logging.basicConfig(level=logging.NOTSET,
filename='日志1.txt',
filemode='w',
format='%(asctime)s %(name)s %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
for i in range(4):
logging.info(i)
print(f'这里循环的i值为{i}')
日志结果在日志1.txt文件中查看
2018-12-16 15:21:03 root INFO 0
2018-12-16 15:21:03 root INFO 1
2018-12-16 15:21:03 root INFO 2
2018-12-16 15:21:03 root INFO 3
那么问题来了,我们究竟如何将日志正确的format呢,python提供了详细的format方法
格式是format=’%(xxx)s’使用时候只需填入xxx就可以了
详细信息
xxxx关键字 | 用法 |
---|---|
asctime | 时间输出,时间格式在datefmt中设置 |
name | 日志的名称,默认为root可以在logging.basicConfig()中更改 |
filename | 调用函数的文件名 |
funcName | 日志输出的函数名 |
levelName | 日志等级名称 |
message | 日志的信息 |
lineno | 日志的代码行 |
process | 进程id |
processName | 进程的名称 |
thread | 线程id |
threadName | 线程名称 |
还有一些其他的关键字没有涉及到,不做阐述,详情请看python文库和官方文档
日志流程处理
logging模块可以通过一些组件处理日志。
以下是流程处理的组件概念
组件 | 方法 |
---|---|
Logger 记录器 | 提供程序运行的接口 |
Handler 处理器 | 将记录器产生的日志发送到合适的地点 |
Filter 过滤器 | 提供过滤方法,设置输出哪些信息 |
Formatter 格式化器 | 格式化日志输出方式 |
logger 记录器:使用接口debug、info、warning等之前必须创建logger实例(创建logger记录器)创建方法:logger = logging.getLogger(logger_name)
创建之后可以进行以下操作:
方法 | 用法 |
---|---|
logger.setLevel(logging.ERROR) | 设置日志等级 |
logger.addHandler(name) | 创建一个名为handler_name的处理器 |
logger.removeHandler(name) | 删除名为name的处理器 |
Handler 处理器
Handler处理器有三种处理方式,StreamHandler FileHandler Nullhandler
Handler简要说明
方法 | 用法 |
---|---|
name.setLevel(logging.WARNING) | 设置日志等级 |
name.setFormatter(name) | 设置处理器的输出格式 |
处理器实例流程
1.创建logger 日志器实例
2.设置logger日志等级
3.创建Handler处理器实例
4.设置处理器日志输出格式
5.将处理器注册到日志器中
6.运行
代码展示:
import logging
#创建logger日志器
logger = logging.getLogger('日志器')
#设置日志器等级
logger.setLevel(logging.INFO)
#创建处理器
hl_f = logging.FileHandler('日志3.log','w',encoding='utf-8') #这是文件处理器
hl_s = logging.StreamHandler() #这是控制台处理器
#设置处理器输出日志格式
formatter = logging.Formatter(
fmt='%(asctime)s %(name)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
hl_f.setFormatter(formatter)
hl_s.setFormatter(formatter)
#将处理器注册到日志器中
logger.addHandler(hl_s)
logger.addHandler(hl_f)
#现在添加两条日志
logger.debug('调试日志,低于日志器等级')
logger.info('信息日志')
logger.warning('警告日志')
运行结果
1.控制台
2018-12-16 18:29:34 日志器 信息日志
2018-12-16 18:29:34 日志器 警告日志
2.文件
2018-12-16 18:29:34 日志器 信息日志
2018-12-16 18:29:34 日志器 警告日志
日志流程封装在后面