Skip to content

Ezpl

Thread-safe singleton entry point for console/file logging orchestration and compatibility hooks.

🔍 API

Ezpl

Main logging singleton for the Ezpl framework.

Ezpl provides a unified, thread-safe interface for console and file logging with advanced features including indentation management, pattern-based logging, and dynamic progress bars. It implements the Singleton pattern to ensure only one instance exists throughout the application lifecycle.

Attributes:

Name Type Description
_instance Ezpl | None

The singleton instance of Ezpl

_lock RLock

Thread lock for synchronized access

_config_locked bool

Whether configuration can be modified

_log_file Path

Path to the log file

_printer EzPrinter

Console output handler

_logger EzLogger

File logging handler

_config_manager ConfigurationManager

Configuration manager instance

Note

Once initialized, Ezpl cannot be re-configured unless reset. Access it via the singleton pattern or module-level functions.

Example

log = Ezpl() log.printer.log("INFO", "Application started") log.logger.log("INFO", "Starting logging to file")

Attributes

printer_level property

printer_level: str

Return the current printer logging level.

logger_level property

logger_level: str

Return the current file logger logging level.

Functions

is_initialized classmethod

is_initialized() -> bool

Return True if the Ezpl singleton has already been created.

Useful for libraries that want to know whether they are the first to initialize Ezpl or if they should avoid re-configuring it.

get_printer

get_printer() -> EzPrinter

Returns the EzPrinter instance.

Returns:

* EzPrinter: The console printer instance providing info(), debug(), success(), etc.
    Implements PrinterProtocol for type safety.

get_logger

get_logger() -> EzLogger

Returns the EzLogger instance.

Returns:

* EzLogger: The file logger instance for file logging.
    Use logger.info(), logger.debug(), etc. directly.
    For advanced loguru features, use logger.get_loguru()
    Implements LoggerProtocol for type safety.

set_level

set_level(level: str) -> None

Set the log level for both the printer and the logger simultaneously.

Args:

* `level` (str): The desired log level (e.g., "INFO", "WARNING").

Returns:

* `None`.

set_printer_level

set_printer_level(level: str) -> None

Set the log level for the printer only.

Args:

* `level` (str): The desired log level for the printer.

Returns:

* `None`.

set_logger_level

set_logger_level(level: str) -> None

Set the log level for the file logger only.

Args:

* `level` (str): The desired log level for the file logger.

Returns:

* `None`.

debug

debug(message: Any) -> None

Log a debug message to the console printer.

info

info(message: Any) -> None

Log an info message to the console printer.

success

success(message: Any) -> None

Log a success message to the console printer.

warning

warning(message: Any) -> None

Log a warning message to the console printer.

error

error(message: Any) -> None

Log an error message to the console printer.

critical

critical(message: Any) -> None

Log a critical message to the console printer.

add_separator

add_separator() -> None

Adds a separator to the log file.

Returns:

* `None`.

manage_indent

manage_indent() -> Generator[None, None, None]

Context manager to manage indentation level.

Returns:

* `None`.

reset classmethod

reset() -> None

Reset the singleton instance (useful for testing).

Warning: This will destroy the current instance and all its state.

set_compatibility_hooks

set_compatibility_hooks(*, hook_logger: bool = True, hook_printer: bool = True, logger_names: list[str] | None = None) -> None

Configure compatibility hooks between Ezpl and classic logging/lib_mode.

Parameters:

Name Type Description Default
hook_logger bool

If True, bridge stdlib logging records to Ezpl. If False, remove previously installed stdlib bridges.

True
hook_printer bool

If True, ezpl.lib_mode.get_printer() delegates to Ezpl's real printer once initialized. If False, it stays silent.

True
logger_names list[str] | None

Optional stdlib logger names to hook explicitly. When omitted, root logger is targeted.

None
Notes
  • This method is safe to call multiple times (idempotent behavior).
  • Hooking named loggers is useful for libraries with propagate=False.

lock_config classmethod

lock_config() -> str

Lock Ezpl configuration so that future configure() and set_level() calls are blocked until unlock_config(token) is called.

Intended usage
  1. Root application configures Ezpl once
  2. Calls token = Ezpl.lock_config()
  3. Stores the token; libraries cannot reconfigure Ezpl without it

Returns:

Name Type Description
str str

A token required to unlock the configuration later.

unlock_config classmethod

unlock_config(token: str) -> bool

Unlock Ezpl configuration.

Parameters:

Name Type Description Default
token str

The token returned by lock_config(). Must match exactly.

required

Returns:

Type Description
bool

True if unlocked successfully, False if the token is wrong.

is_locked classmethod

is_locked() -> bool

Return True if the configuration is currently locked.

is_lib_printer_hook_enabled classmethod

is_lib_printer_hook_enabled() -> bool

Return True when lib_mode printer proxy is allowed to delegate.

set_log_file

set_log_file(log_file: Path | str) -> None

Change the log file (requires reinitialization of the logger).

Parameters:

Name Type Description Default
log_file Path | str

New path to the log file

required

Note: This will reinitialize the file logger but keep the singleton instance.

get_log_file

get_log_file() -> Path

Get the current log file path.

Returns:

Type Description
Path

Path to the current log file

get_config

get_config() -> ConfigurationManager

Get the current configuration manager.

Returns:

Type Description
ConfigurationManager

ConfigurationManager instance for accessing and modifying configuration

set_printer_class

set_printer_class(printer_class: type[EzPrinter] | EzPrinter, **init_kwargs: Any) -> None

Replace the current printer with a custom printer class or instance.

Allows users to override the default printer with a custom class that inherits from EzPrinter. The method preserves current configuration values (level, indentation settings) unless explicitly overridden in init_kwargs.

Parameters:

Name Type Description Default
printer_class type[EzPrinter] | EzPrinter

Custom printer class inheriting from EzPrinter, or an already instantiated EzPrinter instance

required
**init_kwargs Any

Optional initialization parameters for the printer class. If not provided, current configuration values are used.

{}

Raises:

Type Description
TypeError

If printer_class is not a valid class or instance

ValidationError

If initialization parameters are invalid

Example

from ezpl import Ezpl, EzPrinter

class CustomPrinter(EzPrinter): ... def info(self, message): ... super().info(f"[CUSTOM] {message}")

ezpl = Ezpl() ezpl.set_printer_class(CustomPrinter, level="DEBUG") ezpl.get_printer().info("Test") [CUSTOM] Test

set_logger_class

set_logger_class(logger_class: type[EzLogger] | EzLogger, **init_kwargs: Any) -> None

Replace the current logger with a custom logger class or instance.

Allows users to override the default logger with a custom class that inherits from EzLogger. The method preserves current configuration values (level, rotation, retention, compression) unless explicitly overridden in init_kwargs.

Parameters:

Name Type Description Default
logger_class type[EzLogger] | EzLogger

Custom logger class inheriting from EzLogger, or an already instantiated EzLogger instance

required
**init_kwargs Any

Optional initialization parameters for the logger class. If not provided, current configuration values are used.

{}

Raises:

Type Description
TypeError

If logger_class is not a valid class or instance

ValidationError

If initialization parameters are invalid

FileOperationError

If file operations fail during logger creation (may be raised by the logger class constructor)

Example

from ezpl import Ezpl, EzLogger

class CustomLogger(EzLogger): ... def info(self, message): ... super().info(f"[CUSTOM LOG] {message}")

ezpl = Ezpl() ezpl.set_logger_class(CustomLogger, log_file="custom.log") ezpl.get_logger().info("Test")

reload_config

reload_config() -> None

Reload configuration from file and environment variables.

This method reloads the configuration and reapplies it to handlers. Useful when environment variables or the config file have changed after the singleton was initialized.

Note: This will reinitialize handlers with the new configuration.

configure

configure(config_dict: dict[str, Any] | None = None, *, persist: bool = False, **kwargs: Any) -> bool

Configure Ezpl dynamically.

Parameters:

Name Type Description Default
config_dict dict[str, Any] | None

Dictionary of configuration values to update

None
persist bool

If True, write changes to ~/.ezpl/config.json so they survive future runs. Defaults to False (in-memory only).

False
**kwargs Any

Configuration options (alternative to config_dict): - log_file or log-file: Path to log file - printer_level or printer-level: Printer log level - file_logger_level or file-logger-level: File logger level - level or log-level: Set both printer and logger level - log_rotation or log-rotation: Rotation setting (e.g., "10 MB", "1 day") - log_retention or log-retention: Retention period (e.g., "7 days") - log_compression or log-compression: Compression format (e.g., "zip", "gz") - indent_step or indent-step: Indentation step size - indent_symbol or indent-symbol: Symbol for indentation - base_indent_symbol or base-indent-symbol: Base indentation symbol

{}

Returns:

Type Description
bool

True if configuration was applied, False if it was blocked by lock.