Log redaction reduces disclosed data by selecting permitted diagnostic fields before formatting a message.
Python logging: allowlist fields before they reach a handler
Operation contract
The audit formatter keeps an exact event label and receipt ID while dropping an input token. It rejects line breaks and unexpected identifier shapes. This is an allowlist for one event, not a general secret detector. The original record remains unchanged so diagnostic formatting cannot mutate application state.
Failure and ownership boundary
Filtering a structured object cannot undo a secret already embedded in a free-text message, exception or another handler. Avoid handing the raw payload to logging in the first place. This fixture does not establish a retention, access-control or privacy policy. Python logging: include bounded context without printing sensitive payloads and Python JSON validation: reject duplicate members and non-integer amounts should be reviewed alongside it.
Working program
import json
import re
def audit_line(record):
event = record.get("event")
receipt_id = record.get("receipt_id")
if event not in {"accepted", "rejected"}:
raise ValueError("unsupported audit event")
if not isinstance(receipt_id, str) or re.fullmatch(r"R-[0-9]{4}", receipt_id) is None:
raise ValueError("invalid audit identifier")
return json.dumps({"event": event, "receipt_id": receipt_id}, sort_keys=True)
record = {"event": "accepted", "receipt_id": "R-0041", "token": "fixture-only"}
print(audit_line(record))
print("token" in record)
try:
audit_line({"event": "accepted", "receipt_id": "R-0041\n"})
except ValueError:
print("line injection rejected")Output
{"event": "accepted", "receipt_id": "R-0041"}
True
line injection rejectedCosts and limits
The selected identifier has a fixed six-character budget and the serialized result has bounded size. This cost does not apply to arbitrary messages or stack traces. Handler I/O and durable storage are separate operations.
Common Mistakes
- Do not log raw request objects before sanitizing them.
- A field allowlist cannot inspect secrets hidden inside arbitrary text.
Connected lessons
Python logging: include bounded context without printing sensitive payloads, Python regular expressions: use fullmatch for a complete field contract, Python JSON validation: reject duplicate members and non-integer amounts.
Check the next state boundary
Flask error responses: preserve status without exposing internal exception text.
