1. Behavior and Context
Each sink adapter must implement four abstract methods:
- initialize()
- shutdown()
- log(level, msg, **kwargs)
- alog(level, msg, **kwargs)
The base class provides convenience wrappers (debug, info, etc.) and async equivalents (adebug, ainfo, etc.), all guarded by _should_log level checks.
2. Purpose
- Consistency: Uniform sink lifecycle across backends.
- Extensibility: New sinks only need transport-specific logic.
- Performance Control: Per-sink log-level threshold filtering.
3. High-Level API & Examples
Example 1: Minimal Custom Sink
python
from jazzmine.logging.sinks.base_sink import BaseSink
class PrintSink(BaseSink):
def initialize(self) -> None:
self._initialized = True
def shutdown(self) -> None:
pass
def log(self, level: str, msg: str, **kwargs) -> None:
if not self._initialized:
return
print(level.upper(), msg, kwargs)
async def alog(self, level: str, msg: str, **kwargs) -> None:
self.log(level, msg, **kwargs)Example 2: Per-Sink Level Override
python
sink = PrintSink(
sink_config={"type": "print", "level": "warning"},
logger_name="api",
level="INFO", # global default
use_json=True,
)
sink.initialize()
sink.info("ignored") # filtered out by sink-level threshold
sink.error("sent")4. Detailed Class Functionality
LEVEL_ORDER
Maps level names to numeric priority:
- debug: 10
- info: 20
- warning: 30
- error: 40
- critical: 50
__init__(sink_config, logger_name, level, use_json)
- Stores sink configuration and logger identity.
- Applies per-sink level override from sink_config['level'] when present.
- Tracks initialization state and computed level threshold.
Abstract Lifecycle / Transport Methods
Concrete sink implementations must provide:
- initialize
- shutdown
- log
- alog
_should_log(level)
Compares incoming level with sink threshold.
Convenience Methods
- sync: debug, info, warning, error, critical
- async: adebug, ainfo, awarning, aerror, acritical
All methods call _should_log before delegating to concrete transport methods.
5. Error Handling
The base class itself does not raise package-specific errors. Concrete sinks are responsible for dependency checks and transport exception handling.
6. Remarks
- Always call initialize() before use.
- For high-throughput systems, keep transport work out of sync methods where possible.
- New sinks should preserve fail-open behavior unless strict delivery is explicitly required.