pytest 中重写日志之解决logging日志模块中字段组合的固定长度格式、根据不同日志级别打印显示不同颜色、logging日志不能实时显示问题

问题现象如下:

在pytest.ini文件中配置日志打印格式为:

​​​​​[pytest]
log_cli_format=%(asctime)s %(levelname)-5s [%(threadName)-10s] %(name)s.%(module)s.%(funcName)s : %(message)s

 控制台打印信息如下:

2018-03-14 11:35:27,257 INFO  [Thread-2  ] my_app.util.get_login_info : Log line 1
2018-03-14 11:35:27,257 INFO  [Thread-2  ] my_app.cache.call : Log line 2
2018-03-14 11:35:27,257 INFO  [Thread-2  ] my_app.web.parse_response : Log line 3

上面输出的格式不符合个人的预期,因为文件名函数名组合之后长度不固定参差不齐,不便于查看message内容,个人预期要打印的格式为:

2018-03-14 11:35:27,257 INFO  [Thread-2  ] my_app.util.get_login_info : Log line 1
2018-03-14 11:35:27,257 INFO  [Thread-2  ] my_app.cache.call          : Log line 2
2018-03-14 11:35:27,257 INFO  [Thread-2  ] my_app.web.parse_response  : Log line 3

查找资料发现pytest中无法将日志格式的几个字段组合并设置固定长度,个人目前找到的办法是将pytest日志关闭,使用python logging库日志重写函数实现,具体实现方法如下:

1、在pyte st.ini文件中,将  log_cli=false 或者在pytest.ini文件中删除所有log相关的配置,因为pytest默认是将log日志关闭

​​​​​[pytest]
log_cli=false

2、python项目中新建一个.py文件,并复制以下代码

import logging
import sys

from colorama import Fore, Style


class ShortLevelNameFormatter(logging.Formatter):
    def __init__(self, *args, **kargs):
        super().__init__(*args, **kargs)

    def format(self, record: logging.LogRecord) -> str:
        record.expandedFuncName = '%s.%s:%s' % (record.module, record.funcName, record.lineno)
        return super().format(record)


class ColorHandler(logging.StreamHandler):
    def __init__(self, stream=None, level=logging.NOTSET):
        super().__init__(stream=stream)
        self.level = level

    def emit(self, record):
        if record.levelno >= self.level:
            if record.levelno >= logging.ERROR:
                color = Fore.LIGHTRED_EX  # 红色
            elif record.levelno >= logging.WARNING:
                color = Fore.YELLOW  # 黄色
            elif record.levelno >= logging.INFO:
                color = Style.RESET_ALL  # 绿色
            else:
                color = Style.RESET_ALL  # 默认颜色
            message = self.format(record)
            message = color + message + Style.RESET_ALL  # 恢复默认颜色
            stream = self.stream
            stream.write(message)
            stream.write(self.terminator)


def config_logging(file_name: str = None, console_level: int = logging.INFO, file_level: int = logging.DEBUG):
    if file_name is not None: 
        file_handler = logging.FileHandler(file_name, mode='a', encoding="utf8")
        file_handler.setFormatter(ShortLevelNameFormatter(
            '%(asctime)s [%(levelname)-4s] %(expandedFuncName)-32s ->>> %(message)s'
        ))
        file_handler.setLevel(file_level)

    console_handler = ColorHandler(sys.stdout)
    console_handler.setFormatter(ShortLevelNameFormatter(
        '%(asctime)s [%(levelname)-4s] %(expandedFuncName)-35s ->>> %(message)s'
    ))
    console_handler.setLevel(console_level)

    logging.basicConfig(
        level=min(console_level, file_level),
        handlers=[console_handler], #如果需要输出日志到文件,则加上 file_handler 
    )

ShortLevelNameFormatter类是将几个字段组合成一个字段,并在  fmt 里面控制固定长度,ColorHandler类是将不同级别的日志设置成不同的颜色显示

3、然后可以在pytest的conftest.py文件中使用 pytest_configure 钩子函数执行刚才新建py文件中的 config_logging 函数

def pytest_configure(config):

    config_logging()

以上操作完成后,在pycharm中执行测试用例时,发现控制台日志不能实时打印,可能只是打印部分,等测试用例执行完成后才会显示所有日志,解决办法是,在pytest.ini文件中,加入

addopts=--capture=tee-sys 参数
[pytest]
addopts=--capture=tee-sys

参考:pytest捕获标准输出标准错误输出的模式主要有以下几种

  • pytest :和pytest --capture=fd 模式是一样的,默认的就是pytest --capture=fd 模式
  • pytest -s :打开实时输出,关闭Capture Log输出,
  • pytest --capture=sys :打开实时输出,Captrue Log只捕获sys.out,sys.err
  • pytest --capture=fd :关闭实时输出,Captrue Log捕获所有的标准输出
  • pytest --capture=tee-sys :pytest -s 和 pytest --capture=sys的结合,即打开实时输出,同时Captrue Log只捕获sys.out,sys.err

参考引用:

Python-logging模块定制格式描述符实现定长日志等级 - SnowPhoenix - 博客园 (cnblogs.com)

【Python】Logging模块简介 & 开启不同颜色日志输出 - 码农教程

Pytest----Pytest自动化测试框架中标准输出和标准错误输出的捕获方法 - 代码天地

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值