Skip to content

Logger

psengine.logger.rf_logger.RFLogger

RFLogger(
    output: str = DEFAULT_PSENGINE_OUTPUT,
    root_output: str = DEFAULT_ROOT_OUTPUT,
    level: int = INFO,
    propagate: bool = True,
    to_file: bool = True,
    to_console: bool = True,
    console_is_root: bool = True,
)

Sets up logging and gives access to its functions.

Sets up console and/or file-based logging under a structured directory layout.

PARAMETER DESCRIPTION
output

Subdirectory name to use for output (e.g., psengine).

TYPE: str DEFAULT: DEFAULT_PSENGINE_OUTPUT

root_output

Root directory path for all output files.

TYPE: str DEFAULT: DEFAULT_ROOT_OUTPUT

level

Logging level (e.g., logging.INFO, logging.DEBUG).

TYPE: int DEFAULT: INFO

propagate

Whether logs should propagate to parent loggers.

TYPE: bool DEFAULT: True

to_file

Enable logging to a file.

TYPE: bool DEFAULT: True

to_console

Enable logging to the console.

TYPE: bool DEFAULT: True

console_is_root

Set console logger as root logger.

TYPE: bool DEFAULT: True

Source code in psengine/logger/rf_logger.py
def __init__(
    self,
    output: Annotated[
        str, Doc('Subdirectory name to use for output (e.g., `psengine`).')
    ] = DEFAULT_PSENGINE_OUTPUT,
    root_output: Annotated[
        str, Doc('Root directory path for all output files.')
    ] = DEFAULT_ROOT_OUTPUT,
    level: Annotated[
        int, Doc('Logging level (e.g., logging.INFO, logging.DEBUG).')
    ] = logging.INFO,
    propagate: Annotated[bool, Doc('Whether logs should propagate to parent loggers.')] = True,
    to_file: Annotated[bool, Doc('Enable logging to a file.')] = True,
    to_console: Annotated[bool, Doc('Enable logging to the console.')] = True,
    console_is_root: Annotated[bool, Doc('Set console logger as root logger.')] = True,
):
    """Initialize the logger for the application.

    Sets up console and/or file-based logging under a structured directory layout.
    """
    if to_file is False and to_console is False:
        raise ValueError('At least one of to_file or to_console must be set to True')

    if not isinstance(level, (str, int)):
        raise TypeError('level must be a string or int')
    if isinstance(level, str):
        level = level.upper()
        if level not in LOGGER_LEVEL:
            raise ValueError(f'level must be one of: {", ".join(LOGGER_LEVEL)}')
    if isinstance(level, int) and level not in LOGGER_LEVEL_INT:
        raise ValueError(f'level must be one of: {", ".join(LOGGER_LEVEL)}')

    # Setup logging handlers
    self.logger = logging.getLogger(LOGGER_NAME)
    root_logger = logging.getLogger()

    if to_file:
        psengine_file_handler = self._create_file_handler(output)
        root_file_handler = self._create_file_handler(root_output)
        self.logger.addHandler(psengine_file_handler)
        root_logger.addHandler(root_file_handler)

    if to_console:
        console_handler = self._create_console_handler()
        if console_is_root:
            root_logger.addHandler(console_handler)
        else:
            self.logger.addHandler(console_handler)

    # If false then logging messages are not passed to the handlers of ancestor loggers
    self.logger.propagate = propagate

    logging.captureWarnings(True)

    sys.excepthook = self._log_uncaught_exception

    self.logger.setLevel(level=level)
    self.logger.debug('Logger initialized')

logger instance-attribute

logger = getLogger(LOGGER_NAME)

get_logger

get_logger() -> Logger

Returns self.logger object.

Source code in psengine/logger/rf_logger.py
def get_logger(self) -> logging.Logger:
    """Returns self.logger object."""
    return self.logger