Skip to course content
Free LangChain course

LangChain for LLM Applications and RAG

Unit 09.04: Logging without leaking content

Logs built for debugging quietly become the least-protected copy of your most sensitive data.

Redact on the way in

Patterns for account numbers, emails and card numbers, applied before anything is written.

The code redacts a support message and shows a safe log record.

import re

REDACTIONS = [
    (re.compile(r"\bACC-\d+\b"), "[ACCOUNT]"),
    (re.compile(r"[\w.+-]+@[\w-]+\.[\w.]+"), "[EMAIL]"),
    (re.compile(r"\b\d{4}[ -]?\d{4}[ -]?\d{4}[ -]?\d{4}\b"), "[CARD]"),
]


def redact(text):
    for pattern, replacement in REDACTIONS:
        text = pattern.sub(replacement, text)
    return text


RAW = ("Customer [email protected] on ACC-1187 disputes a charge on "
       "4111 1111 1111 1111")
print("raw     :", RAW)
print("redacted:", redact(RAW))

safe_log = {"request_id": "r-8841", "prompt_version": "answer-v3",
            "tokens": 1_240, "latency_ms": 820, "retrieved_ids": ["c1"],
            "content": redact(RAW)}
print("\nlogged  :", safe_log)

# Redact on the way in, not on the way out. A log that captures raw content and
# promises to clean it later is a store of personal data with a plan attached,
# and the plan is what gets deprioritised.

The safe record keeps everything useful for debugging - request id, versions, tokens, latency, retrieved ids - and the content only in redacted form. Almost every investigation you will run needs the first group and not the second.

Redacting on the way in rather than out is the part that matters. A log capturing raw content with a plan to clean it later is a store of personal data with a plan attached, and the plan is what gets deprioritised.

The mistake this prevents

The mistake is relying on regex redaction as complete. These patterns catch structured identifiers and miss free text - a customer writing their own name and address in a question is not matched by any of them. Redaction reduces exposure; retention limits and access control are what bound it.

Takeaway

Redact structured identifiers before writing, keep the debugging metadata in full, and treat redaction as reduction rather than removal. Retention and access control do the rest.