You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向Pytest发送结构化日志并向控制台输出美观日志?

Pytest + Structlog 实现双日志流:美化控制台输出 + 结构化JSON报告

要同时实现Structlog的美观控制台输出和机器可读的JSON日志报告,核心是让Structlog分流日志事件到两个独立的处理器链,分别处理不同的输出格式和目标,互不干扰。

核心方案:用TeeProcessor分流日志

Structlog的TeeProcessor可以将同一条日志事件发送给多个处理器,我们可以分别配置:

  • 一个处理器链负责控制台输出:用ConsoleRenderer生成带颜色、简化格式的日志
  • 另一个处理器链负责JSON报告:用JSONRenderer生成完整结构化的JSON日志,输出到文件或Pytest插件指定的流

1. Structlog配置代码

import structlog
from structlog.processors import (
    JSONRenderer,
    ConsoleRenderer,
    TimeStamper,
    add_log_level,
    format_exc_info,
    TeeProcessor,
    FileRenderer,
)
import sys

def setup_structlog():
    # 控制台处理器链:美化输出,省略冗余结构化字段,带颜色
    console_chain = [
        add_log_level,
        format_exc_info,
        ConsoleRenderer(
            colors=True,
            omit_event_id=True,
            # 自定义控制台格式,比如去掉时间戳
            format="%(levelname)s: %(message)s"
        )
    ]

    # JSON报告处理器链:保留所有结构化数据,包括时间戳
    json_chain = [
        add_log_level,
        TimeStamper(fmt="iso", utc=True, key="timestamp"),
        format_exc_info,
        JSONRenderer()
    ]

    structlog.configure(
        processors=[
            # 通用预处理:添加日志级别、异常信息
            add_log_level,
            format_exc_info,
            # 分流到两个处理器链
            TeeProcessor(
                # 控制台输出到stdout
                structlog.stdlib.ProcessorFormatter.wrap_for_formatter(
                    processors=console_chain,
                    formatter=structlog.stdlib.ProcessorFormatter(processor=ConsoleRenderer())
                ),
                # JSON输出到文件(可指定为Pytest插件需要的路径)
                FileRenderer(
                    file_path="./test_logs.json",
                    renderer=JSONRenderer()
                )
            )
        ],
        logger_factory=structlog.stdlib.LoggerFactory(),
    )

2. 配合Pytest配置

在conftest.py中初始化Structlog,并将JSON日志路径传递给插件:

import structlog

def pytest_configure(config):
    # 初始化Structlog配置
    setup_structlog()
    # 将JSON日志文件路径告知Pytest(根据插件需求调整)
    config.addinivalue_line("json_log_path", "./test_logs.json")

def pytest_sessionfinish(session, exitstatus):
    # 可选:测试结束后处理JSON日志文件(比如传给插件生成报告)
    pass

3. 关键细节

  • 时间戳分离:控制台日志通过ConsoleRenderer的format参数自定义格式,省略时间戳;JSON日志通过TimeStamper添加标准时间戳,互不影响。
  • 输出隔离:控制台输出到stdout,JSON输出到独立文件,避免Pytest捕获控制台的美化输出,保证JSON报告的机器可读性。
  • 字段过滤:如果需要在控制台隐藏某些结构化字段,可以在控制台处理器链中添加structlog.processors.RemoveProcessor,比如移除key、more_than_strings这类字段,只保留日志消息和级别。

内容的提问来源于stack exchange,提问作者roegra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 14:40:22