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

如何在Django项目中使用structlog记录序列化的回溯信息

解决structlog无法序列化回溯信息的问题

你需要调整structlog的处理器配置,确保traceback对象被转换为可序列化的字符串,同时避免重复的JSON格式化逻辑。以下是修改后的配置和说明:

修改后的logging.py配置

import logging.config

import structlog

from server.settings.components import BASE_DIR

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "plain": {
            "()": structlog.stdlib.ProcessorFormatter,
            "processor": structlog.dev.ConsoleRenderer(),
        },
        "json": {
            "()": structlog.stdlib.ProcessorFormatter,
            "processor": structlog.processors.JSONRenderer(),
        },
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "plain",
        },
        "file": {
            "class": "logging.handlers.RotatingFileHandler",
            "filename": BASE_DIR.joinpath("logs/structlog.log"),
            "formatter": "json",
        },
    },
    "root": {
        "level": "INFO",
        "handlers": ["console", "file"],
    },
    "loggers": {
        "server": {
            "handlers": ["console", "file"],
            "level": "INFO",
            "propagate": False,
        },
    },
}

structlog.configure(
    processors=[
        structlog.stdlib.filter_by_level,
        structlog.stdlib.add_logger_name,
        structlog.stdlib.add_log_level,
        structlog.tracebacks.extract,
        structlog.stdlib.PositionalArgumentsFormatter(),
        structlog.processors.TimeStamper(fmt="iso"),
        structlog.processors.StackInfoRenderer(),
        # 格式化traceback为可序列化的字符串
        structlog.tracebacks.format_exc_info,
        # 最后交给logging的Formatter处理,移除多余的JSONRenderer
        structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
    ],
    context_class=dict,
    logger_factory=structlog.stdlib.LoggerFactory(),
    wrapper_class=structlog.stdlib.BoundLogger,
    cache_logger_on_first_use=True,
)

logging.config.dictConfig(LOGGING)

关键修改点说明

  1. 移除重复的JSONRenderer
    你之前在structlog.configure中配置了structlog.processors.JSONRenderer(),但已经通过LOGGING的json formatter指定了相同的处理器,重复配置会导致traceback对象未被正确处理就被序列化。移除后,由ProcessorFormatter统一将处理后的事件传递给指定的格式化器。

  2. 使用专门的traceback格式化处理器
    替换structlog.processors.format_exc_info为structlog.tracebacks.format_exc_info,这个处理器会将exc_info中的traceback对象转换为包含完整调用栈的字符串,确保JSON序列化时不会出现无法处理的对象引用。

  3. 保持处理器顺序
    traceback格式化逻辑必须在structlog.stdlib.ProcessorFormatter.wrap_for_formatter之前执行,这样当事件传递给logging的格式化器时,所有字段都已经是可序列化的类型。

修改后,日志文件中的回溯信息会变成完整的字符串形式,示例如下:

{"event": "Internal Server Error: /healthcheck/error", "exc_info": "Traceback (most recent call last):\n  File \"/path/to/django/core/handlers/exception.py\", line 55, in inner\n    response = get_response(request)\n  ... 完整的调用栈信息 ...", "level": "error", "logger": "server", "timestamp": "2024-05-20T12:34:56.789012"}

同时控制台的彩色输出依然会正常工作,ConsoleRenderer会自动解析traceback字符串并渲染为友好的格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 10:23:11