Logging¶
The drf_corekit.logging module provides structured request / response logging for Django and DRF projects.
Middleware¶
CoreLoggingMiddleware¶
Django middleware that automatically:
- Assigns a transaction ID to every incoming request (from header or auto generated)
- Attaches the transaction ID to the response header
- Logs structured request / response metadata on every response
Setup
Add it to your MIDDLEWARE in settings.py:
Logging Configuration¶
get_logging_config()¶
Builds and returns a fully valid Django LOGGING dict with pre configured formatters, handlers, and loggers. Use this in settings.py.
Signature
get_logging_config(
*,
console_level: str = "INFO",
file_level: str = "INFO",
error_level: str = "ERROR",
disable_existing_loggers: bool = False,
extra_formatters: dict | None = None,
extra_handlers: dict | None = None,
extra_loggers: dict | None = None,
) -> dict
Example — basic usage
Example — with overrides
LOGGING = get_logging_config(
console_level="DEBUG",
extra_loggers={
"myapp": {
"level": "DEBUG",
"handlers": ["core.console"],
"propagate": False,
}
},
)
get_drf_logging_config()¶
Shorthand for get_logging_config() with all defaults. Suitable for most cases.
Logger Access¶
get_logger()¶
Returns a cached logging.Logger instance scoped to a context. Accepts a LoggerContext enum or a plain string.
Signature
Example
from drf_corekit.logging.loggers import get_logger
from drf_corekit.logging.contexts import LoggerContext
logger = get_logger(LoggerContext.AUDIT)
logger.info("User updated profile", extra={"user_id": user.id})
LoggerContext¶
A StrEnum used to categorize log entries by their purpose.
| Member | Value | Use for |
|---|---|---|
REQUEST |
"request" |
Incoming HTTP requests and responses |
AUDIT |
"audit" |
State changes, approvals, business events |
SECURITY |
"security" |
Auth, authorization, security events |
INTEGRATION |
"integration" |
External service or third party calls |
TASK |
"task" |
Background jobs, scheduled work |
SYSTEM |
"system" |
Internal system or infrastructure logs |
Example
from drf_corekit.logging.loggers import get_logger
from drf_corekit.logging.contexts import LoggerContext
logger = get_logger(LoggerContext.SECURITY)
logger.warning("Failed login attempt", extra={"username": username})
Operation Context¶
OperationContext¶
Thread-safe, request-scoped key/value store backed by contextvars. Used internally by CoreLoggingMiddleware to propagate the transaction ID, but also accessible in application code.
| Method | Description |
|---|---|
OperationContext.set(key, value) |
Store a value for the current request |
OperationContext.get(key, default=None) |
Retrieve a stored value |
OperationContext.clear() |
Clear all context (called automatically at end of request) |
OperationContext.set_transaction_id(txn_id) |
Store the transaction ID |
OperationContext.get_transaction_id(default=None) |
Retrieve the current transaction ID |
Example — reading the transaction ID in a view
from drf_corekit.logging.contexts import OperationContext
def my_view(request):
txn_id = OperationContext.get_transaction_id()
...
Example — storing custom request-scoped data
OperationContext.set("tenant_id", request.tenant.id)
# later in the same request
tenant_id = OperationContext.get("tenant_id")
Advanced¶
LoggerFactory¶
Creates a logging.Logger using a pluggable resolver. Useful when you need custom logger naming beyond what get_logger() provides.
from drf_corekit.logging.factory import LoggerFactory
logger = LoggerFactory(context="payments").get_logger()
LoggerNameResolver¶
Base class for custom logger naming strategies. Subclass this and pass it to LoggerFactory to override the default core.<context> naming.
from drf_corekit.logging.factory import LoggerFactory, LoggerNameResolver
class MyResolver(LoggerNameResolver):
def resolve(self, context: str | None, file_path: str | None) -> str:
return f"myapp.{context}" if context else "myapp"
logger = LoggerFactory(context="payments", resolver=MyResolver()).get_logger()