Health data, chat messages, notes, and authentication tokens are useful when debugging. That is exactly why careless logging is dangerous: logs are copied, indexed, retained, and viewed by more systems than the primary database.
I start with an allow-list mindset. Record operational metadata, not content.
logger.info(
'chat.turn.completed',
extra={
'event': 'chat.turn.completed',
'request_id': request_id,
'duration_ms': duration_ms,
'tool_rounds': tool_rounds,
'outcome': 'success',
},
)
This can answer whether a turn was slow without storing what the user said.
Keep identifiers joinable without exposing them#
Operational investigations often need to connect several events for one user. A stable one-way representation provides joinability:
def log_user_id(user_id: str) -> str:
digest = hashlib.sha256(user_id.encode()).hexdigest()[:12]
return f'u_{digest}'
This is pseudonymization, not anonymity. Protect the logs accordingly, but avoid copying raw account identifiers everywhere.
Redact more than headers#
A useful redaction policy covers:
- authorization, cookies, and API keys;
- request and response bodies;
- prompts, messages, notes, and transcripts;
- query strings that may contain search terms;
- exception-local variables containing tokens or secrets;
- Sentry users, tags, breadcrumbs, and contexts.
Apply sanitization before data leaves the process. A dashboard filter added later cannot remove secrets already ingested.
Separate events from payloads#
Prefer fields such as schema version, body size, date range, record count, provider status, and a content hash. These often identify the failure without reproducing the sensitive data.
Test privacy behavior#
Create log records and error events containing known sentinel secrets, then assert the serialized output does not contain them. Test suffix patterns such as _token and _secret, not only a fixed list.
Observability should make the system explainable. In sensitive products, the design challenge is retaining causal and performance evidence while minimizing the personal content that reaches operational tools.