Logs should help an operator answer a question without requiring access to private data. That means deciding what not to record is as important as choosing the fields that make an event searchable.
Risky fields
Treat these values as sensitive by default:
- access tokens and cookies;
- passwords and password-reset links;
- payment details;
- private message contents;
- complete authorization headers.
Even when a value is technically harmless today, it can become sensitive after systems are connected together.
Prefer identifiers
Record a short-lived request ID instead of the entire payload:
{
"event": "profile.updated",
"requestId": "req_72f4",
"userId": "user_1842",
"changedFields": ["timezone"]
}
This gives an investigator a useful path while keeping the event compact.
| Avoid | Prefer |
|---|---|
| Full email address | Internal user ID |
| Request body | Validated field names |
| Session cookie | Request ID |
| Raw exception with input | Sanitized error code |
Review the failure path
Sensitive data often appears in logs only when something fails. Test validation errors, upstream failures, and retry messages separately from the happy path.
A redacted log is not a broken log. It is a log designed for its audience.