前提
日志相信我们每天都会接触到,调试代码需要看console输出的日志、测试web程序需要看后台tomcat日志、测试手机应用需要看appium日志,所以日志还是非常重要的,于是最近了解了一下python logging模块,本文主要是Logging模块的一些用法简介,主要参考文章为Python 官方文档。
简单的示例
import logging
logging.warning('Watch out!') # will print a message to the console
logging.info('I told you so') # will not print anything
这是官方文档的一个例子,后面已经给出提示,日志等级为warning时才会在控制台打印日志,而info并没有打印日志,原因是为什么呢?官方给出的解释是:
‘The INFO message doesn’t appear because the default level is WARNING.’
即默认的日志等级是warning,只有日志等级高于warning时才会打印日志,具体日志等级如下所示:
Level When it’s used DEBUG Detailed information, typically of interest only when diagnosing problems. INFO Confirmation that things are working as expected. WARNING An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected. ERROR Due to a more serious problem, the software has not been able to perform some function. CRITICAL A serious error, indicating that the program itself may be unable to continue running.
英文好的可以试着翻译一下,大概是:
debug: 查看详细信息,调试问题时会感兴趣
info: 确认程序按预期的运行
warning: 表明一些意外发生,或者预示一些问题即将发生(比如:磁盘空间不够)。软件仍然正常工作
error: 由于一个更严重的问题,软件已经无法执行一些功能
critical: 严重的错误,表明程序已经无法继续运行
输出日志到文件
上面完成了一个日志的简单打印到控制台,那么如果我们想把日志打印出来记录到文件中怎么办呢?
继续看一个官方给的例子:
import logging
logging.basicConfig(filename='example.log',level=logging.DEBUG)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
运行这个文件,可以看到控制台没有输出任何日志信息,而在文件同级目录下,生成了一个example.log,打开log文件,可以看到文件内容为:
DEBUG:root:This message should go to the log file
INFO:root:So should this
WARNING:root:And this, too
每运行一次,文件不会覆盖之前的log,会在后面自动添加。
那么问题来了,如果想每次都生成新的日志,应该怎么办呢?
只需加上一个参数即可:
logging.basicConfig(filename='example.log',filemode='w',level=logging.DEBUG)
设置日志显示格式
上面完成了输出日志到控制台,输出日志到文件,而日志格式呢都是固定的,如果我们想自定义日志格式呢,官方也提供了解决方案。
一个官方给的例子:
import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too')
对应的在控制台打印效果如图所示:
对比上一张图:可以看到root不见了。ps:这边的logger就是默认的实例名称
如果想要加上时间,怎么办呢?也很简单,只要稍微修改一下format格式:
import logging
logging.basicConfig(format='%(asctime)s-%(levelname)s %(message)s', level=logging.DEBUG)
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too')
打印出来:
logging组件介绍
logging库一共有四个重要的组件:loggers, handlers, filters, and formatters.
官方文档是这样介绍的:
The logging library takes a modular approach and offers several categories of components: loggers, handlers, filters, and formatters.
- Loggers expose the interface that application code directly uses.
- Handlers send the log records (created by loggers) to the appropriate destination.
- Filters provide a finer grained facility for determining which log records to output.
- Formatters specify the layout of log records in the final output.
大致翻译了一下:
- Loggers 暴露了应用程序代码能直接使用的接口
- Handlers 将(loggers产生的)日志记录发送到合适的目的地
- Filters 提供了更好的粒度控制用来决定输出哪些日志记录
- Formatters 明确了最终输出中日志记录的格式
Loggers
logging是通过调用logger 的方法来执行的,所以如果没有特意创建,会默认一个 root 的logger(上面有提到),创建一个logger:
logger = logging.getLogger(__name__)
logger实例创建后就可以进行日志等级设置、增加filter、增加handler等操作:
- Logger.setLevel(logging.DEBUG) 设置日志等级为debug,即等级超过debug才会打印日志
- Logger.addHandler 和 Logger.removeHandler 为Logger实例增加、删除一个处理器
- Logger.addFilter 和 Logger.removeFilter 为Logger实例增加、删除一个过滤器
Handlers
官方文档示例介绍的handlers一共有两种:StreamHandler 和 FileHandler
The standard library includes quite a few handler types (see [Useful Handlers]; the tutorials use mainly StreamHandler and FileHandler in its examples.
当然还要其他 多种handlers ,感兴趣的童鞋可以去了解一下
其中StreamHandler ,主要用来向控制台输出日志
sends logging output to streams such as sys.stdout, sys.stderr or any file-like object
FileHandler,主要用来磁盘生成一个文件
sends logging output to a disk file
Formatters
Formatters主要用来设置日志的结构和消息内容,设置格式如下:
formatter = logging.Formatter('[%(asctime)s] - [%(levelname)s] - %(message)s')
一个完整的例子
官网提供了一下比较完整的例子,如下所示:
import logging
# create logger
logger = logging.getLogger('simple_example')
logger.setLevel(logging.DEBUG)
# create console handler and set level to debug
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# create formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# add formatter to ch
ch.setFormatter(formatter)
# add ch to logger
logger.addHandler(ch)
# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
最终在控制台上输出结果为:
2005-03-19 15:10:26,618 - simple_example - DEBUG - debug message
2005-03-19 15:10:26,620 - simple_example - INFO - info message
2005-03-19 15:10:26,695 - simple_example - WARNING - warn message
2005-03-19 15:10:26,697 - simple_example - ERROR - error message
2005-03-19 15:10:26,773 - simple_example - CRITICAL - critical message
官方文档还介绍了配置相关,这边不在介绍,感兴趣的童鞋可以去看一下,再贴一下 官方文档
这一篇主要对官方文档的一个学习总结,下一篇将直接上干货介绍logger在接口测试、UI自动化测试中的使用