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.2.tar.gz (40.7 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.2-py3-none-any.whl (40.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: logforge_django-0.1.2.tar.gz
  • Upload date:
  • Size: 40.7 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.2.tar.gz
Algorithm Hash digest
SHA256 aaa3e814928b061e0cfa2261b95522f6fb441f0f6b43a0c4261f018cacea8ba8
MD5 aa73a9346b41f88c26c9863982a073f6
BLAKE2b-256 e888bdd07e14b2cf9c4644a34273f1666e0348b4fb34a2af3ef4a2b3a1e0ec0b

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for logforge_django-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b7552a07194d8f9e92df7dbda02995bfd5345762b594a81dfa567e96e8f9b217
MD5 fe7050ff4223a63e82abdf23be9ee036
BLAKE2b-256 ef74b1566102a0edf12ff6d89c71f7032dab0f97343e3d5ed5165cc1e1e63b43

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