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

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for logforge_django-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5b207449e5b1f4dd9266d71e7a03b78cfb4c12f2894cbf73c25a584a1903e491
MD5 7d05a1600e79717c621d0655010f9421
BLAKE2b-256 8f9f066e86ad7602663ee76ad61a7dfb7b529b5ce0f5ec301a0098f39b42f926

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for logforge_django-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fa09f9097179d8ec5ecbf0eb0da1b130ecfe682ad718bfcc0cef1f1b802f9d5d
MD5 5e72c81a5fc0d325025870241960f20e
BLAKE2b-256 824be0fbc34c69b45d90116fed4f9e70ae9e3a04914fe943a7d0c3034c8ba615

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