Skip to Content
FeaturesModulesLogging

Django Logging

Django-CFG’s Logging Module provides auto-configuring structured logging for the django_cfg namespace. It sets up modular per-module log files with daily rotation and configurable retention.

Features

  • Modular log files — separate rotating file per django_cfg.* logger under logs/djangocfg/
  • Daily rotationTimedRotatingFileHandler with midnight rotation and configurable retention
  • Debug-aware levelsDEBUG to files in dev mode, WARNING to console in production
  • Sanitized extra context — reserved LogRecord attributes in extra={} are automatically prefixed with ctx_

Quick Start

from django_cfg.modules.django_logging import get_logger logger = get_logger("django_cfg.myapp") logger.debug("Processing started") logger.info("User created", extra={"user_id": 42}) logger.warning("Rate limit approaching", extra={"endpoint": "/api/users"}) logger.error("Payment failed", extra={"order_id": "ORD-123"})

get_logger() automatically detects the caller’s file path to build the logger name when called without arguments from within django_cfg code:

# In a file at django_cfg/modules/my_module/service.py logger = get_logger() # auto-resolves to: django_cfg.my_module (or similar based on path) # Explicit name logger = get_logger("django_cfg.payments.stripe")

get_logger() rewrites a name that doesn’t start with django_cfg based on the caller’s file path, and the per-module log file is chosen from the resolved name. To be certain which file an event lands in, pass a fully-qualified name (get_logger("django_cfg.payments.stripe")).

Configuration

Configure on the DjangoConfig (logging is on by default — you only set this to tune retention):

from django_cfg.modules.django_logging import DjangoLoggingConfig class MyExtensionSettings: logging = DjangoLoggingConfig( enabled=True, file_enabled=True, file_rotation_days=30, )

DjangoLoggingConfig Fields

FieldTypeDefaultDescription
enabledboolTrueEnable or disable the module
file_enabledboolTrueEnable file logging
file_rotation_daysint30Days of log files to retain (1–365)

Log File Layout

On startup, DjangoLogger creates the following directory structure in the project root:

logs/ ├── django.log # All Django logs (rotation: daily, keep 30 days) └── djangocfg/ ├── core.log # django_cfg.core.* ├── email.log # django_cfg.email.* ├── telegram.log # django_cfg.telegram.* └── <module>.log # One file per django_cfg.* sub-namespace /tmp/djangocfg/ └── debug.log # Always-on debug mirror (set DJANGO_LOG_TO_TMP=false to disable)

Log level per handler:

HandlerDev (DEBUG=True)Production
ConsoleDEBUGWARNING
logs/django.logDEBUGINFO
logs/djangocfg/<module>.logDEBUGINFO
/tmp/djangocfg/debug.logDEBUGDEBUG

Public API

get_logger(name="")

Returns a configured logging.Logger instance. Auto-detects caller path when called without arguments from within django_cfg code.

from django_cfg.modules.django_logging import get_logger logger = get_logger("django_cfg.payments")

sanitize_extra(extra)

Prefixes any key in extra that conflicts with Python’s reserved LogRecord attributes (e.g., module, message, name) with ctx_ to prevent KeyError.

from django_cfg.modules.django_logging import sanitize_extra safe = sanitize_extra({"module": "myapp", "user_id": 42}) # {"ctx_module": "myapp", "user_id": 42} logger.info("Event", extra=safe)

clean_old_logs(days=30, logs_dir=None)

Deletes log files older than days from the logs/ directory. Returns a stats dict:

from django_cfg.modules.django_logging import clean_old_logs stats = clean_old_logs(days=7) # {"deleted": 12, "bytes": 45678, "human_readable": "0.04 MB"}

Environment Variable

Set DJANGO_LOG_TO_TMP=false to disable the /tmp/djangocfg/debug.log mirror:

DJANGO_LOG_TO_TMP=false python manage.py runserver

See Also

Last updated on