Skip to content
Low Level Design Mastery Logo
LowLevelDesign Mastery

Designing a Logging Framework

Design a flexible logging framework that supports multiple log levels, different output destinations, and various formatting strategies.

Design a flexible logging framework that supports multiple log levels, different output destinations, and various formatting strategies. It must work safely when multiple threads log at the same time, without mixing up or losing log messages.

In this problem, you’ll build a framework that processes log messages through a pipeline of filters and handlers, ensuring high performance even under high concurrency.


Design a logging utility that allows developers to record application events with different severity levels and route them to various destinations.

Functional Requirements:

  • Log Levels: Support DEBUG, INFO, WARNING, ERROR, and FATAL severities.
  • Rich Metadata: Include timestamp, log level, message, thread name, and logger name in every record.
  • Multi-Destination: Route logs to Console, File, or Database simultaneously.
  • Configurability: Enable/disable log levels per logger; configure output destinations dynamically.
  • Custom Formatting: Support different strategies (e.g., Simple Text, JSON) for different destinations.
  • Thread Safety: Ensure logs aren’t garbled or lost when multiple threads log concurrently.

Non-Functional Requirements:

  • Clean OOD: Well-defined roles for Loggers, Handlers, Formatters, and Filters.
  • Open-Closed Principle: Easily add new log levels or output sinks without modifying core code.
  • Performance: Low latency—the logging process should not block the main application.
  • Chain of Responsibility: Use this pattern to allow logs to be processed by multiple handlers in sequence.
  • Maintainability: The core logging logic should be easy to test, understand, and maintain.

The framework follows a modular pipeline: Logger → Filter → Handler → Formatter.

Diagram
classDiagram
    class Logger {
        <<Singleton>>
        -LogLevel level
        -List~Handler~ handlers
        +log(level, msg)
        +addHandler(handler)
    }
    
    class Handler {
        <<abstract>>
        -LogLevel level
        -Formatter formatter
        +publish(logRecord)*
    }
    
    class ConsoleHandler {
        +publish()
    }
    
    class FileHandler {
        +publish()
    }

    class Formatter {
        <<interface>>
        +format(logRecord) String
    }

    Logger o-- Handler
    Handler --> Formatter
    Handler <|-- ConsoleHandler
    Handler <|-- FileHandler

Diagram

A user might want to log to the console AND a file at the same time. Hardcoding this in the Logger class violates the Single Responsibility Principle.

Solution: Use the Chain of Responsibility (or an Observer-like list of Handlers). The Logger simply broadcasts the message to a list of Appenders. Each Appender knows how to handle its specific destination.

Different destinations need different formats (e.g., a simple string for the console but JSON for an ELK stack).

Solution: Use the Strategy Pattern. Each Handler is injected with a Formatter strategy. This allows you to mix and match handlers and formats dynamically (e.g., a FileHandler with a JSONFormatter).

If multiple threads write to the same file at once, the logs will get garbled. If the file system is slow, it could hang the entire application.

Solution: Use Asynchronous Logging. The Logger puts the log message into a thread-safe BlockingQueue, and a background thread consumes the queue and writes to the destinations. This keeps the main application thread fast.


By solving this problem, you’ll master:

  • Pipeline Architecture - Building extensible processing stages.
  • Decoupling - Separating log generation from log destination.
  • Concurrency Patterns - Safe resource access across threads.
  • SOLID Principles - Designing for long-term maintainability.

Ready to see the full implementation? Open the interactive playground to access:

  • 🎯 Step-by-step guidance through the 8-step LLD approach
  • 📊 Interactive UML builder to visualize your design
  • 💻 Complete Code Solutions in Python, Java, C++, TypeScript, JavaScript, C#
  • 🤖 AI-powered review of your design and code

After mastering the Logging Framework, try these similar problems: