An immutable ledger of who did what, when, and where.
Application logs (`logger.info("request started")`) are for debugging. Audit Logs are for security and compliance. They answer specific questions during an incident: "Who deleted the production database?", "When was this permission granted?", or "Did Alice view Bob's medical records?". Because of this, they must be structured, immutable, and heavily protected.
Audit events must capture the "Five W's": Who, What, When, Where, and Why (if applicable). They are often written to an append-only datastore (like AWS S3 with Object Lock or a specialized SIEM) so that even if the main database is compromised, the hacker cannot erase their tracks.
def delete_user(admin_id, target_user_id, ip_address):
# 1. Perform the action
db.users.delete(target_user_id)
# 2. Fire-and-forget the Audit Log (Async or via Message Queue)
audit_event = {
"timestamp": "2023-10-25T14:32:00Z",
"actor_id": admin_id,
"action": "user.deleted",
"target_resource": f"user/{target_user_id}",
"ip_address": ip_address,
"status": "success"
}
# Push to an immutable, append-only store
audit_queue.publish(audit_event)
Audit logging increases storage costs (as logs are kept for years for compliance) and adds slight complexity to state-mutating code. It usually requires a dedicated pipeline (like Kafka -> S3) separate from normal application logs.