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

如何在structlog中同时使用两个不同的渲染器?

实现structlog多渲染器配置

要分别给控制台和日志文件配置不同的渲染器,核心是借助structlog.stdlib.ProcessorFormatter,让不同的logging handler使用各自的渲染逻辑。以下是修改后的完整配置:

import logging
import logging.config
import structlog
from structlog.stdlib import BoundLogger, ProcessorFormatter

# 1. 配置logging handlers和对应的ProcessorFormatter
logging.config.dictConfig(
    {
        "version": 1,
        "disable_existing_loggers": False,
        "formatters": {
            # 控制台用带颜色的ConsoleRenderer
            "console_formatter": {
                "()": ProcessorFormatter,
                "processor": structlog.dev.ConsoleRenderer(colors=True),
                # 通用处理器链:和structlog配置里的通用部分一致
                "foreign_pre_chain": [
                    structlog.contextvars.merge_contextvars,
                    structlog.processors.add_log_level,
                    structlog.processors.StackInfoRenderer(),
                    structlog.processors.TimeStamper(fmt="iso"),
                ],
            },
            # 文件用无颜色的ConsoleRenderer(或换成JSONRenderer更适合文件存储)
            "file_formatter": {
                "()": ProcessorFormatter,
                "processor": structlog.dev.ConsoleRenderer(colors=False),
                "foreign_pre_chain": [
                    structlog.contextvars.merge_contextvars,
                    structlog.processors.add_log_level,
                    structlog.processors.StackInfoRenderer(),
                    structlog.processors.TimeStamper(fmt="iso"),
                ],
            },
        },
        "handlers": {
            "default": {
                "level": "DEBUG",
                "class": "logging.StreamHandler",
                "formatter": "console_formatter",  # 绑定控制台格式化器
            },
            "file": {
                "level": "INFO",
                "class": "logging.handlers.WatchedFileHandler",
                "filename": "/var/tmp/test.log",
                "formatter": "file_formatter",  # 绑定文件格式化器
            },
        },
        "loggers": {
            "": {
                "handlers": ["default", "file"],
                "level": "DEBUG",
                "propagate": True,
            },
        },
    }
)

# 2. 配置structlog,只保留通用处理器,最终交给logging的Formatter处理
structlog.stdlib.recreate_defaults(log_level=None)
structlog.configure(
    processors=[
        structlog.contextvars.merge_contextvars,
        structlog.processors.add_log_level,
        structlog.processors.StackInfoRenderer(),
        structlog.processors.TimeStamper(fmt="iso"),
        # 将处理后的事件交给logging的Formatter完成最终渲染
        structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
    ],
    logger_factory=structlog.stdlib.LoggerFactory(),
    wrapper_class=BoundLogger,
    cache_logger_on_first_use=True,
)

关键说明:

  • ProcessorFormatter:作为structlog和标准logging之间的桥梁,允许我们为每个logging handler单独指定渲染器(processor参数),同时通过foreign_pre_chain定义通用的日志处理步骤,避免重复代码。
  • 控制台渲染器:使用structlog.dev.ConsoleRenderer(colors=True),输出带颜色的美观日志,仅处理DEBUG及以上级别。
  • 文件渲染器:使用structlog.dev.ConsoleRenderer(colors=False),输出无颜色的纯文本日志,仅处理INFO及以上级别;如果需要更适合日志分析的格式,也可以替换为structlog.processors.JSONRenderer()。
  • structlog核心配置:移除了原有的顶层ConsoleRenderer,改用wrap_for_formatter将事件传递给logging的Formatter完成最终渲染,确保不同handler使用各自的渲染逻辑。

测试示例:

log = structlog.get_logger()
log.debug("这是一条DEBUG日志,只会出现在控制台")
log.info("这是一条INFO日志,会同时出现在控制台和日志文件")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 17:03:18