migration refactor

This commit is contained in:
2025-08-16 12:29:37 +03:00
parent f368f5ced9
commit 0e2fc14732
16 changed files with 1977 additions and 2761 deletions

View File

@@ -1,9 +1,6 @@
# [MODULE] Superset Tool Logger Utility
# @contract: Этот модуль предоставляет утилиту для настройки логирования в приложении.
# @semantic_layers:
# - [CONFIG]: Настройка логгера.
# - [UTILITY]: Вспомогательные функции.
# @coherence: Модуль должен быть семантически когерентен со стандартной библиотекой `logging`.
# PURPOSE: Предоставляет стандартизированный класс-обертку `SupersetLogger` для настройки и использования логирования в проекте.
# COHERENCE: Модуль согласован со стандартной библиотекой `logging`, расширяя ее для нужд проекта.
import logging
import sys
@@ -11,8 +8,20 @@ from datetime import datetime
from pathlib import Path
from typing import Optional
# [CONSTANTS]
# CONTRACT:
# PURPOSE: Обеспечивает унифицированную настройку логгера с выводом в консоль и/или файл.
# PRECONDITIONS:
# - `name` должен быть строкой.
# - `level` должен быть валидным уровнем логирования (например, `logging.INFO`).
# POSTCONDITIONS:
# - Создает и настраивает логгер с указанным именем и уровнем.
# - Добавляет обработчики для вывода в файл (если указан `log_dir`) и в консоль (если `console=True`).
# - Очищает все предыдущие обработчики для данного логгера, чтобы избежать дублирования.
# PARAMETERS:
# - name: str - Имя логгера.
# - log_dir: Optional[Path] - Директория для сохранения лог-файлов.
# - level: int - Уровень логирования.
# - console: bool - Флаг для включения вывода в консоль.
class SupersetLogger:
def __init__(
self,
@@ -23,34 +32,40 @@ class SupersetLogger:
):
self.logger = logging.getLogger(name)
self.logger.setLevel(level)
formatter = logging.Formatter(
'%(asctime)s - %(levelname)s - %(message)s'
)
# Очищаем существующие обработчики
if self.logger.handlers:
for handler in self.logger.handlers[:]:
self.logger.removeHandler(handler)
# [ANCHOR] HANDLER_RESET
# Очищаем существующие обработчики, чтобы избежать дублирования вывода при повторной инициализации.
if self.logger.hasHandlers():
self.logger.handlers.clear()
# Файловый обработчик
# [ANCHOR] FILE_HANDLER
if log_dir:
log_dir.mkdir(parents=True, exist_ok=True)
timestamp = datetime.now().strftime("%Y%m%d")
file_handler = logging.FileHandler(
log_dir / f"{name}_{self._get_timestamp()}.log"
log_dir / f"{name}_{timestamp}.log", encoding='utf-8'
)
file_handler.setFormatter(formatter)
self.logger.addHandler(file_handler)
# Консольный обработчик
# [ANCHOR] CONSOLE_HANDLER
if console:
console_handler = logging.StreamHandler()
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(formatter)
self.logger.addHandler(console_handler)
# CONTRACT:
# PURPOSE: (HELPER) Генерирует строку с текущей датой для имени лог-файла.
# RETURN: str - Отформатированная дата (YYYYMMDD).
def _get_timestamp(self) -> str:
return datetime.now().strftime("%Y%m%d")
# END_FUNCTION__get_timestamp
# [INTERFACE] Методы логирования
def info(self, message: str, extra: Optional[dict] = None, exc_info: bool = False):
self.logger.info(message, extra=extra, exc_info=exc_info)
@@ -59,47 +74,15 @@ class SupersetLogger:
def warning(self, message: str, extra: Optional[dict] = None, exc_info: bool = False):
self.logger.warning(message, extra=extra, exc_info=exc_info)
def critical(self, message: str, extra: Optional[dict] = None, exc_info: bool = False):
self.logger.critical(message, extra=extra, exc_info=exc_info)
def debug(self, message: str, extra: Optional[dict] = None, exc_info: bool = False):
self.logger.debug(message, extra=extra, exc_info=exc_info)
def exception(self, message: str):
self.logger.exception(message)
def exception(self, message: str, *args, **kwargs):
self.logger.exception(message, *args, **kwargs)
# END_CLASS_SupersetLogger
def setup_logger(name: str, level: int = logging.INFO) -> logging.Logger:
# [FUNCTION] setup_logger
# [CONTRACT]
"""
Настраивает и возвращает логгер с заданным именем и уровнем.
@pre:
- `name` является непустой строкой.
- `level` является допустимым уровнем логирования из модуля `logging`.
@post:
- Возвращает настроенный экземпляр `logging.Logger`.
- Логгер имеет StreamHandler, выводящий в sys.stdout.
- Форматтер логгера включает время, уровень, имя и сообщение.
@side_effects:
- Создает и добавляет StreamHandler к логгеру.
@invariant:
- Логгер с тем же именем всегда возвращает один и тот же экземпляр.
"""
# [CONFIG] Настройка логгера
# [COHERENCE_CHECK_PASSED] Логика настройки соответствует описанию.
logger = logging.getLogger(name)
logger.setLevel(level)
# Создание форматтера
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(name)s - %(message)s')
# Проверка наличия существующих обработчиков
if not logger.handlers:
# Создание StreamHandler для вывода в sys.stdout
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
# END_MODULE_logger