minvws / nl-kat-coordination

Repo nl-kat-coordination for minvws
European Union Public License 1.2
121 stars 55 forks source link

Introduce Structured Logging #3114

Open ammar92 opened 1 week ago

ammar92 commented 1 week ago

About this feature

To create a basic audit trail, we need to introduce structured logging in our modules.

Detailed description

Implementing structured logging will not only aid in debugging the application but will also provide valuable content that can be processed into audit or event log records. This feature will enhance both transparency and traceability of actions within the system.

Implementation

Possible solution

We could also hook on loggers used by our dependencies, such as httpx, to get HTTP requests logging.

jpbruinsslot commented 1 week ago

perhaps a helpful django settings.py example using structlog, is a few years old now so take it with a grain of salt:

import structlog

# ...

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

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'structlog': {
            '()': structlog.stdlib.ProcessorFormatter,
            'processor': structlog.processors.JSONRenderer(),
        },
    },
    'handlers': {
        'stderr': {
            'level': 'DEBUG',
            'formatter': 'structlog',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['stderr'],
            'level': 'WARNING',
        },
        "django_structlog": {
            "handlers": ["stderr"],
            "level": "DEBUG",
        },
    },
}

structlog.configure(
    processors=[
        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.processors.ExceptionPrettyPrinter(),
        structlog.stdlib.ProcessorFormatter.wrap_for_formatter,
    ],
    context_class=structlog.threadlocal.wrap_dict(dict),
    logger_factory=structlog.stdlib.LoggerFactory(),
    wrapper_class=structlog.stdlib.BoundLogger,
    cache_logger_on_first_use=True,
)