前言
日志是对于软件执行所发生的事件的一种追踪记录方式。日常使用过程中对代码执行的错误和问题会进行查看日志来分析定位问题所在。平常编写代码以及调试也经常用到。通常的新手的做法是直接print打印,但是打印的结果只在控制台显示。今天我们学习一种高级的日志打印和记录模块logging。
logging提供了一系列的函数,它们是debug(), info(), warning(), error(), 和critical()。
他们的使用场景请看下表
日志功能分别对各种事件和严重性都进行分级。
示例
简单示例
因为是python自带的所以无需安装,默认的级别是WARNING,所以下面只显示一条warning信息。
import logging
logging.warning('this is warning')
logging.info('this is info')
更改级别
我们将默认的级别改成最低级别,则会打印同级别以及高级别的日志信息
import logging
logging.basicConfig(level=logging.DEBUG)
logging.debug('this is debug')
logging.info('this is info')
logging.warning('this is warning')
logging.error('this is error')
保存日志
只是打印到控制台对于少量信息倒是可控,但是信息量大的时候就不方便查找了。那么我们需要将其保存到文件中。
import logging
logging.basicConfig(level=logging.DEBUG,filename='log.log',format='%(asctime)s - %(lineno)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
logger.debug('this is debug')
logger.info('this is info')
logger.warning('this is warning')
logger.error('this is error')
上面我们在保存的时候,同时还添加了其他描述信息,比如执行时间,执行代码行数,日志级别,打印消息。当然方法远不止这些,具体请看下表
日志输出进阶
首先了解以下进阶的方法的说明:
StreamHandler
类位于核心 logging
包,它可将日志记录输出发送到数据流例如 sys.stdout, sys.stderr 或任何文件类对象(或者更精确地说,任何支持 write()
和 flush()
方法的对象
FileHandler
类位于核心 logging
包,它可将日志记录输出到磁盘文件中。 它从 StreamHandler
继承了输出功能。
我们需要通过调用 Logger
类(以下称为 loggers , 记录器)的实例来执行日志记录。
Logger
对象有三个常见的方法:
Logger.setLevel()
指定记录器将处理的最低严重性日志消息,其中 debug 是最低内置严重性级别, critical 是最高内置严重性级别。 例如,如果严重性级别为 INFO ,则记录器将仅处理 INFO 、 WARNING 、 ERROR 和 CRITICAL 消息,并将忽略 DEBUG 消息。Logger.addHandler()
和Logger.removeHandler()
从记录器对象中添加和删除处理程序对象。处理程序在以下内容中有更详细的介绍 处理程序 。Logger.addFilter()
和Logger.removeFilter()
可以添加或移除记录器对象中的过滤器。 Filter 对象 包含更多的过滤器细节。
下面示例采用添加日志记录器对象输出和上面一样在控制台打印
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level=logging.INFO)
handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(lineno)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.info('This is a log info')
logger.debug('Debugging')
logger.warning('Warning exists')
logger.info('Finish')
当然也同样能保存到文件,为了演示修改了文件名称为put.log
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level=logging.INFO)
handler = logging.FileHandler('put.log')
formatter = logging.Formatter('%(asctime)s - %(lineno)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.info('This is a log info')
logger.debug('Debugging')
logger.warning('Warning exists')
logger.info('Finish')
日志双向输出
既然之前的方案已经能达到相同的效果了,那么后面的方法到底有什么强大之处。我们来实现一个之前方法所不能达成的效果。
上面的日志信息虽然都保存到了文本中,但是控制台却没有了任何信息,这对我们查看日志也不是很友好,我们希望的是既能在控制台输出,同时也能保存到日志文件中。
我们添加两个日志记录器对象,一个使用输出到控制台的功能一个使用保存到文件的功能,就可以实现同时执行输出和保存了。
import logging
logger = logging.getLogger(__name__)
logger.setLevel(level=logging.INFO)
handler1 = logging.FileHandler('output.log')
handler2 = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(lineno)s - %(levelname)s - %(message)s')
handler1.setFormatter(formatter)
handler2.setFormatter(formatter)
logger.addHandler(handler1)
logger.addHandler(handler2)
logger.info('This is a log info')
logger.debug('Debugging')
logger.warning('Warning exists')
logger.info('Finish')