日志Logging记录的重要性
在开发过程中,如果程序运行出现了问题,我们是可以使用我们自己的 Debug 工具来检测到到底是哪一步出现了问题,如果出现了问题的话,是很容易排查的。但程序开发完成之后,我们会将它部署到生产环境中去,这时候代码相当于是在一个黑盒环境下运行的,我们只能看到其运行的效果,是不能直接看到代码运行过程中每一步的状态的。在这个环境下,运行过程中难免会在某个地方出现问题,甚至这个问题可能是我们开发过程中未曾遇到的问题,碰到这种情况应该怎么办?
如果我们现在只能得知当前问题的现象,而没有其他任何信息的话,如果我们想要解决掉这个问题的话,那么只能根据问题的现象来试图复现一下,然后再一步步去调试,这恐怕是很难的,很大的概率上我们是无法精准地复现这个问题的,而且 Debug 的过程也会耗费巨多的时间,这样一旦生产环境上出现了问题,修复就会变得非常棘手。但这如果我们当时有做日志记录的话,不论是正常运行还是出现报错,都有相关的时间记录,状态记录,错误记录等,那么这样我们就可以方便地追踪到在当时的运行过程中出现了怎样的状况,从而可以快速排查问题。
因此,日志记录是非常有必要的,任何一款软件如果没有标准的日志记录,都不能算作一个合格的软件。作为开发者,我们需要重视并做好日志记录过程。
Logging和print?
总的来说 logging 模块相比 print 的优点:
①可以在 logging 模块中设置日志等级,在不同的版本(如开发环境、生产环境)上通过设置不同的输出等级来记录对应的日志,非常灵活。
②print 的输出信息都会输出到标准输出流中,而 logging 模块就更加灵活,可以设置输出到任意位置,如写入文件、写入远程服务器等。
③logging 模块具有灵活的配置和格式化功能,如配置输出当前模块信息、运行时间等,相比 print 的字符串格式化更加方便易用。
Logging基础知识
1.level和basicConfig的作用
(1)level
在python的Logging标准库中,分为五个日志级别level。
默认的日志级别是warning,所以只会输出后三种。
(2)basicConfig 的参数之level、filename、filemode、format
但是如果我们设置级别为info时,我们就看不到debug信息了。
下面我们使用 baseConfig() 来指定其日志输出级别为info 则输出后四种,root是记录器。
注意,logging.basicConfig级别的设置必须在最开头,即调用logging前!否则无效。
以上是用logging向控制台输出信息 那如何向文件中输出日志呢?只需要在logging.basicConfig中加一个filename参数即可!
# 这样只有print输出到控制台,其他都在文件里。
import logging
logging.basicConfig(filename='demo.log',level=logging.INFO)
print('this is a log text')
logging.debug("This is debug log") #打印的是调试级别
logging.info("This is info log") #信息级别
logging.warning("This is warning log") #警告级别
logging.error("This is error log") #错误级别
logging.critical("This is critical log") #致命级别
这就是最简单的方法将日志保存到文件系统上
logging.basicConfig中的filemode参数指定了日志的写入模式:w是写入模式(先清空再写入) a是追加模式
logging.basicConfig(filename='demo.log',filemode='w',level=logging.INFO)
也可以使用参数 format 添加一些公共信息定义日志输出格式
#输出格式和添加一些公共信息 format 定义日志输出格式
logging.basicConfig(format="(asctime)s|%(levelname)s|%(filename)s:%(lineno)s|(message)s", level = logging.DEBUG)
2.logging输出的格式及调用
还可以使用百分号或{}的形式对变量进行替换
import logging
logging.basicConfig(level = logging.DEBUG)
name ='张三'
age = 10
logging.debug("姓名 %s, 年龄%d", name,age)
logging.debug("姓名 {}, 年龄{}".format(name,age))
logging.debug(f"姓名 {name}, 年龄{age}")