Engineering Notes
Home/DevOps & Cloud/Observability/Logging (Platform View)
DevOps & Cloud · Observability

Logging (Platform View)

Logs are the detailed record of what happened, and at scale they're also a cost and compliance problem. Build a pipeline from structured stdout logs to a searchable store, see where PII gets redacted, and understand Loki vs Elasticsearch trade-offs.

☁️ DevOps & Cloud● Beginner⏱ 5 min read▶ 1 interactive🛠️ 2 exercises🎤 5 interview Q&As

🎯 What you'll learn

  • The logging pipeline: emit, collect, process, store, query
  • Structured JSON logs with a consistent schema
  • Storage models, retention and cost
  • Multiline gotchas, security and compliance

📚 Before you start

backend/frameworks/13-logging covered how an application writes good logs (levels, structured JSON, child loggers, redaction). This topic covers what happens to logs after they leave the process: collection, shipping, parsing, storage, querying, retention and cost — the logging platform.

1The Pipeline

text
app → stdout/stderr (JSON lines)
    → container runtime writes /var/log/containers/<pod>_<ns>_<container>-<id>.log
    → node agent (Fluent Bit / Vector / OTel Collector DaemonSet) tails files
         · parses JSON / multiline stack traces
         · enriches: k8s namespace, pod, labels, node, cluster, region
         · redacts / drops / samples
    → buffer (disk/memory; sometimes Kafka for large fleets)
    → backend: Loki · Elasticsearch/OpenSearch · CloudWatch Logs · Datadog · Splunk
    → query UI, alerts on log patterns, archive to object storage

Apps write to stdout; the platform does the rest (twelve-factor). Apps should never know where logs end up.

2Structure and Schema

Agree on a common schema across services so queries work fleet-wide:

FieldExampleWhy
timestampRFC 3339 with ms, UTCordering, correlation
levelinfofiltering
service, version, envcheckout, 2.3.1, prodwhich deploy produced it
trace_id, span_idW3C idsjump from a trace to its logs (03-tracing_and_correlation_ids/)
messageconstant event namegrouping
event-specific fieldsorder_id, duration_ms, statusfiltering, aggregation

OpenTelemetry's log data model and Elastic Common Schema (ECS) are ready-made conventions.

Unstructured
text
2026-10-20 09:12:03 ERROR payment failed for user 42 amount 45.00 card 4242424242424242

Hard to query, and it leaks a card number.

Structured JSON
json
{"ts":"2026-10-20T09:12:03Z","level":"error","service":"payments",
 "msg":"payment failed","user_id":"42","amount_cents":4500,
 "error":"card_declined","trace_id":"4bf92f35…"}

Queryable fields, a trace ID for correlation, no PAN.

3Storage Models and Cost

Backend styleIndexesQueryCost profile
full-text indexed (Elasticsearch/OpenSearch, Splunk)every field/termfast arbitrary searchhigh storage + RAM for indexes
label-indexed (Loki)only a few labels (app, namespace, level); content scanned at query timefast for label filters, slower for broad text searchcheap: compressed chunks in object storage
managed cloud (CloudWatch Logs)per log group, Insights scansad-hoc queries billed per GB scannedingest + storage + query billed

Log volume is usually the biggest observability bill. Control it with:

  • levels: info in prod; debug only temporarily/targeted
  • sampling of repetitive success logs (keep 100% of errors)
  • dropping noisy health-check/access logs at the agent
  • tiered retention: hot (7–14 days, searchable) → warm/cold → archive (object storage, months/years for compliance)
  • metrics instead of logs for counts and latencies (02-metrics/)

4Multiline, Parsing and Gotchas

  • Stack traces span many lines; log them as one JSON field ("stack": "...") rather than relying on multiline regexes at the agent.
  • Mixed formats (JSON + plain text from a library) need fallback parsing — standardize the logger.
  • Clock skew between nodes reorders lines; trust per-event timestamps from the app, and NTP everywhere.
  • Back-pressure: when the backend is down, agents buffer to disk and then drop — monitor agent buffer usage and dropped-record counters.
  • Cardinality in label-indexed stores: never use request IDs or user IDs as Loki labels (same rule as metrics).

5Security and Compliance

  • Logs are a data store: PII and secrets in logs are a breach waiting to happen. Redact at the source and at the agent.
  • Access control per team/namespace; audit who queried what for sensitive logs.
  • Audit logs (who did what) have different retention and integrity requirements (append-only, tamper-evident) than debug logs.
  • Data residency: logs from EU users may need to stay in the EU.
Under the HoodWhy Loki Is Cheap and Elasticsearch Is Fast▾

Elasticsearch builds an inverted index (term → list of document IDs) for every field, using Lucene segments that are merged in the background. Any word in any field can be found in milliseconds — but the index is often as large as the raw data, must live on fast disks with plenty of RAM, and ingestion pays the indexing CPU cost for every line.

Loki indexes only the label set of each stream (e.g. {app="checkout", namespace="prod", level="error"}). Log lines of a stream are appended to compressed chunks stored in object storage. A query first selects streams by labels via the small index, then scans (decompresses and greps) the chunks in the time range — brute force, parallelized across queriers. Ingestion is cheap and storage costs object-storage prices; queries that can't narrow by labels and time are slow. Hence the design rule: few, low-cardinality labels; everything else in the line.

Applications write JSON to stdout; a node agent tails container log files, parses, enriches with Kubernetes metadata, redacts and buffers, then ships to a backend with hot, warm and archive retention tiers queried by trace id and labels
Applications write JSON to stdout; a node agent tails container log files, parses, enriches with Kubernetes metadata, redacts and buffers, then ships to a backend with hot, warm and archive retention tiers queried by trace id and labels

⚠️ Common Pitfalls

  1. Writing log files inside containers — lost on restart, invisible to the agent.
  2. No common schema — every team's logs need different queries.
  3. Infinite retention by default — runaway cost.
  4. High-cardinality labels in Loki / mapping explosions in Elasticsearch (dynamic fields per user).
  5. Secrets/PII in logs.
  6. Not monitoring the logging pipeline itself — silent drops during incidents, exactly when you need logs.

📋 Quick Reference

text
app → stdout JSON → node agent (parse, enrich, redact, buffer) → backend → query/alerts → archive
common schema: timestamp, level, service, version, env, trace_id, message, fields
cost: levels, sampling, drop noise, tiered retention, metrics for counts
Loki: few labels + scan · Elasticsearch: index everything

🧠 Key takeaways

  • Emit structured JSON to stdout with a consistent schema (service, level, trace_id…).
  • Collect with agents, process (parse, redact, enrich, drop noise) before storing.
  • Cost = bytes × retention: tier hot vs archive; Loki indexes labels (cheap), Elasticsearch indexes content (fast search).
  • Never log secrets/PII; restrict access; correlate with trace IDs.

🎤 Interview Q&A

Questions interviewers ask about this topic. Answer out loud first, then open a card to compare.

Q1What makes logs useful in production?core▾

Structured format (JSON), consistent fields (timestamp, level, service, trace ID), meaningful messages with context, appropriate levels, centralized collection and search, and retention policies.

Follow-ups interviewers ask
  • Why trace IDs? To correlate logs across services for one request.
Q2How do logs get from containers to a central system?core▾

Apps write to stdout/stderr; the runtime stores them on the node; a log agent (Fluent Bit, Vector, Promtail, CloudWatch agent) tails, enriches with metadata (pod, namespace) and ships to Elasticsearch/OpenSearch, Loki, CloudWatch or a SaaS.

Follow-ups interviewers ask
  • Why stdout rather than files? 12-factor: the platform handles routing and rotation.
Q3How do you manage log volume and cost?senior▾

Use appropriate levels, sample noisy logs, drop health-check logs, avoid logging payloads, set retention tiers, and convert frequent counts into metrics.

Follow-ups interviewers ask
  • Loki vs Elasticsearch? Loki indexes labels only (cheaper); Elasticsearch indexes full text (powerful, costlier).
Q4What must never appear in logs?core▾

Passwords, tokens, API keys, session IDs, full card numbers, and unnecessary personal data. Use redaction and review logging in code review.

Follow-ups interviewers ask
  • Why? Logs are broadly accessible and retained, creating compliance and security risks.
Q5Logs vs metrics vs traces: when to use each?core▾

Metrics for trends and alerting (cheap aggregates), traces for latency and flow across services, logs for detailed context about specific events and errors.

Follow-ups interviewers ask
  • Which is cheapest at high volume? Metrics.

🛠️ Practice exercises

Each exercise is a file in this topic folder. Code exercises are self-checking: run them and make the checks pass.

✅ Check yourself

Answer the questions — feedback is instant.

1. Where should containerized apps write logs?
Agents collect them.
2. Why redact in the pipeline, before storage?
Prevent it as early as possible.
3. Loki is cheaper than Elasticsearch mainly because…
Full-text search costs index space.
4. What field links a log line to a distributed trace?
Correlation across signals.