Design a Logger with Independent Handlers

Quick Overview

Design a logging library with independent handlers, immutable records, isolated failures, bounded backpressure, and safe runtime reconfiguration.

Design a Logger with Independent Handlers

Company: Rippling

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Technical Screen

# Design a Logger with Independent Handlers Design a logging library in which each handler is independent. A logger may dispatch one record to console, file, remote, or future handlers, but a handler owns its own filtering, formatting, buffering, failures, and lifecycle. Adding or removing one handler must not require changes to the others. ### Constraints & Assumptions - A log record contains timestamp, severity, message, logger name, and structured fields. - Handlers may be synchronous or asynchronous. - A slow or failed remote handler must not corrupt another handler's output. - Configuration can change while the process is running. - Recursive logging from inside a handler must be controlled. ### Clarifying Questions to Ask - Is ordering required globally, per logger, or per handler? - May a handler drop records under pressure? - What flush and shutdown guarantees are required? - How should handler failures be surfaced to the application? ### Part 1 - Interfaces and ownership Define logger, record, filter, formatter, and handler contracts. State which component owns mutable state and lifecycle. #### What This Part Should Cover - Immutable records at the dispatch boundary - Handler-local filter, formatter, and sink - Open extension without logger type checks - Explicit start, flush, close, and error behavior ### Part 2 - Isolation and concurrency Explain dispatch, asynchronous queues, backpressure, ordering, exception isolation, and recursion protection. #### What This Part Should Cover - One handler cannot mutate another's view - Bounded queues and documented overflow policy - Per-handler ordering semantics - Failure reporting outside the normal logging path ### Part 3 - Configuration and testing Describe safe handler replacement and tests for independent behavior, overload, shutdown, and partial failure. #### What This Part Should Cover - Atomic configuration snapshots - Graceful drain and resource ownership - Fault-injection and concurrency tests - Metrics for drops, lag, and sink errors ```hint Dispatch an immutable record Independence is much easier when handlers receive the same immutable value and cannot modify shared formatting or sink state. ``` ### What a Strong Answer Covers - Narrow handler interfaces with clear ownership and lifecycle - Isolation of state, failures, formatting, and backpressure - Deterministic ordering and shutdown guarantees - Runtime configuration plus tests that force one handler to fail or stall ### Follow-up Questions 1. How would you prevent an error reported by a handler from recursively entering that handler? 2. What does `flush` mean for an asynchronous remote handler? 3. How can configuration be replaced without losing records or using a closed sink?

Quick Answer: Design a logging library with independent handlers, immutable records, isolated failures, bounded backpressure, and safe runtime reconfiguration.

|Home/Software Engineering Fundamentals/Rippling
Rippling logo
Rippling
Aug 21, 2026
mediumSoftware EngineerTechnical ScreenSoftware Engineering Fundamentals
4
0

Design a Logger with Independent Handlers

Design a logging library in which each handler is independent. A logger may dispatch one record to console, file, remote, or future handlers, but a handler owns its own filtering, formatting, buffering, failures, and lifecycle. Adding or removing one handler must not require changes to the others.

Constraints & Assumptions

  • A log record contains timestamp, severity, message, logger name, and structured fields.
  • Handlers may be synchronous or asynchronous.
  • A slow or failed remote handler must not corrupt another handler's output.
  • Configuration can change while the process is running.
  • Recursive logging from inside a handler must be controlled.

Clarifying Questions to Ask Guidance

  • Is ordering required globally, per logger, or per handler?
  • May a handler drop records under pressure?
  • What flush and shutdown guarantees are required?
  • How should handler failures be surfaced to the application?

Part 1 - Interfaces and ownership

Define logger, record, filter, formatter, and handler contracts. State which component owns mutable state and lifecycle.

What This Part Should Cover Guidance

  • Immutable records at the dispatch boundary
  • Handler-local filter, formatter, and sink
  • Open extension without logger type checks
  • Explicit start, flush, close, and error behavior

Part 2 - Isolation and concurrency

Explain dispatch, asynchronous queues, backpressure, ordering, exception isolation, and recursion protection.

What This Part Should Cover Guidance

  • One handler cannot mutate another's view
  • Bounded queues and documented overflow policy
  • Per-handler ordering semantics
  • Failure reporting outside the normal logging path

Part 3 - Configuration and testing

Describe safe handler replacement and tests for independent behavior, overload, shutdown, and partial failure.

What This Part Should Cover Guidance

  • Atomic configuration snapshots
  • Graceful drain and resource ownership
  • Fault-injection and concurrency tests
  • Metrics for drops, lag, and sink errors

What a Strong Answer Covers Guidance

  • Narrow handler interfaces with clear ownership and lifecycle
  • Isolation of state, failures, formatting, and backpressure
  • Deterministic ordering and shutdown guarantees
  • Runtime configuration plus tests that force one handler to fail or stall

Follow-up Questions Guidance

  1. How would you prevent an error reported by a handler from recursively entering that handler?
  2. What does flush mean for an asynchronous remote handler?
  3. How can configuration be replaced without losing records or using a closed sink?
Loading comments...