Core Logging Module¶
Package: structum-core (modules structum.logging)
Status: Core Protocol
Dependencies: Zero (Python Standard Library only)
Overview¶
[!NOTE] Architectural Role: This module is part of the Foundation Layer.
See Enterprise Architecture Guide for the full architectural map.
The Core Logging module defines the Logging Protocols that all Structum applications use. It provides zero-dependency interfaces that allow applications to log without caring about the underlying implementation (stdout, file, JSON, ELK, etc.).
By coding against these interfaces, your application remains:
Testable: Easy to mock logging in unit tests
Portable: No hard dependencies on specific libraries
Modular: The logging backend can be swapped at any time
LoggerInterface¶
The primary contract is the LoggerInterface protocol. It extends standard Python logging with support for structured context (**kwargs).
class LoggerInterface(Protocol):
def debug(self, message: str, **kwargs: Any) -> None: ...
def info(self, message: str, **kwargs: Any) -> None: ...
def warning(self, message: str, **kwargs: Any) -> None: ...
def error(self, message: str, **kwargs: Any) -> None: ...
def critical(self, message: str, **kwargs: Any) -> None: ...
Key Features¶
StructuredByDefault: All methods accept arbitrary keyword arguments.
Runtime Checkable: Supports
isinstance(logger, LoggerInterface).Type Safe: Fully typed for Mypy compliance.
Usage¶
Getting a Logger¶
Use the global factory function to get a logger conforming to the interface.
from structum.logging import get_logger
# Returns a logger implementing LoggerInterface
logger = get_logger(__name__)
Logging Structured Data¶
Do not format strings! Pass data as keyword arguments.
✅ DO:
logger.info("user_login", user_id=123, status="success")
❌ DON’T:
# Bad: Hard to parse, hard to index
logger.info(f"User {123} logged in with status success")
Exception Logging¶
Pass exc_info=True to include stack traces.
try:
risky_operation()
except Exception:
logger.error("operation_failed", exc_info=True)
Architecture: Core vs. Plugin¶
Feature |
Core Logging ( |
Observability Plugin ( |
|---|---|---|
Role |
Interface definition |
Implementation |
Dependencies |
None (stdlib) |
|
Output |
Basic console (fallback) |
JSON, Colors, Context Propagation |
Context |
Definitions only |
full |
[!TIP] Use the Core interface in your business logic.
Only use the Plugin when you need to configure the backend or use advanced observability features like tracing context injection.
Extending¶
To create a custom logging backend, implement the protocol:
from structum.logging.interfaces import LoggerInterface
class MyCustomLogger(LoggerInterface):
def info(self, message: str, **kwargs: Any) -> None:
print(f"[MYLOG] {message} {kwargs}")
# ... implement other methods