1. Introduction
- ConfigLoader for reading dict/JSON/YAML input.
- ConfigValidator for schema and dependency validation.
- LoggingConfigurator for stdlib handlers, structlog processors, async workers, and sink class instantiation.
2. Behavior and Context
In production deployments, logging setup must be deterministic and fail early on malformed configuration. This module enforces that behavior while allowing optional dependency-driven features (YAML, async HTTP, cloud sinks).
The sink ecosystem is wired through SINK_REGISTRY, mapping sink type keys (for example datadog, redis) to import paths for lazy runtime loading.
3. Purpose
- Input Flexibility: Supports dict, JSON file, YAML file.
- Schema Enforcement: Rejects invalid sink/type/field combinations.
- Runtime Wiring: Builds handlers, processors, workers, and sink instances.
- Extensibility: Registry-driven sink class loading.
4. High-Level API & Examples
Example 1: Load and Validate from YAML
from jazzmine.logging import ConfigLoader, ConfigValidator
cfg = ConfigLoader.load("logging.yml")
cfg = ConfigLoader.merge_defaults(cfg)
ConfigValidator.validate(cfg)Example 2: Build Runtime Components
from jazzmine.logging.config import LoggingConfigurator
cfg = {
"name": "orders",
"level": "INFO",
"json": True,
"sinks": [
{"type": "console"},
{"type": "http", "url": "https://logs.internal/ingest", "async": True},
{"type": "redis", "host": "localhost", "stream_key": "orders:logs"},
],
}
workers = LoggingConfigurator.create_async_workers(cfg)
sink_loggers = LoggingConfigurator.create_sink_loggers(cfg)
LoggingConfigurator.configure_stdlib(cfg)
LoggingConfigurator.configure_structlog(cfg, workers)5. Detailed Class Functionality
DEFAULTS
Default baseline config:
- name = "base"
- level = "INFO"
- json = True
- sinks = [{"type": "console"}]
SINK_REGISTRY
Maps sink type string to fully-qualified class path. This enables pluggable class resolution in create_sink_loggers via importlib.
ConfigLoader.load(raw)
- Accepts dict or path-like input.
- File path behavior:
- .json -> parsed by json.loads
- .yaml / .yml -> parsed by yaml.safe_load (requires pyyaml)
- unknown suffix -> attempts JSON, then YAML fallback
- Raises file/config/dependency errors on failures.
ConfigLoader.merge_defaults(cfg)
Shallow merge of user config into DEFAULTS, ensuring sinks remains explicitly user-controlled if provided.
ConfigValidator.validate(cfg)
Validates:
- name is string
- level is string
- json is bool
- sinks is a non-empty list
- each sink has type
- type is among built-in valid types
Additional sink checks:
- file sink requires path and verifies file path is creatable.
- http sink requires url; async mode requires aiohttp.
LoggingConfigurator.configure_stdlib(cfg)
- Resolves log level.
- Clears root handlers.
- Adds handlers for:
- console -> logging.StreamHandler
- file -> FileHandler or TimedRotatingFileHandler
- http -> custom SyncHTTPHandler
- Sets simple message formatter and root level.
LoggingConfigurator.configure_structlog(cfg, async_workers)
Builds processors:
- context vars merge
- timestamp
- level add
- stack info
- exception formatting
- optional async HTTP worker submit processor
- final renderer (JSONRenderer or console renderer)
Configures structlog filtering by configured level.
LoggingConfigurator.create_async_workers(cfg)
Creates AsyncHttpWorker instances for HTTP sinks where async = True. Worker ID includes sink index and URL to avoid duplicates.
LoggingConfigurator.create_sink_loggers(cfg)
- Skips console, file, and http (already handled by stdlib/structlog paths).
- Dynamically imports sink classes from SINK_REGISTRY.
- Instantiates each sink with common constructor contract.
- Warns and continues if sink initialization fails.
6. Error Handling
- LoggerFileError: missing config path or non-creatable file sink target.
- LoggerConfigError: malformed config or unsupported sink type.
- LoggerDependencyError: required optional package missing.
- Sink class import/instantiation failures in create_sink_loggers produce warnings and do not abort setup.
7. Remarks
- This module intentionally mixes strict validation (for config correctness) with lenient sink boot (for partial availability).
- For mission-critical sinks, consider enforcing hard-fail behavior when sink instantiation emits warnings.
- Extend SINK_REGISTRY to add new sink types without changing public APIs.