IMPLEMENTATION QUALITY / OBJECT DESIGN BRIEF

Logging and observability

Logging and observability at the code level means designing classes so their behavior can be understood in production: structured logs with context (orderId, userId, traceId), appropriate levels (DEBUG, INFO, WARN, ERROR), metrics for counts and latency, and tracing spans around important operations.

IntermediatePhase 07 / Topic 8 of 8ResponsibilitiesCollaborationsExtensibility
01

Overview

Logging and observability at the code level means designing classes so their behavior can be understood in production: structured logs with context (orderId, userId, traceId), appropriate levels (DEBUG, INFO, WARN, ERROR), metrics for counts and latency, and tracing spans around important operations. Good logs explain what happened without a debugger.

Design-wise, logging is a cross-cutting concern: inject a logger interface, use decorators or middleware for common instrumentation, never log secrets or personal data, and keep log statements meaningful. In LLD discussions, mentioning audit logs (who did what), metrics for key actions, and correlation IDs shows production awareness.

A ship's logbook

The crew records position, weather, and important events with timestamps. When something goes wrong, the log reconstructs what happened. Writing 'something happened' every minute would be useless noise.

02

When to use it

  • Any code running in production.
  • Audit requirements (payments, admin actions).
  • Debugging intermittent issues and performance.
03

Where it shows up in interviews

Production readiness

Recognize it when: 'how would you debug this in production?'

  • Design a payment processor
  • Design a task scheduler
  • Design a rate limiter
04

Where it is used in real software

SLF4J, Logback, Pino, Winston

Structured logging libraries with levels and JSON output.

OpenTelemetry

Standard APIs for traces, metrics, and log correlation.

MDC (Mapped Diagnostic Context)

Attaches request IDs to every log line in a thread or async context.

05

Key terms

Structured logging
Key-value or JSON logs, machine-queryable.
Log levels
DEBUG, INFO, WARN, ERROR by severity.
Correlation ID
ID linking all logs of one request.
Audit log
Immutable record of who did what and when.
PII redaction
Removing personal data from logs.
06

How it works, step by step

  1. 1
    Inject a logger

    Via constructor or a framework factory.

  2. 2
    Log events, not narration

    'order placed' with orderId and total.

  3. 3
    Choose levels carefully

    ERROR for failures needing attention; INFO for business events.

  4. 4
    Attach context

    traceId, userId (not secrets).

  5. 5
    Add metrics and spans

    Counters for outcomes, histograms for latency.

07

Useful vs noisy logs

Payment processing

Step 1 / 4
Log lineQualityWhy
'here 1', 'here 2'BadNo meaning or context
'payment failed'WeakWhich payment? Why?
{event: 'payment_declined', orderId, reason: 'insufficient_funds', amountCents}GoodQueryable and actionable
{card: '4111 1111 1111 1111'}DangerousNever log card numbers or secrets

NOWLog line: 'here 1', 'here 2' | Quality: Bad | Why: No meaning or context

Structured, contextual, and safe logs turn production debugging from guesswork into queries.

08

Implementation

interface Logger {  info(event: string, fields?: Record<string, unknown>): void;  error(event: string, fields?: Record<string, unknown>): void;  child(fields: Record<string, unknown>): Logger;} const REDACT = new Set(["password", "cardNumber", "token"]);const jsonLogger = (base: Record<string, unknown> = {}): Logger => {  const write = (level: string, event: string, fields: Record<string, unknown> = {}) => {    const safe = Object.fromEntries(Object.entries({ ...base, ...fields }).map(([k, v]) => [k, REDACT.has(k) ? "[redacted]" : v]));    console.log(JSON.stringify({ ts: new Date().toISOString(), level, event, ...safe }));  };  return {    info: (e, f) => write("info", e, f),    error: (e, f) => write("error", e, f),    child: (f) => jsonLogger({ ...base, ...f }),  };}; class PaymentProcessor {  constructor(private gateway: PaymentGateway, private log: Logger) {}  async pay(orderId: string, amountCents: number) {    const log = this.log.child({ orderId });    const start = performance.now();    try {      const res = await this.gateway.charge(orderId, amountCents);      log.info("payment_succeeded", { amountCents, ms: Math.round(performance.now() - start) });      return res;    } catch (e) {      log.error("payment_failed", { amountCents, reason: (e as Error).message });      throw e;    }  }}
09

Complexity and performance

Log callMicroseconds

Async appenders keep it off the hot path.

Storage costProportional to volume

Sample DEBUG logs.

10

Trade-offs

Detail vs cost and noise

More logs aid debugging but cost storage and bury signals; log business events and failures, sample the rest.

Sync vs async logging

Async appenders reduce latency but can drop logs on crash.

11

Variants and related techniques

Audit trail

Separate durable, append-only log for compliance.

Decorator-based instrumentation

Wrap services with logging and metrics decorators.

12

Common mistakes

  • Logging secrets, tokens, or personal data.

    Fix: Redact centrally and review log fields.

  • String concatenation at DEBUG level.

    Fix: Use parameterized logging to avoid building unused strings.

  • Logging and rethrowing at every layer.

    Fix: Log once where the error is handled.

13

Interview questions

How do you design logging for an LLD component?

Inject a logger, emit structured events for key business actions and failures with IDs and context, use proper levels, redact sensitive fields, add metrics for counts and latency, and propagate a correlation ID.

Why structured logs?

Key-value logs can be filtered, aggregated, and alerted on reliably (for example count of payment_failed by reason), while free-text logs require fragile parsing.

14

Practice problems

ProblemDifficultyWhat it trains
Add structured logging to a booking serviceEasyEvents and context.
Build a logging decorator with timing metricsMediumCross-cutting concern.