Juicy Shop
Security Logging & Monitoring
If you can't see an attack, you can't stop it. Learn what security events to log, how to avoid logging secrets, and why alerting and an incident response plan turn logs into defence.
Why detection matters
Prevention fails eventually — the question is how long an attacker dwells before you notice. The industry measures breaches in months of undetected access. Logging and monitoring failures mean you learn about a compromise from a customer, a regulator, or the news rather than from your own systems. Good telemetry shrinks dwell time from months to minutes.
What to log
Record security-relevant events: authentication successes and failures, access-control denials, input-validation failures, high-value actions (password/email change, payments, privilege changes), and admin activity. Each entry needs enough context to investigate — timestamp, source IP, user/session id, action, and outcome — plus a correlation id so you can stitch a request across services.
What NOT to log
Logs are a juicy target, so never write secrets into them: passwords, full card numbers, session tokens, API keys, or personal data beyond what you need. Redact or hash identifiers where possible. A log that leaks credentials turns your observability system into a breach. Also protect log integrity — append-only, access-controlled storage stops an attacker from erasing their tracks.
From logs to response
Logs nobody reads are just disk usage. Define thresholds and alerts (e.g. a spike in failed logins, repeated access-control denials, a new admin account) and route them to people who can act. Pair this with an incident-response plan: who is paged, how you contain, and how you communicate. Test the pipeline — an alert that never fires is indistinguishable from no alert.
Insecure vs secure
try {
await login(email, password);
} catch {
// swallowed — no record an attack is happening
}
log.info(`login attempt ${email}:${password}`);Failures are silently swallowed (no detection) and the password is written to the log, turning the log store into a credential leak.
try {
await login(email, password);
log.info({ event: "auth.success", email, ip });
} catch (err) {
log.warn({ event: "auth.failure", email, ip, id });
metrics.increment("auth.failure");
// alert fires on a spike of failures
}Both outcomes are logged with structured context and no secrets, and a metric drives alerting so a brute-force spike is noticed in real time.
Key takeaways
- You cannot respond to attacks you never detect — telemetry shrinks dwell time.
- Log auth events, access denials, validation failures, and high-value actions with context.
- Never log secrets or sensitive data; protect log integrity.
- Turn logs into alerts and pair them with a tested incident-response plan.