import logging import logging.config import os import yaml import zmq from control_backend.core.config import settings def add_logging_level(level_name: str, level_num: int, method_name: str | None = None) -> None: """ Adds a logging level to the `logging` module and the currently configured logging class. """ if not method_name: method_name = level_name.lower() if hasattr(logging, level_name): raise AttributeError(f"{level_name} already defined in logging module") if hasattr(logging, method_name): raise AttributeError(f"{method_name} already defined in logging module") if hasattr(logging.getLoggerClass(), method_name): raise AttributeError(f"{method_name} already defined in logger class") def log_for_level(self, message, *args, **kwargs): if self.isEnabledFor(level_num): self._log(level_num, message, args, **kwargs) def log_to_root(message, *args, **kwargs): logging.log(level_num, message, *args, **kwargs) logging.addLevelName(level_num, level_name) setattr(logging, level_name, level_num) setattr(logging.getLoggerClass(), method_name, log_for_level) setattr(logging, method_name, log_to_root) def setup_logging(path: str = ".logging_config.yaml") -> None: """ Setup logging configuration of the CB. Tries to load the logging configuration from a file, in which we specify custom loggers, formatters, handlers, etc. :param path: :return: """ if os.path.exists(path): with open(path) as f: try: config = yaml.safe_load(f.read()) except (AttributeError, yaml.YAMLError) as e: logging.warning(f"Could not load logging configuration: {e}") config = {} if "custom_levels" in config: for level_name, level_num in config["custom_levels"].items(): add_logging_level(level_name, level_num) if config.get("handlers") is not None and config.get("handlers").get("ui"): pub_socket = zmq.Context.instance().socket(zmq.PUB) pub_socket.connect(settings.zmq_settings.internal_pub_address) config["handlers"]["ui"]["interface_or_socket"] = pub_socket logging.config.dictConfig(config) else: logging.warning("Logging config file not found. Using default logging configuration.")