1.日志简介
说到日志,无论是写框架代码还是业务代码,都离不开日志的记录,他能给我们定位问题带来极大的帮助。
记录日志最简单的方法就是在你想要记录的地方加上一句 print , 我相信无论是新手还是老鸟都经常这么干。在简单的代码中或者小型项目中这么干一点问题都没有。但是在一些稍大一点的项目,有时候定位一个问题,需要查看历史日志定位问题,用print就不合时宜了。
print 打印出来的日志没有时间,不知道日志记录的位置,也没有可读的日志格式, 还不能把日志输出到指定文件。。。。除非这些你都全部自己重复造一遍轮子。
最佳的做法是使用内置的logging模块, 因为 logging 模块给开发者提供了非常丰富的功能。
2.日志级别
日志级别分为以下5个级别
日志级别 使用场景
DEBUG:debug级别用来记录详细的信息,方便定位问题进行调试,在生产环境我们一般不开启DEBUG
INFO:用来记录关键代码点的信息,以便代码是否按照我们预期的执行,生产环境通常会设置INFO级别
WARNING:记录某些不预期发生的情况,如磁盘不足
ERROR:由于一个更严重的问题导致某些功能不能正常运行时记录的信息
CRITICAL:当发生严重错误,导致应用程序不能继续运行时记录的信息
日志级别等级排序:CRITICAL> ERROR> WARNING> INFO> DEBUG
级别越高打印的日志越少,反之亦然,即
DEBUG: 打印全部的日志
INFO: 打印 info, warning, error, critical 级别的日志
WARNING: 打印 warning, error, critical 级别的日志,默认情况下日志的级别是WARGING
ERROR: 打印 error, critical 级别的日志
CRITICAL: 打印 critical 级别
备注:注意代码中日志级别需要使用大写
3.修改日志级别
如何让debug级别的信息也输出?
当然是修改默认的日志级别,在开始记录日志前可以使用logging.basicConfig方法来设定日志级别
import logging
logging.basicConfig( level=logging.DEBUG) # 日志级别需要使用大写
logging.debug("this is debug")
logging.info("this is info")
logging.error("this is error")
输出结果:
DEBUG:root:this is debug
INFO:root:this is info
ERROR:root:this is error
4.日志记录到文件
前面的日志默认会把日志输出到标准输出流,就是只在命令行窗口输出,程序重启后历史日志没地方找,所以把日志永久记录是一个很常见的需求。同样通过配置函数logging.basicConfig可以指定日志输出到什么地方
import logging
logging.basicConfig(filename='F:/example.log', level=logging.INFO)
logging.debug("this is debug")
logging.info("this is info")
logging.error("this is error")
这里我指定日志输出到文件test.log中,日志级别指定为了 INFO,最后文件中记录的内容如下:
INFO:root:this is info
ERROR:root:this is error
每次重新运行时,日志会以追加的方式在后面,如果每次运行前要覆盖之前的日志,则需指定 filemode=‘w’, 这个和 open 函数写数据到文件用的参数是一样的。
5.指定日志格式
默认输出的格式包含3部分,日志级别,日志记录器的名字,以及日志内容,中间用“:”连接。如果我们想改变日志格式,例如想加入日期时间、显示日志器名字,我们是可以使用format参数来设置日志的格式
import logging
logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s')
logging.error("this is error")
输出:
2021-12-15 07:44:16,547 ERROR root this is error
日志格式化输出提供了非常多的参数,除了时间、日志级别、日志消息内容、日志记录器的名字外,还可以指定线程名,进程名等等,具体如下:
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(levelname)s 文本形式的日志级别
%(message)s 用户输出的消息
%(filename)s 调用日志输出函数的模块的文件名
%(name)s Logger的名字%(levelno)s数字形式的日志级别
%(pathname)s 调用日志输出函数的模块的完整路径名,可能没有
%(module)s 调用日志输出函数的模块名
%(funcName)s 调用日志输出函数的函数名
%(lineno)d 调用日志输出函数的语句所在的代码行
%(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d 输出日志信息时的,自Logger创建以来的毫秒数
%(thread)d 线程ID。可能没有
%(threadName)s 线程名。可能没有
%(process) d进程ID。可能没有
到这里为止,日志模块的基本用法就这些了,也能满足大部分应用场景,更高级的方法接着往下看,可以帮助你更好的处理日志