103 lines
4.6 KiB
Python
103 lines
4.6 KiB
Python
import sys
|
||
import time
|
||
import logging
|
||
import logging.handlers
|
||
import os
|
||
import schedule
|
||
|
||
import config
|
||
from database import DatabaseManager
|
||
from sd_api import ServiceDeskClient
|
||
from sync_logic import Synchronizer
|
||
|
||
def setup_logging():
|
||
"""
|
||
Настраивает продвинутую конфигурацию логирования с ротацией файлов
|
||
и разными уровнями для консоли и файла.
|
||
"""
|
||
# 1. Устанавливаем корневому логгеру самый низкий уровень (DEBUG).
|
||
# Это позволяет хэндлерам самим решать, что пропускать.
|
||
root_logger = logging.getLogger()
|
||
root_logger.setLevel(logging.DEBUG)
|
||
|
||
# 2. Создаем директорию для логов, если она не существует.
|
||
try:
|
||
if not os.path.exists(config.LOG_PATH):
|
||
os.makedirs(config.LOG_PATH)
|
||
except OSError as e:
|
||
print(f"Ошибка создания директории для логов {config.LOG_PATH}: {e}")
|
||
# В случае ошибки выходим, т.к. логирование в файл не будет работать
|
||
sys.exit(1)
|
||
|
||
# 3. Настраиваем форматтер для логов.
|
||
log_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||
|
||
# 4. Настраиваем хэндлер для вывода в консоль (уровень INFO).
|
||
console_handler = logging.StreamHandler(sys.stdout)
|
||
console_handler.setLevel(logging.INFO)
|
||
console_handler.setFormatter(log_formatter)
|
||
|
||
# 5. Настраиваем хэндлер для записи в файл с ежедневной ротацией (уровень DEBUG).
|
||
# Файлы будут вида sync_service.log, sync_service.log.2023-10-27 и т.д.
|
||
log_file = os.path.join(config.LOG_PATH, 'sync_service.log')
|
||
file_handler = logging.handlers.TimedRotatingFileHandler(
|
||
log_file,
|
||
when='midnight', # Ротация в полночь
|
||
interval=1, # Каждый день
|
||
backupCount=7, # Хранить 7 старых файлов
|
||
encoding='utf-8'
|
||
)
|
||
file_handler.setLevel(logging.DEBUG)
|
||
file_handler.setFormatter(log_formatter)
|
||
|
||
# 6. Добавляем оба хэндлера к корневому логгеру.
|
||
root_logger.addHandler(console_handler)
|
||
root_logger.addHandler(file_handler)
|
||
|
||
# 7. Отключаем слишком "болтливые" логи от сторонних библиотек.
|
||
logging.getLogger("requests").setLevel(logging.WARNING)
|
||
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
||
logging.getLogger("schedule").setLevel(logging.INFO)
|
||
|
||
def job():
|
||
"""
|
||
Основная задача, которую будет выполнять планировщик.
|
||
"""
|
||
log = logging.getLogger(__name__)
|
||
log.info("Запуск задачи синхронизации...")
|
||
|
||
try:
|
||
# Инициализация всех компонентов
|
||
db_manager = DatabaseManager(config.DB_FULL_PATH)
|
||
sd_client = ServiceDeskClient(config.SD_ACCESS_KEY, config.SD_BASE_URL)
|
||
|
||
# Контекстный менеджер для БД гарантирует открытие/закрытие соединения
|
||
with db_manager as db:
|
||
# Перед первым запуском создаем таблицы, если их нет
|
||
db.setup_tables()
|
||
|
||
synchronizer = Synchronizer(db, sd_client)
|
||
synchronizer.run_full_sync()
|
||
|
||
except Exception as e:
|
||
log.critical(f"Произошла непредвиденная ошибка на верхнем уровне: {e}", exc_info=True)
|
||
|
||
|
||
if __name__ == '__main__':
|
||
setup_logging()
|
||
main_log = logging.getLogger(__name__)
|
||
|
||
# --- Первоначальный запуск ---
|
||
# Можно запустить один раз при старте, чтобы не ждать первого интервала
|
||
main_log.info("Первый запуск сервиса...")
|
||
job()
|
||
|
||
# --- Настройка расписания ---
|
||
# В вашем коде было 3 минуты, можно настроить как угодно
|
||
sync_interval_minutes = 15
|
||
main_log.info(f"Сервис запущен. Синхронизация будет выполняться каждые {sync_interval_minutes} минут.")
|
||
schedule.every(sync_interval_minutes).minutes.do(job)
|
||
|
||
while True:
|
||
schedule.run_pending()
|
||
time.sleep(1) |