ruslaniv
ruslaniv

Reputation: 604

How to log traceback information using structlog

I'm trying to set up an ELK based observability system in our project.

So I started with revising a logging system in our Django based project. I have decided to start with structlog in order to obtain structured log files that are shipped to Logstash.

I have this in my logging.py as a project wide logging configuration:

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(),
        structlog.processors.format_exc_info,
        structlog.processors.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)

Everything seems to be logging fine (and I really like the console rich output) but I can't get it to serialize the traceback. All I see in my log file is:

{"event": "Internal Server Error: /healthcheck/error", "exc_info": ["<class 'ValueError'>", "ValueError('This is a ValueError')", "<traceback object at 0x7f13f61bf340>"]}

How can I have Structlog to produce a full serialized traceback object in my log file?

Upvotes: 0

Views: 996

Answers (1)

Dmitry Teamush
Dmitry Teamush

Reputation: 11

Try adding structlog.processors.dict_tracebacks to your processors and just in case - better before JSONRenderer.

Upvotes: 1

Related Questions