Audit Logging¶
The core.audit system provides centralized, structured logging of all important business actions.
It ensures that all critical changes in the system are:
- traceable
- consistent
- queryable
- debuggable
Audit logging is a core infrastructure feature and is used across all apps.
Purpose¶
Audit logs exist to answer:
- Who did what?
- When did it happen?
- What changed?
- On which object?
They are essential for:
- debugging
- compliance
- accountability
- analytics
- incident investigation
Core Concept¶
All audit logging is performed through a single helper:
log_audit(...)
This function creates an AuditLog entry for any model instance.
Audit Log Model¶
Each audit entry contains:
- actor → user who performed the action (nullable)
- action → string describing the event
- object_repr → human-readable object representation
- object_pk → primary key (string)
- content_type → model type
- object_id → object identifier (string)
- changes → structured JSON describing what changed
- ip → request IP address
- user_agent → client user agent
- created_at → timestamp
Logging an Action¶
Example usage:
log_audit( instance=membership, actor=request.user, action="org_membership.role_changed", changes={ "role": { "old": "engineer", "new": "manager", } }, request=request, )
Action Naming Convention¶
Actions follow a consistent naming pattern:
Examples:
- team.created
- team.updated
- team.deactivated
-
team.reactivated
-
team_membership.added
- team_membership.updated
- team_membership.role_changed
- team_membership.deactivated
-
team_membership.reactivated
-
org_membership.created
- org_membership.updated
- org_membership.role_changed
- org_membership.deactivated
- org_membership.reactivated
Changes Format¶
The changes field must be:
- JSON-serializable
- minimal
- structured
Standard pattern¶
{
"field_name": {
"old":
Example¶
{ "role": { "old": "engineer", "new": "manager" }, "is_active": { "old": true, "new": false } }
Metadata¶
If a request is provided:
- IP address is extracted from request.META
- user agent is extracted from request headers
If no request is provided: - metadata fields remain empty
Where Audit Logging Happens¶
Audit logging is performed in the service layer, not in views.
Why?¶
Because:
- services define business logic
- services know what actually changed
- views should remain thin
- logging must not depend on HTTP layer
When to Log¶
Audit logs should be created when:
- objects are created
- objects are updated
- objects are deactivated or reactivated
- roles or permissions change
- ownership or relationships change
When NOT to Log¶
Avoid logging:
- read operations
- trivial or derived state changes
- idempotent operations (no actual change)
- internal helper updates with no business meaning
Idempotency¶
Audit logs should only be created when something actually changes.
Example:
- updating a team with the same data → no audit log
- deactivating an already inactive object → no audit log
This prevents noise in the audit trail.
Querying Audit Logs¶
Helper functions are provided:
By object¶
list_audit_logs_for_object(instance=team)
By actor¶
list_audit_logs_for_actor(actor=user)
By action¶
list_audit_logs_for_action(action="team.updated")
Data Model Relationship¶
flowchart TD
A[User] --> B[AuditLog]
C[Any Model] --> B
B --> D[Changes JSON]
- Any model can be linked via content_type + object_id
- This uses Django’s GenericForeignKey
Integration Example¶
Example: updating a team
- Service validates input
- Service determines changed fields
- Service updates model
- Service calls
log_audit - Audit entry is persisted
Logging Strategy¶
The system follows:
- event-based logging (not field-level hooks)
- explicit logging (no hidden magic)
- service-controlled logging
This ensures clarity and avoids unexpected behavior.
Benefits¶
Audit logging provides:
- full traceability of changes
- consistent debugging information
- structured data for analytics
- foundation for future features (history UI, activity feeds)
Future Extensions¶
The audit system can be extended with:
- UI for audit history
- filtering and pagination APIs
- export capabilities
- real-time activity streams
- soft-delete tracking
- field-level diff visualization
Summary¶
The audit system is a critical part of the backend infrastructure.
It ensures that all important actions are:
- recorded
- structured
- accessible
This improves reliability, transparency, and long-term maintainability of the system.