Logging and monitoring AI apps in production
You cannot investigate what you did not record. Log the right things about every AI interaction, protect the personal data inside those logs, and watch for abuse.
In 60 seconds
Logging and monitoring AI apps in production
You cannot investigate what you did not record. Log the right things about every AI interaction, protect the personal data inside those logs, and watch for abuse.
What to log for each interaction
| Field | Why | Privacy care |
|---|---|---|
| Request id, time, feature, tenant | Tie events together | Low risk |
| User id (pseudonymous where possible) | Per-user abuse and quotas | Use an internal id, not name or phone |
| Model name and version, prompt template version | Know which change caused what | Low risk |
| User input and model output | Investigate abuse and quality | Redact personal data; restrict access; shorter retention |
| Retrieved sources (document ids) | What influenced the answer | Log ids, not full document text |
| Tool calls, arguments and results | What the system actually did | Redact sensitive arguments |
| Tokens, cost, latency | Denial of wallet and performance | Low risk |
| Safety signals | Guardrail blocks, refusals, canary hits, limit hits | Low risk |
Redact before you store
import re
PATTERNS = [
("EMAIL", re.compile(r"[\w.+-]+@[\w-]+\.[\w.-]+")),
("PAN", re.compile(r"\b[A-Z]{5}[0-9]{4}[A-Z]\b")),
# Indian mobile: optional +91, then 10 digits starting 6-9.
# Runs before LONG_NUMBER, which would otherwise eat "+91 98..." whole.
("PHONE", re.compile(r"(?<!\d)(?:\+91[ -]?)?[6-9]\d{9}(?!\d)")),
# 12 to 16 digits, spaces or dashes allowed: Aadhaar-like or card-like
("LONG_NUMBER", re.compile(r"(?<!\d)\d(?:[ -]?\d){11,15}(?!\d)")),
]
def redact(text: str) -> str:
for label, pattern in PATTERNS:
text = pattern.sub(f"[{label}]", text)
return textSignals worth alerting on
| Signal | What it may mean |
|---|---|
| One account near its token limit every day, or a sudden cost spike | Denial of wallet, or a bot using your feature |
| Repeated prompt-extraction or "ignore previous instructions" style input | Someone probing your app |
| Your prompt canary appears in an output | The system prompt has leaked |
| Many refusals or blocked outputs for one user | Jailbreak attempts |
| Outputs with links or images to unknown domains | Possible data exfiltration attempt |
| A tool used far more than usual, or for the first time | Misuse, or a loop |
| Retrieved documents from another tenant | A permission filter failure: treat as an incident |
- 1
Baseline
Learn what normal looks like for a few weeks: volume, cost, refusals, tools. - 2
Rules
Write alert rules for the signals above; many teams use their SIEM, and formats such as Sigma for sharing detection rules. - 3
Route
Each alert goes to an owner who knows the feature. - 4
Runbook
Write what to do: block the account, turn off a tool, use the kill switch. - 5
Tune
Remove noisy alerts, add new ones after every incident.
Retention and rules
Watch and read more
Lab
A log record design, a working redaction function with tests, three alert rules and a retention table.
The problem
Work on your own computer with the fake data in the starter.
- Run the starter. Make the redaction tests pass (the patterns may need fixing or reordering).
- Add one test of your own for a case the patterns miss, and write one sentence on why regex alone is not enough.
- Design a JSON log record for one chatbot turn with at least eight fields from this lesson. Mark which fields hold personal data.
- Write three alert rules in plain words: signal, threshold, who gets told, first action.
- Write a retention table: full text, metadata, cost data, security alerts.
Practice lab
Edit the code and run it. Python runs in your browser — nothing is sent to our server.
No output. Add print(...) to see values.
You are done when
Hard questions
Try to answer before you reveal. If you can answer these, you understood the lesson.
Q1Why can the order of redaction patterns matter?Reveal
Because an earlier pattern can consume text that a later one needs. In the starter, the general "long number" pattern runs first and sees "91 9876543210" as a 12-digit number, so a phone number gets the wrong label and a stray "+" is left behind. Run the more specific patterns (a phone number with its country code) before the general catch-all ones, and use boundaries so a pattern cannot match inside a bigger number.
Q2An investigator needs the exact user message from 6 months ago, but your full-text retention is 30 days. How can you design for both privacy and investigations?Reveal
Keep metadata longer: request ids, user ids, model and prompt versions, document ids, tool calls and safety signals. When an alert fires or an incident opens, copy the related full records into a protected incident store with its own retention. Most investigations can start from metadata, and the most important text is preserved at the moment it becomes relevant.
Questions people ask
Should we log full prompts and outputs at all?
Often yes, because incidents are hard to investigate without them. But redact first, restrict access, and keep full text for a shorter time than metadata. For very sensitive features, consider logging only metadata plus a hash, with full text kept briefly for investigations.
How long should we keep AI logs?
There is no single answer. It depends on your purpose, your legal duties and your contracts. Decide per log type, write it down, and delete automatically when the time is up.
Can users ask us to delete their conversations?
Privacy laws often give people rights over their data, including erasure in many cases. Design logs so you can find and delete one user's data. Your legal team can say exactly what applies.
Does the model provider also keep our prompts?
It depends on the provider and your contract or settings. Read their data use and retention terms, and choose options that fit your data. This is part of your threat model, not an afterthought.
Lesson test
5 questions. Get 3 right (60%) to pass and complete this lesson.