NJ Municipality Lookup
CodebaseSrcAdapters

Logging

Implementations of the `LoggerPort` interface for structured logging.

Logging Adapters

Implementations of the LoggerPort interface for structured logging.

Purpose

Provides logging adapters that implement the domain's LoggerPort interface, enabling dependency injection and testability while supporting multiple logging backends.

Key Concepts

  • Port Implementation: All loggers implement LoggerPort from domain/ports/logger
  • Structured Context: Supports key-value pairs for enriched log entries
  • Level Filtering: Debug, info, warn, and error severity levels
  • Environment Adaptation: Different loggers for development vs production

Available Adapters

ConsoleLogger

Console-based logger for local development and environments without external logging services.

Features:

  • Colored terminal output with ANSI codes
  • ISO 8601 timestamps
  • JSON-formatted context
  • Configurable minimum log level
  • Optional custom prefix

Example:

import { createConsoleLogger } from "@/adapters/logging/console-logger";

const logger = createConsoleLogger({
  minLevel: "debug",
  colorize: true,
  prefix: "nj-geocoding",
});

logger.info("Address lookup completed", {
  address: "123 Main St",
  duration: 150,
});

Integration with Application

Loggers are injected into use cases and adapters through dependency injection:

import { createConsoleLogger } from "@/adapters";
import { createLookupAddressUseCase } from "@/domain/use-cases";

const logger = createConsoleLogger();
const lookupAddress = createLookupAddressUseCase(
  geocodingService,
  cache,
  logger,
);

Adding New Logger Adapters

To add a new logger (e.g., for CloudWatch Logs or file-based logging):

  1. Create new file implementing LoggerPort
  2. Export factory function
  3. Add to src/adapters/index.ts

Example:

import type { LoggerPort } from "@/domain/ports/logger";

export class FileLogger implements LoggerPort {
  debug(message: string, context?: Record<string, unknown>): void {
    // Write to file
  }
  // ... implement other methods
}

export function createFileLogger(config: FileLoggerConfig): LoggerPort {
  return new FileLogger(config);
}

On this page