Home / Blog / Structured Logging: Make Your Logs Answer Questions, Not Just Tell Stories
EngineeringAugust 10, 2026·3 min read

Structured Logging: Make Your Logs Answer Questions, Not Just Tell Stories

Why small engineering teams should switch from free-text logs to structured JSON logging, and how to do it without heavy tooling.

At 2 a.m., when a customer says their payment "just disappeared," the difference between a five-minute fix and a two-hour archaeology dig usually comes down to one thing: whether your logs are searchable data or a pile of prose. Most small teams start with console.log("payment failed for user " + id) and never revisit it — until the night they really need to.

Structured logging is the simplest upgrade with the highest payoff in a small team's observability stack. It costs almost nothing to adopt and pays you back on every incident.

What "structured" actually means

Instead of formatting values into a sentence, you emit a machine-readable record — usually one JSON object per line:

{"level":"error","event":"payment_failed","order_id":"ORD-2291","gateway":"midtrans","reason":"timeout","duration_ms":30012}

The human-readable message is optional. The fields are the point. Now "show me every gateway timeout in the last hour" is a filter, not a regex-guessing game against strings someone typed differently in five places.

The three habits that matter

Tooling is the easy part — pino in Node, structlog in Python, slog in Go. The discipline is what makes it work:

A good log line answers who, what, and with which request — before anyone has to ask.

Levels are a contract, not decoration

Pick meanings and enforce them. A workable scheme: error means a human should eventually look, warn means something degraded but self-healed, info marks business events worth auditing, debug is off in production by default. When everything is info, nothing is. The fastest way to ruin logging is to let error-level noise train the team to ignore errors.

Also decide what never gets logged: full card numbers, passwords, raw webhook payloads containing personal data. Redact at the logger level so nobody has to remember at the call site.

You don't need an observability platform yet

A common objection: "we don't run Elasticsearch." You don't need to. JSON-per-line logs on disk are already queryable with grep and jq:

cat app.log | jq 'select(.event=="payment_failed" and .gateway=="midtrans")'

That one-liner replaces an hour of scrolling. When you eventually outgrow files and adopt Loki, CloudWatch, or a hosted service, structured logs slot straight in — the migration is configuration, not a rewrite. Teams that log free text first end up paying twice: once in painful debugging now, and again in a reformatting project later.

The takeaway

Structured logging is not an enterprise practice you defer until you're big. It is a small-team superpower precisely because you have no dedicated ops crew — your logs are your on-call engineer. Pick a JSON logger, define ten event names for your core flows, attach IDs everywhere, and enforce log levels in code review. The next time something disappears at 2 a.m., you'll find it with a filter instead of a flashlight.

Build with Abati Technology

We build software that ships — WhatsApp API, developer tools, POS, and mobile apps. Let's talk about your project.

Get in Touch →