Chitragupta — Keeper of Records (Logging & Audit)
Chitragupta records every deed: every request, every state change, every call — accurately and nothing more.
Structured logging only
- All logs are structured JSON. No bare
print(), no f-string log soup.- Python:
structlogwith JSON renderer. Bind context once (structlog.contextvars), not per-line. - Node/TS:
pino. Use child loggers for per-request context.
- Python:
- One event per log line. Put data in fields, not in the message string:
log.info("order_created", order_id=..., amount=...). - Log to stdout/stderr; the platform ships them. Never write log files inside containers.
Log levels
DEBUG: developer diagnostics, off in prod by default.INFO: normal business events (request completed, job finished).WARN: degraded but handled (retry succeeded, fallback used).ERROR: something failed and needs attention. Always include the exception/stack.- Never log expected control flow at ERROR, and never swallow exceptions at DEBUG.
Correlation & tracing
- Every inbound request gets a correlation/trace ID (accept
X-Request-ID/W3Ctraceparent, or generate one). - Propagate the ID to every downstream call, queue message, and background job. Include it in every log line and error response.
- Prefer OpenTelemetry trace context over homegrown IDs (see
surya).
What never gets logged
- Secrets, API keys, tokens, passwords, session cookies,
Authorizationheaders. - PII (emails, phone numbers, addresses) unless explicitly required — then mask (
a***@gmail.com). - Full request/response bodies by default; log sizes and status instead.
- Add a redaction processor (structlog processor / pino
redactpaths) so this is enforced in code, not by discipline.
Log at boundaries
- Request in: method, path, correlation ID. Response out: status, duration ms.
- Every external call (DB excepted): target, duration, status, retry count.
- Background jobs: start, finish/fail, duration, items processed.
Audit trail
- Every state-changing action (create/update/delete, permission change, login) writes an audit record: who (user/service ID), what (action + entity + before/after where feasible), when (UTC timestamp), from where (IP/origin).
- Audit records are append-only — separate table or stream, never edited or deleted by application code.
- Define retention up front: app logs 30 days hot, audit logs ≥ 1 year (or per compliance requirement).
AI-native specifics
- Log every LLM call with: prompt template version, model ID, input/output token counts, latency ms, finish reason, cost estimate.
- Redact or hash raw user content in LLM logs where policy requires; store full transcripts only in a designated, access-controlled store.
- Log tool-call sequences for agent runs so failures can be replayed step by step.
Before shipping logging — checklist
- JSON structured output, correct levels, one event per line
- Correlation ID present and propagated end to end
- Redaction in place — no secrets, tokens, or unmasked PII
- State-changing actions produce audit records (who/what/when)
- LLM calls log model, prompt version, tokens, latency