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 viaLOGFORGE['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;
changedrespects 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=Trueordeleted_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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d76ae702a6800c22325c21a6d59ff41a7a268a884ba222fb5a52fdf66a36857
|
|
| MD5 |
62157963a3bf59601ac1fdd84d851b87
|
|
| BLAKE2b-256 |
d631c7f87384fd62f4ce260dcefe4dd1cde889c40ed2fd081f31d085e7c4b561
|
File details
Details for the file logforge_django-0.1.3-py3-none-any.whl.
File metadata
- Download URL: logforge_django-0.1.3-py3-none-any.whl
- Upload date:
- Size: 40.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
087c401d834bffc582fa02e73321f9e6c0a22b4f34cf58af84795370f9166de6
|
|
| MD5 |
1995322e97e5eeb4b9d230ec5897623c
|
|
| BLAKE2b-256 |
36afe6c062e6df67f195d3bd80ebcd3076c38257b586040a78dbd26b82881372
|