Skip to main content

Django audit logging package for LogForge

Project description

LogForge Django

Unified audit logging for Django: creates audit_logs rows on create, update, delete, restore, force_delete with diffs, actor, IP, and context.

Install

pip install logforge-django

Configure (settings.py)

INSTALLED_APPS = [
    # ...
    'logforge.audit',  # or 'logforge.audit.apps.AuditConfig'
]

MIDDLEWARE = [
    # ...
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'logforge.audit.middleware.request_context.RequestContextMiddleware',
]

LOGFORGE = {
    'enabled': True,
    'events': ['create','update','delete','restore','force_delete'],
    'include': [],
    'exclude': ['updated_at'],
    'redact': ['password','token','secret'],
    'actor': {'resolver': None, 'default': None},
    'context': {'capture_ip': True, 'capture_user_agent': True},
    'payload_max_bytes': 65536,
    'suppress_exceptions': True,
    'writer': 'db',  # 'db' (default) or 'queue'
    'queue': {'queue': 'celery', 'delay': 0},
    'archive': {'enabled': False, 'path': None, 'format': 'json'},
    'performance': {'enabled': False, 'slow_threshold_ms': 100, 'sample_rate': 1.0},
}

Run:

python manage.py migrate

Use

from django.db import models
from logforge.audit.mixins.logs_activity import LogsActivity

class Post(LogsActivity, models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField(blank=True)

Writers

  • Database (default): 'writer': 'db' (sync)

  • Queue (Celery): 'writer': 'queue'

    • Default queue name is 'audit-logs'. You can override via LOGFORGE['queue']['queue'].

    • settings.py:

      CELERY_BROKER_URL = 'redis://127.0.0.1:6379/0'
      CELERY_RESULT_BACKEND = 'redis://127.0.0.1:6379/1'
      
    • myproject/celery.py:

      import os
      from celery import Celery
      os.environ.setdefault('DJANGO_SETTINGS_MODULE','myproject.settings')
      app = Celery('myproject')
      app.config_from_object('django.conf:settings', namespace='CELERY')
      app.autodiscover_tasks()
      
    • myproject/init.py:

      from .celery import app as celery_app
      __all__ = ('celery_app',)
      
    • Run:

      python manage.py runserver
      celery -A myproject worker -P solo -l info
      
    • Example writer configuration (overrides shown):

      LOGFORGE.update({
          'writer': 'queue',
          'queue': {
              # default is 'audit-logs' if not set
              'queue': 'audit-logs',
              # seconds to delay (optional)
              'delay': 0,
          },
      })
      

Include/Exclude & Redaction

LOGFORGE.update({
    'include': [],
    'exclude': ['updated_at'],
    'redact': ['password','token'],
    'per_model': {
        'myapp.Post': {'include': ['title','content'], 'redact': ['content']},
        'myapp.CustomUser': {'exclude': ['last_login','date_joined'], 'redact': ['password','email']},
    }
})
  • Diffs are filtered; changed respects filters.
  • If update diff is empty after filtering, it’s skipped.
  • Redaction supports dot-notation (e.g., new.metadata.user.profile.email).

Soft Deletes

  • Set is_deleted=True or deleted_at → event “delete”
  • Clear them → “restore”
  • Hard row removal (on soft-deletable model) → “force_delete” Note: you implement the soft-delete behavior (manager/override); LogForge just logs it.

Batching

from logforge.audit.support.audit_batch import AuditBatch
with AuditBatch.run_context(context={'job':'seed'}) as batch_uuid:
    Post.objects.create(title='A', content='x')

Commands

  • Prune:
python manage.py prune_audit_logs --days=30 --dry-run
python manage.py prune_audit_logs --days=30
  • Archive:
python manage.py archive_audit_logs --days=90 --output="media/logforge/audit_90d.jsonl"

If LOGFORGE['archive']['path'] is unset, defaults to MEDIA_ROOT/logforge if available.

Dashboard

Add the LogForge dashboard routes to your project URLs to enable the UI and API endpoints:

# myproject/urls.py
from django.urls import include, path

urlpatterns = [
    # ...
    path('logforge/', include('logforge.audit.urls', namespace='logforge')),
]

Access control defaults to authenticated staff users. You can customize with LOGFORGE['dashboard']:

LOGFORGE.update({
    'dashboard': {
        # Dotted path to a callable that receives a user and returns True/False
        # Example: 'myproject.auth.can_view_logforge'
        'allow': None,  # None => default to user.is_authenticated and user.is_staff

        # When True, redirects unauthorized users to Django admin login instead of LOGIN_URL
        'use_admin_login': False,
    }
})

Performance (optional)

LOGFORGE['performance'] = {'enabled': True, 'slow_threshold_ms': 100, 'sample_rate': 1.0}

Admin (optional)

from django.contrib import admin
from logforge.audit.models.activity_log import ActivityLog

@admin.register(ActivityLog)
class ActivityLogAdmin(admin.ModelAdmin):
    list_display = ('event_type','resource_type','resource_id','user_id','ip_address','batch_uuid','created_at')
    list_filter = ('event_type','resource_type','created_at')
    search_fields = ('resource_type','resource_id','user_id','ip_address','batch_uuid')
    date_hierarchy = 'created_at'
    readonly_fields = ('created_at','updated_at')

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

logforge_django-0.1.3.tar.gz (40.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

logforge_django-0.1.3-py3-none-any.whl (40.4 kB view details)

Uploaded Python 3

File details

Details for the file logforge_django-0.1.3.tar.gz.

File metadata

  • Download URL: logforge_django-0.1.3.tar.gz
  • Upload date:
  • Size: 40.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.18

File hashes

Hashes for logforge_django-0.1.3.tar.gz
Algorithm Hash digest
SHA256 6d76ae702a6800c22325c21a6d59ff41a7a268a884ba222fb5a52fdf66a36857
MD5 62157963a3bf59601ac1fdd84d851b87
BLAKE2b-256 d631c7f87384fd62f4ce260dcefe4dd1cde889c40ed2fd081f31d085e7c4b561

See more details on using hashes here.

File details

Details for the file logforge_django-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for logforge_django-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 087c401d834bffc582fa02e73321f9e6c0a22b4f34cf58af84795370f9166de6
MD5 1995322e97e5eeb4b9d230ec5897623c
BLAKE2b-256 36afe6c062e6df67f195d3bd80ebcd3076c38257b586040a78dbd26b82881372

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page