Compare commits

1 Commits

Author SHA1 Message Date
abcbb08134 add gzip logging 2025-07-23 18:39:32 +03:00

View File

@@ -3,26 +3,44 @@
# <IMPORTS> # <IMPORTS>
import logging import logging
import os import os
import gzip
import shutil
from logging.handlers import RotatingFileHandler
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
from .database import DatabaseLogHandler, DatabaseManager from .database import DatabaseLogHandler, DatabaseManager
from .settings import settings from .settings import settings
# </IMPORTS> # </IMPORTS>
# <HELPER name="gzip_rotator">
class GzipRotator:
def __call__(self, source: str, dest: str) -> None:
try:
with open(source, 'rb') as f_in:
with gzip.open(dest, 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
os.remove(source)
except Exception as e:
print(f"Ошибка при сжатии лог-файла: {e}")
def namer(name: str) -> str:
return name + ".gz"
# </HELPER>
# <CONTRACT for="setup_logging"> # <CONTRACT for="setup_logging">
# description: "Настраивает логирование, опционально добавляя обработчик для записи в базу данных." # description: "Настраивает логирование с ротацией и сжатием, опционально добавляя обработчик для записи в базу данных."
# preconditions: # preconditions:
# - "run_id должен быть строкой." # - "run_id должен быть строкой."
# - "db_manager должен быть экземпляром DatabaseManager или None." # - "db_manager должен быть экземпляром DatabaseManager или None."
# postconditions: # postconditions:
# - "Базовая конфигурация логирования настроена." # - "Базовая конфигурация логирования настроена с ротацией и сжатием."
# - "Если log_to_db is True и db_manager предоставлен, добавляется обработчик для БД." # - "Если log_to_db is True и db_manager предоставлен, добавляется обработчик для БД."
# exceptions: # exceptions:
# - "Может возникнуть исключение при ошибке инициализации обработчика БД." # - "Может возникнуть исключение при ошибке инициализации обработчика БД."
# </CONTRACT> # </CONTRACT>
# <ACTION name="setup_logging"> # <ACTION name="setup_logging">
def setup_logging(run_id: str, db_manager: Optional[DatabaseManager] = None): def setup_logging(run_id: str, db_manager: Optional[DatabaseManager] = None):
"""Настраивает систему логирования проекта.""" """Настраивает систему логирования проекта с ротацией и сжатием."""
# <CORE_LOGIC> # <CORE_LOGIC>
log_format = '[%(asctime)s] [%(levelname)s] :: %(message)s' log_format = '[%(asctime)s] [%(levelname)s] :: %(message)s'
handlers = [] handlers = []
@@ -33,11 +51,24 @@ def setup_logging(run_id: str, db_manager: Optional[DatabaseManager] = None):
# </ACTION> # </ACTION>
# <ACTION name="configure_file_handler"> # <ACTION name="configure_file_handler">
# Добавляем обработчик для записи логов в файл. # Добавляем обработчик для записи логов в файл с ротацией и сжатием.
log_file_name = f"run_{run_id}.log" log_file_name = f"run_{run_id}.log"
file_handler = logging.FileHandler(settings.log_dir / log_file_name, mode='w', encoding='utf-8') log_file_path = settings.log_dir / log_file_name
# Используем RotatingFileHandler для управления размером лог-файлов.
# 10 MB per file, 5 backup files
file_handler = RotatingFileHandler(
log_file_path, maxBytes=10*1024*1024, backupCount=5, encoding='utf-8'
)
file_handler.setLevel(logging.INFO) file_handler.setLevel(logging.INFO)
file_handler.setFormatter(logging.Formatter(log_format)) file_handler.setFormatter(logging.Formatter(log_format))
# <REFACTORING_TARGET>
# Добавляем сжатие для ротированных файлов
file_handler.rotator = GzipRotator()
file_handler.namer = namer
# </REFACTORING_TARGET>
handlers.append(file_handler) handlers.append(file_handler)
# </ACTION> # </ACTION>
@@ -65,7 +96,7 @@ def setup_logging(run_id: str, db_manager: Optional[DatabaseManager] = None):
if any(isinstance(h, DatabaseLogHandler) for h in handlers): if any(isinstance(h, DatabaseLogHandler) for h in handlers):
logging.info("Обработчик логов для записи в базу данных успешно добавлен.") logging.info("Обработчик логов для записи в базу данных успешно добавлен.")
logging.info("Система логирования инициализирована.") logging.info("Система логирования инициализирована с ротацией и сжатием.")
# </CORE_LOGIC> # </CORE_LOGIC>
# <COHERENCE_CHECK status="PASSED" /> # <COHERENCE_CHECK status="PASSED" />
# </ACTION> # </ACTION>