108 lines
6.5 KiB
Python
108 lines
6.5 KiB
Python
# -*- 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()
|
||
|
||
|