Core Logging Protocols

Logging and Metrics interface for Structum.

This module acts as the Architectural Facade (DP-1) for observability. It provides: 1. Unified API: A consistent interface for logging and metrics regardless of the backend. 2. Operational Continuity: Fallback implementations (Adapters & Null Objects) that ensure the application runs even without plugins. 3. Zero Dependency: Pure stdlib implementations by default.

Plugins (like structum-observability) patch these objects at runtime to inject advanced behavior.

class structum.logging.StandardLoggerAdapter(logger: Logger)[source]

Bases: object

Fallback implementation that adapts standard logging.Logger to LoggerInterface.

Architectural Role: Operational Continuity (DP-2).

This class ensures that calls to log.info(…, user_id=123) do not crash when the advanced observability plugin is missing. It captures structured arguments (**kwargs) and places them into the ‘extra’ dictionary, creating a rudimentary structured logging experience compatible with standard tools.

__init__(logger: Logger)[source]

Initialize the adapter with a stdlib logger.

Parameters:
logger: Logger

The standard library Logger instance to wrap.

debug(message: str, **kwargs: Any) None[source]

Log a debug message.

info(message: str, **kwargs: Any) None[source]

Log an info message.

warning(message: str, **kwargs: Any) None[source]

Log a warning message.

error(message: str, **kwargs: Any) None[source]

Log an error message.

critical(message: str, **kwargs: Any) None[source]

Log a critical message.

structum.logging.get_logger(name: str) LoggerInterface[source]

Returns a logger instance conforming to LoggerInterface.

By default, this returns a StandardLoggerAdapter wrapping the stdlib logger. Plugins (like structum_observability) should patch this function to return their own implementation (e.g., a structlog BoundLogger).

class structum.logging.MetricsCollectorProtocol(*args, **kwargs)[source]

Bases: Protocol

Protocol defining the metrics collection interface.

Implementations should provide methods for incrementing counters and observing values (e.g., for histograms or gauges).

increment(metric: str, labels: dict[str, str] | None = None) None[source]

Increment a counter metric.

observe(metric: str, value: float, labels: dict[str, str] | None = None) None[source]

Observe a value for a histogram or gauge metric.

__init__(*args, **kwargs)
class structum.logging.NullMetrics[source]

Bases: object

Null Object implementation for metrics (fallback when no backend is configured).

Architectural Role: Operational Continuity (DP-2).

This class implements the MetricsCollectorProtocol but performs no actions. It allows application code to instrumentation itself (metrics.increment(…)) without checking if a metrics backend is actually installed.

increment(metric: str, labels: dict[str, str] | None = None) None[source]

No-op increment. Swallows the metric to prevent runtime errors.

observe(metric: str, value: float, labels: dict[str, str] | None = None) None[source]

No-op observe. Swallows the value to prevent runtime errors.

structum.logging.set_metrics_collector(collector: MetricsCollectorProtocol) None[source]

Permette ai plugin di registrare il proprio collettore di metriche.

structum.logging.configure_logging(level: str = 'INFO', format: str = 'json') None[source]

Combines basic logging configuration. Plugins should patch this to provide advanced setup.

structum.logging.get_logger_backend() str[source]

Returns the name of the active logging backend.

structum.logging.set_context(**kwargs: Any) None[source]

Sets global context variables (Fallback: No-op).

In the Core implementation, this is a No-Op. Context propagation requires the structum-observability plugin which implements contextvars management.

structum.logging.clear_context() None[source]

Clears global context variables (Fallback: No-op).

structum.logging.bind_context(**kwargs: Any)[source]

Context manager for temporary context (Fallback: yield).

Without the plugin, this simply yields control back to the caller without modifying any context, ensuring code compatibility.

Interfaces