Source code for mylogging.misc.misc_module

"""Module with functions for misc subpackage."""
from __future__ import annotations
from typing import Callable, Any, Union
import warnings
from pathlib import Path
import logging
from dataclasses import dataclass
import traceback as traceback_py_module
import sys

from ..my_logging import my_logger
from ..internal_module import filter_out
from ..config_module import config


[docs]@dataclass class RedirectedLogsAndWarnings: """Helper so resetting the original behavior is simple.""" logs: list[logging.LogRecord] warnings: list[dict[str, Any]] showwarning_backup: Callable output_backup: Union[str, Path, None] stream_backup: Any
[docs] def close_redirect(self): """Stop saving logs and warnings to lists. Restoring original logs and warnings if necessary.""" warnings.showwarning = self.showwarning_backup if self.output_backup: config.output = self.output_backup if self.output_backup: config.stream = self.stream_backup config.to_list = None
[docs]def redirect_logs_and_warnings( used_logs: list[logging.LogRecord], used_warnings: list, keep_logs_and_warnings: bool = True ) -> RedirectedLogsAndWarnings: """For example if using many processes with multiprocessing, it may be beneficial to log from one place. It's possible to log to variables (logs as well as warnings), pass it to the main process and then log it with workings filter etc. To log stored logs and warnings, use Args: used_logs (list): List where logs will be stored used_warnings (list): List where warnings will be stored keep_logs_and_warnings (bool, optional): If False, warnings and logs will be silenced. Default to True. Returns: RedirectedLogsAndWarnings: Object, where you can reset redirect. Logs and warnings you already have from inserted parameters. """ showwarning_backup = warnings.showwarning def custom_warn(message, category, filename, lineno, file=None, line=None): used_warnings.append( { "message": message, "category": category, "filename": filename, "lineno": lineno, "file": file, "line": line, } ) if keep_logs_and_warnings: showwarning_backup(message, category, filename, lineno, file=None, line=None) warnings.showwarning = custom_warn if not keep_logs_and_warnings: output_backup = config.output stream_backup = config.stream config.output = None config.stream = None else: output_backup = None stream_backup = None config.to_list = used_logs return RedirectedLogsAndWarnings( logs=used_logs, warnings=used_warnings, showwarning_backup=showwarning_backup, output_backup=output_backup, stream_backup=stream_backup, )
[docs]def log_and_warn_from_lists(logs_list: None | list = None, warnings_list: None | list = None) -> None: """When logs and warnings was redirected to python lists. This can log it from the lists to file or console. Can be useful for example if using multiprocessing. Args: logs_list (None | list, optional): [description]. Defaults to None. warnings_list (None | list, optional): [description]. Defaults to None. Raises: RuntimeError: [description] """ if logs_list: for record in logs_list: for handler in my_logger.logger.handlers: if isinstance(handler, my_logger.SaveHandler): raise RuntimeError("\n\nYou have to close redirect before log from list.\n\n") if not filter_out(record.msg, "WARNING"): handler.emit(record) if warnings_list: for i in warnings_list: warnings.showwarning(**i)