从 0 到 1 搭建 Python 语言 Web UI自动化测试学习系列 12--日志模块设计
测试学习记录,仅供参考!
日志
把每一个操作都记录下来,叫做日志,日志是跟踪运行软件所发生事件的方法;
参考中文日志指南日志基础教程:https://docs.python.org/zh-cn/3/howto/logging.html
自行学习移步官方网站:https://docs.python.org/3/howto/logging-cookbook.html
https://docs.python.org/3/library/logging.html#logging.LogRecord
在 python 中一般使用 logging 模块(python内置模块)生成日志,可以生成日志,包括可以设置日志等级、日志路径、日志文件回滚等;
日志的作用:信息查询、服务诊断、数据分析等;
logger 日志器 提供了应用程序的接口
Handler 处理器 通过logger在不同位置输出日志
Formator 格式器 决定日志以什么的样式显示
Filter 过滤器 过滤哪些需要记录输出,哪些需要丢弃
封装日志处理
第一步,先封装日志模块
日志模块是一个独立的,先完成后完成都行,看个人选择;若先完成日志模块,后面写其他部分代码的时候可以直接引入调用,会比较方便;若最后再补充日志,需要联系上下文按需补全;
做日志封装之前,需要先设置路径,拿到项目的根目录;
项目根目录路径
1、在 config 软件包 setting.py 文件中;
os.path.dirname():获取当前脚本所在的目录;
两个下划线 “__file__”:表示当前脚本文件的路径
os.path.abspath():将相对路径转换为绝对路径;
os.path.dirname(os.path.abspath(__file__)):获取当前脚本文件的绝对路径值;
例如:
# 导包
import osDIR_PATH = os.path.dirname(os.path.abspath(__file__))
print(DIR_PATH)
2、 打印查看:能够获取到当前文件 setting.py 的绝对路径
E:\Users\webuiauto\config
3、获取到项目的根目录 webuiauto ,所以再套一层 os.path.dirname() 即可;
# 导包
import osDIR_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
print(DIR_PATH)
4、再打印查看:能够获取到项目的根目录;
E:\Users\webuiauto
5、目的
拿到项目的根目录,到后面在其他文件里面(有配置文件、读取数据文件等等)可以直接调用 根目录 加上 所需文件就行了,读取文件时不用在每个地方都去写一遍这个“os.path.dirname(os.path.dirname(os.path.abspath(__file__)))”,直接引入即可(引进setting.py 文件,然后调用 DIR_PATH 变量就能拿到项目的根目录)
6、拿到项目根目录之后,使用 sys.path.append(DIR_PATH) 将根目录加入到模块搜索路径,在别的地方使用时,能够更好的找到项目根路径;
# 导包
import os
import sysDIR_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(DIR_PATH)
文件路径
7、log 日志指定存放路径;
# 导包
import os
import sysDIR_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(DIR_PATH)# 文件路径
FILE_PATH = {'log': os.path.join(DIR_PATH, 'log')
}print(FILE_PATH['log'])
E:\Users\webuiauto\log
封装 log 日志
8、在 util_tools 软件包下新建名称为 logs_util 的 Python 软件包,在 logs_util 下新建名称为 recordlog.py 的 Python 文件;
设置文件编码格式:# -*- coding:utf-8 -*-
日志格式:路径 + 文件名
路径:log_path
显示样式:r"\test.{}.log" 注意添加 r 防止识别错误,添加 r 识别成路径的意思;
格式化处理:format(time.strftime('%Y%m%d')) 里面时间格式自行选择;
# -*- coding:utf-8 -*-
import logging
import time
from config import setting
import os# 设置log日志存放路径
log_path = setting.FILE_PATH['log']
# 如果文件路径不存在
if not os.path.exists(log_path):# 创建一个文件路径os.mkdir(log_path)# 设置日志文件名称格式
logfile_name = log_path + r"\test.{}.log".format(time.strftime('%Y%m%d'))
print(logfile_name)
拿到日志的 名称和格式;
E:\Users\webuiauto\log\test.20210521.log
9、日志控制台、日志文件处理
# -*- coding:utf-8 -*-
import logging
from logging.handlers import RotatingFileHandler
import time
from sre_constants import error
from config import setting
import oslog_path = setting.FILE_PATH['log']if not os.path.exists(log_path):os.mkdir(log_path)logfile_name = log_path + r"\test.{}.log".format(time.strftime('%Y%m%d'))class RecordLog:def __init__(self):passdef output_logging(self):logger = logging.getLogger(__name__)if not logger.handlers:logger.setLevel(logging.DEBUG)log_format = logging.Formatter('%(levelname)s - %(asctime)s - %(filename)s:%(lineno)d -[%(module)s:%(funcName)s] - %(message)s')sh = logging.StreamHandler()sh.setLevel(logging.DEBUG)sh.setFormatter(log_format)logger.addHandler(sh)fh = RotatingFileHandler(filename=logfile_name, mode='a', maxBytes=5242880, backupCount=7, encoding='utf-8')fh.setLevel(logging.DEBUG)fh.setFormatter(log_format)logger.addHandler(fh)return logger# 调试一下能不能打印成功
rec = RecordLog()
logs = rec.output_logging()
logs.info('这是info日志信息')
logs.error('这是error日志信息')
调试运行后可以发现已经产生日志文件了;
日志信息字体颜色
10、设置控制台输出日志信息对象的文字颜色;
安装 colorlog 模块;
pip install colorlog
11、优化 recordlog.py 文件;
# -*- coding:utf-8 -*-
import logging
from logging.handlers import RotatingFileHandler
import time
from sre_constants import error
import colorlog
from config import setting
import oslog_path = setting.FILE_PATH['log']
if not os.path.exists(log_path):os.mkdir(log_path)logfile_name = log_path + r"\test.{}.log".format(time.strftime('%Y%m%d'))class RecordLog:def __init__(self):pass@classmethoddef log_color(cls):log_color_config = {'DEBUG': 'cyan','INFO': 'green','WARNING': 'yellow','ERROR': 'red','CRITICAL': 'red'}formatter = colorlog.ColoredFormatter('%(log_color)s %(levelname)s - %(asctime)s - %(filename)s:%(lineno)d -[%(module)s:%(funcName)s] - %(message)s',log_colors=log_color_config)return formatterdef output_logging(self):logger = logging.getLogger(__name__)stream_format = self.log_color()if not logger.handlers:logger.setLevel(logging.DEBUG)log_format = logging.Formatter('%(levelname)s - %(asctime)s - %(filename)s:%(lineno)d -[%(module)s:%(funcName)s] - %(message)s')sh = logging.StreamHandler()sh.setLevel(logging.DEBUG)sh.setFormatter(stream_format)logger.addHandler(sh)fh = RotatingFileHandler(filename=logfile_name, mode='a', maxBytes=5242880, backupCount=7, encoding='utf-8')fh.setLevel(logging.DEBUG)fh.setFormatter(log_format)logger.addHandler(fh)return logger# 调试一下能不能打印成功
rec = RecordLog()
logs = rec.output_logging()
logs.info('这是info日志信息')
logs.error('这是error日志信息')
logs.debug('这是debug日志信息')
logs.warning('这是warning日志信息')
logs.critical('这是critical日志信息')
12、其他文件需要用日志时直接引入即可;
# -*- coding:utf-8 -*-
import logging
from logging.handlers import RotatingFileHandler
import time
import colorlog
from config import setting
import oslog_path = setting.FILE_PATH['log']
if not os.path.exists(log_path):os.mkdir(log_path)logfile_name = log_path + r"\test.{}.log".format(time.strftime('%Y%m%d'))class RecordLog:def __init__(self):pass@classmethoddef log_color(cls):log_color_config = {'DEBUG': 'cyan','INFO': 'green','WARNING': 'yellow','ERROR': 'red','CRITICAL': 'red'}formatter = colorlog.ColoredFormatter('%(log_color)s %(levelname)s - %(asctime)s - %(filename)s:%(lineno)d -[%(module)s:%(funcName)s] - %(message)s',log_colors=log_color_config)return formatterdef output_logging(self):logger = logging.getLogger(__name__)stream_format = self.log_color()if not logger.handlers:logger.setLevel(logging.DEBUG)log_format = logging.Formatter('%(levelname)s - %(asctime)s - %(filename)s:%(lineno)d -[%(module)s:%(funcName)s] - %(message)s')sh = logging.StreamHandler()sh.setLevel(logging.DEBUG)sh.setFormatter(stream_format)logger.addHandler(sh)fh = RotatingFileHandler(filename=logfile_name, mode='a', maxBytes=5242880, backupCount=7, encoding='utf-8')fh.setLevel(logging.DEBUG)fh.setFormatter(log_format)logger.addHandler(fh)return logger# 调试一下能不能打印成功
rec = RecordLog()
logs = rec.output_logging()
13、后续在其他模块文件中使用,先导包;在什么地方需要添加日志,就在什么地方引用;
from util_tools.logs_util.recordlog import logslogs.info('这是测试日志信息')
自定义日志
一般添加日志系统,是使用python自带的日志模块;可在项目根目录下新建一个 demo 文件(自定义文件名称);
# 导包
import logging
import os# 定义日志logger --logging.getLogger('名称'),创建一个'testlogs'-名称可自定义
logger = logging.getLogger('testlogs')
# 定义一个变量--创建格式formatter--格式(生成时间-日志级别-消息内容)
formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
# 控制台输出-文件流处理器 创建一个打印在命令行输出的 logging.StreamHandler--定义为 sh
sh = logging.StreamHandler()
# 设置文件流格式为formatter
sh.setFormatter(formatter)
# 设置日志级别--DEBUG级别
sh.setLevel(logging.DEBUG)
# 添加控制台输出
logger.addHandler(sh)
# 定义日志存放文件路径--项目根目录下有一个logs文件目录,每次运行时保存在logs文件目录 --os.path.join获取路径
logs = os.path.join(os.path.dirname(__file__), '../logs')
# 判断logs路径是否存在--如果目录不存在
if not os.path.exists(logs):# os.mkdir创建一下logs目录os.mkdir(logs)
# 创建好之后再定义一下--在logs文件目录下新建testlogs.log日志文件
logfile = os.path.join(logs, 'testlogs.log')
# 定义变量--创建文件处理器
fh = logging.FileHandler(logfile)
# 设置格式formatter--还是使用相同的格式
fh.setFormatter(formatter)
# 设置日志级别--DEBUG级别
fh.setLevel(logging.DEBUG)
# 设置好之后添加进来--fh文件处理器
logger.addHandler(fh)# 测试一下
if __name__ == '__main__':logger.info('Hello World!这是一个测试日志文件。')
执行成功后,会发现在项目根目录下新增了 logs 文件夹目录,在logs文件目录下新增了一个空文件,不过里面什么内容都没有,并没有记录日志;
# 导包
import logging
import os# 定义日志logger --logging.getLogger('名称'),创建一个'testlogs'-名称可自定义
logger = logging.getLogger('testlogs')
# 设置日志级别--DEBUG级别
logger.setLevel(logging.DEBUG)
# 定义一个变量--创建格式formatter--格式(生成时间-日志级别-消息内容)
formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")
# 控制台输出-文件流处理器 创建一个打印在命令行输出的 logging.StreamHandler--定义为 sh
sh = logging.StreamHandler()
# 设置文件流格式为formatter
sh.setFormatter(formatter)
# 设置日志级别--DEBUG级别
sh.setLevel(logging.DEBUG)
# 添加控制台输出
logger.addHandler(sh)
# 定义日志存放文件路径--项目根目录下有一个logs文件目录,每次运行时保存在logs文件目录 --os.path.join获取路径
logs = os.path.join(os.path.dirname(__file__), '../logs')
# 判断logs路径是否存在--如果目录不存在
if not os.path.exists(logs):# os.mkdir创建一下logs目录os.mkdir(logs)
# 创建好之后再定义一下--在logs文件目录下新建testlogs.log日志文件
logfile = os.path.join(logs, 'testlogs.log')
# 定义变量--创建文件处理器
fh = logging.FileHandler(logfile)
# 设置格式formatter--还是使用相同的格式
fh.setFormatter(formatter)
# 设置日志级别--DEBUG级别
fh.setLevel(logging.DEBUG)
# 设置好之后添加进来--fh文件处理器
logger.addHandler(fh)# 测试一下
if __name__ == '__main__':logger.info('Hello World!这是一个测试日志文件。')
再次运行日志文件中也有了内容,若打开查看显示乱码,自行设置编码格式;
(以‘GBK’重新加载可显示正常中文;或者优化编码格式UTF-8)
2021-05-21 13:14:21,520 INFO Hello World!这是一个测试日志文件。进程已结束,退出代码为 0
仅供参考,其他自行了解;
未完待续。。。