?13.1 日志的定义
13.1.1 日志的定义
听到日志这个东西可能有的人莫名其妙,第一次接触就会觉得我们为什么要收集日志,即使要收集日志那么我们需要收集哪些日志,日志的作用是什么等等。
其实日志无论是在测试、开发中都非常重要,如果你在跑自动化时程序报错了,但是你没有日志你怎么去定位时程序错误还是你app的错误?或者还是其它环境因素?
在java中有log4j这日志模块,在python里面我们使用的是logging这个模块,这个模块不需要你去怎么下载安装等等,python自带的有,你只需要拿来用就好。
13.2 日志收集实战
13.2.1 日志三要素
假如在测试过程中我们知道了日志的重要性,这样就可以了吗?答案肯定是否定的,我们在收集日志的过程中我们需要明白几个事情:
一、日志的级别
在公司员工有级别之分,这个日志也是一样,他也有级别之分。为什么这么说呢?你总不可能把测试过程中所有的日志都收集下来吧,我管他3、7、21的都收集起来。这个肯定不行。
首先我们日志需要按照info、debug、error等级别来进行区分的。当然这个级别可以自己去设置。在一般的情况下我们普通的输出我们直接用info类型,调试的时候用debug类型,如果预计有错误时那么我们就需要用error类型的日志。
二、日志的格式
为什么有日志格式呢?因为在我们调试程序或者看日志的时候我们为了更好的去阅读,或者增加日志的可读性,以及我们定位问题方便、快速我们需要对日志的格式进行一些优化,好比我在这个日志输出的时候输出时间,以及我看到这个日志的时候我知道是哪一个类出错了呢?
三、日志位置
大家在写程序的时候看日志可能大多数人还是通过在控制台进行查看,如果说你不小心将控制台关闭了呢?以及你集成框架后你怎么从控制台看呢?这些都不是现实的,所以在日志中我们需要有一个位置去保存我们的日志,所以在搭建框架时我们都会有一个默认的日志目录。
13.2.2 日志收集实战
一、日志文件配置
首先我们收集日志我们要对logging模块进行一个配置,其实这个和log4j是一样的,大家可以在官网或者其它地方查询一下这个配置的基础文件,我这里也给大家展示一个:log.conf
[loggers] keys=root,infoLogger,errorlogger [logger_root] level=DEBUG handlers=infohandler,errorhandler [logger_infoLogger] handlers=infohandler qualname=infoLogger propagate=0 [logger_errorlogger] handlers=errorhandler qualname=errorlogger propagate=0 ############################################### [handlers] keys=infohandler,errorhandler [handler_infohandler] class=StreamHandler level=INFO formatter=form02 args=(sys.stdout,) [handler_errorhandler] class=FileHandler level=ERROR formatter=form01 args=(‘../logs/mylog.log‘, ‘a‘) ############################################### [formatters] keys=form01,form02 [formatter_form01] format=%(asctime)s %(filename)s %(levelname)s %(message)s datefmt=%Y-%m-%d %H:%M:%S [formatter_form02] format=%(asctime)s %(filename)s %(levelname)s %(message)s datefmt=%Y-%m-%d %H:%M:%S
这个配置文件每个人配置的都不一样,但是大体功能都差不多,这个只需要根据自己的爱好去定义就行,下面我把配置定义的方法贴出来大家看一下:
1. 初始化 logger = logging.getLogger("endlesscode"),getLogger()方法后面最好加上所要日志记录的模块名字,后面的日志格式中的%(name)s 对应的是这里的模块名字 2. 设置级别 logger.setLevel(logging.DEBUG),Logging中有NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL这几种级别,日志会记录设置级别以上的日志 3. Handler,常用的是StreamHandler和FileHandler,windows下你可以简单理解为一个是console和文件日志,一个打印在CMD窗口上,一个记录在一个文件上 4. formatter,定义了最终log信息的顺序,结构和内容,我喜欢用这样的格式 ‘[%(asctime)s] [%(levelname)s] %(message)s‘, ‘%Y-%m-%d %H:%M:%S‘, %(name)s Logger的名字 %(levelname)s 文本形式的日志级别 %(message)s 用户输出的消息 %(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒 %(levelno)s 数字形式的日志级别 %(pathname)s 调用日志输出函数的模块的完整路径名,可能没有 %(filename)s 调用日志输出函数的模块的文件名 %(module)s 调用日志输出函数的模块名 %(funcName)s 调用日志输出函数的函数名 %(lineno)d 调用日志输出函数的语句所在的代码行 %(created)f 当前时间,用UNIX标准的表示时间的浮 点数表示 %(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数 %(thread)d 线程ID。可能没有 %(threadName)s 线程名。可能没有 %(process)d 进程ID。可能没有
其实大家只需要按照我上面的配置就好,这里需要提点的一下是,在配置文件里面你需要配置一下日志的输出文件,如果你没有这个文件,系统会报错,“args=(‘../logs/mylog.log‘, ‘a‘)” 这一句大家根据自己的情况进行更改。
当我们把所有的配置文件配置好了之后我们只需要在我们需要用到的地方去引入就好,看下面的代码:
#coding=utf-8 import logging import logging.config #这个是配置文件的路径 CONF_LOG = "../Config/log.conf" logging.config.fileConfig(CONF_LOG) logger = logging.getLogger() #下面就是使用日志打印日志信息 logger.info("info类型的日志") logger.error("error 的日志")
通过上面的配置以及输出最后的结果如下图:
通过这个图片我们能够看到我们有输出的日志时间、以及类的名字、以及等级。是不是很方便?动手吧。
备注:我这里把错误的日志在logs文件下的mylog.log文件也进行了保存,因为我们在看线上错误日志时大多数只看错误的日志,所以只将错误的日志进行了保存,如果其它类型的需要保存,那么你就按照类似格式在info等配置下也把目录配置进去即可。