django-structlog

10.0.0 · active · verified Fri Apr 10

django-structlog is a structured logging integration for Django projects that leverages the `structlog` library. It enriches logs with cohesive metadata, simplifying event and incident tracking. The current version is 10.0.0, and the library maintains an active release cadence with multiple updates throughout the year to support new Django and Python versions.

Warnings

Install

Imports

Quickstart

To get started with `django-structlog`, install the package, add `"django_structlog"` to your `INSTALLED_APPS`, and `"django_structlog.middlewares.RequestMiddleware"` to your `MIDDLEWARE` settings. Crucially, configure your `LOGGING` dictionary in `settings.py` to use `structlog.stdlib.ProcessorFormatter` with appropriate processors, including `structlog.contextvars.merge_contextvars` as the first processor. Finally, configure `structlog` itself using `structlog.configure()`. You can then obtain loggers using `structlog.get_logger()` and log structured messages.

import structlog

# settings.py

INSTALLED_APPS = [
    # ...
    "django_structlog",
    # ...
]

MIDDLEWARE = [
    # ...
    "django_structlog.middlewares.RequestMiddleware",
    # ...
]

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "json_formatter": {
            "()": structlog.stdlib.ProcessorFormatter,
            "processor": structlog.processors.JSONRenderer(),
            "foreign_pre_chain": [
                structlog.contextvars.merge_contextvars,
                structlog.processors.TimeStamper(fmt="iso"),
                structlog.stdlib.add_logger_name,
                structlog.stdlib.add_log_level,
                structlog.stdlib.PositionalArgumentsFormatter(),
            ],
        },
        "plain_console": {
            "()": structlog.stdlib.ProcessorFormatter,
            "processor": structlog.dev.ConsoleRenderer(),
            "foreign_pre_chain": [
                structlog.contextvars.merge_contextvars,
                structlog.processors.TimeStamper(fmt="iso"),
                structlog.stdlib.add_logger_name,
                structlog.stdlib.add_log_level,
                structlog.stdlib.PositionalArgumentsFormatter(),
            ],
        },
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "plain_console",
        },
        "json_file": {
            "class": "logging.handlers.RotatingFileHandler",
            "filename": "logs/json.log",
            "maxBytes": 1024 * 1024 * 5,  # 5 MB
            "backupCount": 5,
            "formatter": "json_formatter",
        },
    },
    "loggers": {
        "django_structlog": {
            "handlers": ["console", "json_file"],
            "level": "INFO",
            "propagate": False,
        },
        "django": {
            "handlers": ["console", "json_file"],
            "level": "INFO",
            "propagate": False,
        },
        "my_app": { # Example for your application logs
            "handlers": ["console", "json_file"],
            "level": "DEBUG",
            "propagate": False,
        },
        "root": {
            "handlers": ["console", "json_file"],
            "level": "INFO",
        },
    },
}

structlog.configure(
    processors=[
        structlog.contextvars.merge_contextvars, # MUST be the first processor
        structlog.stdlib.filter_by_level,
        structlog.processors.TimeStamper(fmt="iso"),
        structlog.stdlib.add_logger_name,
        structlog.stdlib.add_log_level,
        structlog.stdlib.PositionalArgumentsFormatter(),
        structlog.processors.StackInfoRenderer(),
        structlog.processors.format_exc_info,
        structlog.processors.UnicodeDecoder(),
        structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
    ],
    logger_factory=structlog.stdlib.LoggerFactory(),
    cache_logger_on_first_use=True,
)

# views.py (example usage)
import structlog
from django.http import HttpResponse

logger = structlog.get_logger(__name__)

def my_view(request):
    logger.info("request_received", path=request.path, method=request.method)
    # Your view logic
    return HttpResponse("Hello from django-structlog!")

view raw JSON →