Unit 14.04: What to log, and what never to log
The fields that explain almost every incident contain no user content at all.
Five always, three never
What to log and what must never be logged.
The code sorts eight fields.
FIELDS = [
("request_id", "always", "how a support ticket becomes traceable"),
("method and path", "always", "no user content"),
("status and latency", "always", "the operational picture"),
("caller identity", "always", "which key, not which person"),
("model and prompt version", "always", "explains an answer six weeks later"),
("request body", "NEVER", "user content; may contain anything"),
("model output", "NEVER", "may repeat user content"),
("the API key", "NEVER", "the credential itself"),
]
print(f"{'field':28} {'log it?':8} why")
for field, when, why in FIELDS:
print(f"{field:28} {when:8} {why}")
always = sum(1 for _, w, _ in FIELDS if w == "always")
print(f"\n{always} fields explain almost every incident, and none is content")
Request id, method and path, status and latency, caller identity, and the model and prompt versions explain nearly every incident you will investigate - and none of them is content.
The request body and the model output are the two that make a log store a second copy of everything a user typed. That store is usually more widely readable than the database, and was set up with less thought.
The mistake this prevents
The mistake is logging the body during an incident to help debug, and leaving it on. The temporary change becomes permanent, and nobody revisits it because it is doing something useful.
Takeaway
Log identifiers, timings, statuses and versions; never bodies, outputs or credentials. The metadata explains almost every incident on its own.
