一、日志
1.1什么是日志
日志是跟踪软件运行时所发生的事件的一种方法,软件开发者在代码中调用日志函数,表明发生了特定的事件,事件由描述性消息描述,同时还包含事件的重要性,重要性也称为级别或严重性。
1.2何时使用日志
logging模块提供了一些函数,用来做一些简单的日志,他们是debug()、info()、warning()、error()、critical()。要决定什么时候使用logging,见下表,描述了常见的任务及对应的最佳工具。
你想完成的任务 | 完成任务的最佳工具 |
---|---|
在控制台上显示命令行脚本或者程序的常规用法说明 | print() |
报告在程序的正常操作期间发生的事件(例如,用于状态监视或故障调查) | logging.info() (或者 logging.debug() ,非常详细的输出,用于诊断目的) |
对于特定的运行时事件发出警告 |
在库代码中使用 使用 |
对于特定的运行时事件报告错误 | 抛出异常 |
报告错误的抑制而不引发异常(例如,在长时间运行的服务器进程中的错误处理程序) | 根据特定的错误和应用领域,使用合适的logging.error() 、 logging.exception() 或者logging.critical() |
1.3事件严重性(事件的级别)
级别 | 何时使用 |
---|---|
DEBUG |
详细信息,一般只在调试问题时使用。 |
INFO |
证明事情按预期工作。 |
WARNING |
某些没有预料到的事件的提示,或者在将来可能会出现的问题提示。例如:磁盘空间不足。但是软件还是会照常运行。 |
ERROR |
由于更严重的问题,软件已不能执行一些功能了。 |
CRITICAL |
严重错误,表明软件已不能继续运行了。 |
默认等级时warning。意味着只有warning以上的事件等级才会反馈信息,可以通过logging.setLevel()修改默认等级。
二、Logging简介
logging模块定义的类和函数位应用程序和库实现了一个灵活的事件日志系统。由标准库提供的日志记录API的好处是所有的Python模块都可以使用日志。
2.1使用logging记录到控制台
#1.使用logging 将日志打印到控制台 logging.basicConfig(level=logging.DEBUG) #默认level时warning。所以需要修改一下级别 logging.debug('debug') logging.info('info') logging.warning('warning') logging.error('error') logging.critical('critical')
2.2使用logging将日志记录到文件
#2.将日志记录到文件 logging.basicConfig(filename='logging.log',filemode='a',level=logging.DEBUG) #默认level时warning。所以需要修改一下级别 logging.debug('debug') logging.info('info') logging.warning('warning') logging.error('error') logging.critical('critical')
2.3 如果程序由多个模块,组织日志
# myapp.py import logging import mylib def main(): logging.basicConfig(filename='myapp.log', level=logging.INFO) logging.info('Started') mylib.do_something() logging.info('Finished') if __name__ == '__main__': main()
三、改变显示消息格式Formatter
logger对象一般不会直接实例化得到,而是通过模块级别的logging.getLogger()得到。以相同的名字多次调用getLogger()。永远返回相同的logger对象的引用-->单例模式。
3.1 format 指定输出格式和内容
import logging logging.basicConfig(format='%(levelname)s:%(message)s',level=logging.DEBUG) logging.debug('debug msg') logging.info('info msg') logging.warning('warning msg') logging.error('error msg') logging.critical('critical msg')
常用的format格式:
%(levelno)s: 打印日志级别的数值 %(levelname)s: 打印日志级别名称 %(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0] %(filename)s: 打印当前执行程序名 %(funcName)s: 打印日志的当前函数 %(lineno)d: 打印日志的当前行号 %(asctime)s: 打印日志的时间 %(thread)d: 打印线程ID %(threadName)s: 打印线程名称 %(process)d: 打印进程ID %(message)s: 打印日志信息
import os #format logging.basicConfig(level=logging.DEBUG, format='%(asctime)s:%(filename)s [line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename= os.path.join('format.txt'), filemode='w', ) logging.debug('debug msg') logging.error('error msg')
四、Logger
Logger对象有三个作用,首先,它暴露给应用几个方法以便应用可以在运行时写log;其次,Logger对象按照log信息的严重程度或者根据filter对象来决定如何处理log信息(默认的过滤功能);最后,logger还负责把log信息传送给相关的loghandlers。
4.1将日志记录控制台及文件
import logging logger = logging.getLogger() # 创建一个handler,用于写入日志文件 fh = logging.FileHandler('test.log',encoding='utf-8') # 再创建一个handler,用于输出到控制台 ch = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setLevel(logging.DEBUG) fh.setFormatter(formatter) ch.setFormatter(formatter) logger.addHandler(fh) #logger对象可以添加多个fh和ch对象 logger.addHandler(ch) logger.debug('logger debug message') logger.info('logger info message') logger.warning('logger warning message') logger.error('logger error message') logger.critical('logger critical message')
logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别,当然,也可以通过
fh.setLevel(logging.Debug)单对文件流设置某个级别。