Files
2025-PGanec/src/pganec/main.py
2025-06-08 23:41:18 +03:00

108 lines
6.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
# src/pganec/config.py
import argparse
import logging
import sys
from logging.handlers import MemoryHandler
from pganec.config import load_config, ConfigError, ConfigNotFoundError, InvalidConfigFormatError
from pganec.tui import PGanecApp
# --- Настройки и инициирование логирования ---
logger = logging.getLogger(__name__)
# --- Главная функция приложения ---
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="PGanec — TUI резервного копирования и восстановления баз PostgreSQL")
parser.add_argument("-c", "--config", required=True,
help="Путь к файлу конфигурации (YAML)")
parser.add_argument("-d", "--debug-level", default="INFO",
help="Уровень отладки (QUIET, NOTSET, DEBUG, INFO, WARNING, ERROR, CRITICAL)")
parser.add_argument("-l", "--loging", default="",
help="Путь к файлу логирования (если не указан, логирование не будет вестись)")
args = parser.parse_args()
# Настройка отладочных логов
# --- Определение числового уровня логирования для передачи в TUI ---
level_input_str = args.debug_level.upper()
log_level_to_pass = logging.INFO # Значение по умолчанию, если что-то пойдет не так
if level_input_str == "QUIET":
log_level_to_pass = logging.CRITICAL + 1
else:
# Пытаемся получить числовое значение для стандартных уровней
parsed_level = getattr(logging, level_input_str, None)
if parsed_level is not None and isinstance(parsed_level, int):
log_level_to_pass = parsed_level
else:
# Если уровень не распознан, выводим предупреждение в stderr,
# так как logger.warning может быть еще не настроен для вывода.
print(f"Предупреждение: Неизвестный уровень логирования '{args.debug_level}'. "
f"Используется INFO по умолчанию.", file=sys.stderr)
log_level_to_pass = logging.INFO # Возвращаемся к INFO по умолчанию
# --- Настройка раннего логирования с MemoryHandler ---
# 1. Устанавливаем уровень корневого логгера, чтобы он пропускал нужные сообщения
root_logger = logging.getLogger()
root_logger.setLevel(log_level_to_pass) # Важно для MemoryHandler
# 2. Создаем MemoryHandler
# Он будет копить логи до момента, когда TUI сможет их отобразить.
# `capacity` - сколько записей хранить.
# `flushLevel` - уровень, при котором MemoryHandler попытается сбросить логи в target.
# Ставим очень высокий, чтобы он не сбрасывал сам по себе, т.к. target еще нет.
# `target` - пока None, установим его в TUI.
memory_handler = MemoryHandler(capacity=200, flushLevel=logging.CRITICAL + 10, target=None)
memory_handler.setLevel(logging.NOTSET) # MemoryHandler должен принимать все, что пропускает root_logger
# 3. Добавляем MemoryHandler к корневому логгеру
root_logger.addHandler(memory_handler)
logger.debug(
f"main.py: MemoryHandler добавлен. Log Level: '{logging.getLevelName(root_logger.getEffectiveLevel())}'")
logging.getLogger().setLevel(log_level_to_pass)
logger.debug(f"Запущено с параметрами: {args}")
logger.info(f"Задан уровень логирования: '{logging.getLevelName(log_level_to_pass)}'"
f" ({log_level_to_pass})")
# logging.basicConfig(
# level=chosen_log_level_int,
# format="%(asctime)s - %(name)s - %(levelname)s - %(module)s.%(funcName)s:%(lineno)d - %(message)s"
# )
# Загрузка конфигурации
config = None # Инициализируем config
try:
config = load_config(args.config)
if config: # Добавим проверку, что config не None, если load_config может вернуть None при успехе (хотя по типу не должен)
logger.debug(
f"В конфигурации получены ключи: {list(config.keys())}") # Логируем ключи, а не всю конфигурацию
else:
# Эта ситуация не должна возникать, если load_config выбрасывает исключения при ошибках
# или возвращает dict. Но для полноты.
print(f"Ошибка: Конфигурация не была загружена из '{args.config}', но исключение не было выброшено.",
file=sys.stderr)
sys.exit(1)
except ConfigNotFoundError:
print(f"Ошибка: Файл конфигурации '{args.config}' не найден.", file=sys.stderr)
sys.exit(1)
except InvalidConfigFormatError as e:
print(f"Ошибка: Файл конфигурации '{args.config}' имеет неверный формат. {e}", file=sys.stderr)
sys.exit(1)
except ConfigError as e:
print(f"Ошибка при загрузке конфигурации: {e}", file=sys.stderr)
sys.exit(1)
except Exception as e:
logger.critical(f"Необработанная ошибка во время инициализации: {e}", exc_info=True)
print(f"Произошла критическая и непредвиденная ошибка: {e}", file=sys.stderr)
sys.exit(2)
# Запуск главного меню TUI с передачей числового уровня логирования
# app = PGanecApp(log_level_int=log_level_to_pass) # Передаем и конфигурацию
app = PGanecApp(log_level_int=log_level_to_pass, app_config=config, early_log_handler=memory_handler)
app.run()
# PGanecApp().run()