""" Логгер для всех сервисов """ import time import inspect from types import FrameType class Logger: """ Логгер для всех сервисов на python """ def __init__(self, prefix: str) -> None: self.__pref = prefix """Префикс для каждого частного логгера""" def __call__(self, msg: str) -> None: """Печатает сообщение отладки""" _pref = "" try: frame = inspect.currentframe() if isinstance(frame, FrameType): # Получаем фрейм вызывающей функции caller_frame: FrameType | None = frame.f_back if isinstance(caller_frame, FrameType): # Имя функции _pref = caller_frame.f_code.co_name del frame del caller_frame _pref = self.__pre(_pref) except TypeError: _pref = self.__pref + ": " print(f"DEBU {self.__now()} {_pref}{msg}") def debug(self, msg: str) -> None: """Печатает сообщение отладки""" _pref = "" try: frame = inspect.currentframe() if isinstance(frame, FrameType): # Получаем фрейм вызывающей функции caller_frame: FrameType | None = frame.f_back if isinstance(caller_frame, FrameType): # Имя функции _pref = caller_frame.f_code.co_name del frame del caller_frame _pref = self.__pre(_pref) except TypeError: _pref = self.__pref + ": " print(f"DEBU {self.__now()} {_pref}{msg}") def error(self, msg: str) -> None: """Печатает сообщение ошибки""" _pref = "" try: frame = inspect.currentframe() if isinstance(frame, FrameType): # Получаем фрейм вызывающей функции caller_frame: FrameType | None = frame.f_back if isinstance(caller_frame, FrameType): # Имя функции _pref = caller_frame.f_code.co_name del frame del caller_frame _pref = self.__pre(_pref) except TypeError: _pref = self.__pref + ": " print(f"ERRO {self.__now()} {_pref}{msg}") def warn(self, msg: str) -> None: """Печатает сообщение предупреждения""" _pref = "" try: frame = inspect.currentframe() if isinstance(frame, FrameType): # Получаем фрейм вызывающей функции caller_frame: FrameType | None = frame.f_back if isinstance(caller_frame, FrameType): # Имя функции _pref = caller_frame.f_code.co_name del frame del caller_frame _pref = self.__pre(_pref) except TypeError: _pref = self.__pref + ": " print(f"WARN {self.__now()} {_pref}{msg}") def __now(self) -> str: """Возвращает текущее время с миллисекундами в формате %Y-%m-%d %H:%M:%S.%f""" timestamp = time.time() ms = int(timestamp * 1000) % 1000 _time = f"%Y-%m-%d %H:%M:%S.{ms:03d}" return time.strftime(_time, time.localtime()) def __pre(self, fn_name: str) -> str: """Получить имя вызвавшей функции""" # Имя функции # Также можно получить: # - имя файла: caller_frame.f_code.co_filename # - номер строки: caller_frame.f_lineno # - локальные переменные: caller_frame.f_locals # Очищаем ссылки на фреймы (важно для сборки мусора) pref: str = self.__pref + "." + fn_name + "(): " return pref