- Removed unnecessary `__init__.py` and `Dockerfile` to streamline project organization. - Updated `.dockerignore` and `.gitignore` to improve exclusion patterns for build artifacts and environment files. - Enhanced `Makefile` with new commands for managing Docker containers and added help documentation. - Introduced `pyproject.toml` for better project metadata management and dependency tracking. - Updated `requirements.txt` to reflect changes in dependencies for metrics and monitoring. - Refactored various handler files to improve code organization and maintainability.
118 lines
4.4 KiB
Python
118 lines
4.4 KiB
Python
import asyncio
|
||
import os
|
||
import sys
|
||
import signal
|
||
|
||
# Ensure project root is on sys.path for module resolution
|
||
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||
if CURRENT_DIR not in sys.path:
|
||
sys.path.insert(0, CURRENT_DIR)
|
||
|
||
from helper_bot.main import start_bot
|
||
from helper_bot.utils.base_dependency_factory import get_global_instance
|
||
from helper_bot.server_monitor import ServerMonitor
|
||
from helper_bot.utils.auto_unban_scheduler import get_auto_unban_scheduler
|
||
from helper_bot.utils.metrics_exporter import MetricsManager
|
||
|
||
|
||
async def start_monitoring(bdf, bot):
|
||
"""Запуск модуля мониторинга сервера"""
|
||
monitor = ServerMonitor(
|
||
bot=bot,
|
||
group_for_logs=bdf.settings['Telegram']['group_for_logs'],
|
||
important_logs=bdf.settings['Telegram']['important_logs']
|
||
)
|
||
return monitor
|
||
|
||
|
||
async def main():
|
||
"""Основная функция запуска"""
|
||
bdf = get_global_instance()
|
||
|
||
# Создаем бота для мониторинга
|
||
from aiogram import Bot
|
||
from aiogram.client.default import DefaultBotProperties
|
||
|
||
monitor_bot = Bot(
|
||
token=bdf.settings['Telegram']['bot_token'],
|
||
default=DefaultBotProperties(parse_mode='HTML'),
|
||
timeout=30.0
|
||
)
|
||
|
||
# Создаем экземпляр монитора
|
||
monitor = await start_monitoring(bdf, monitor_bot)
|
||
|
||
# Инициализируем планировщик автоматического разбана
|
||
auto_unban_scheduler = get_auto_unban_scheduler()
|
||
auto_unban_scheduler.set_bot(monitor_bot)
|
||
auto_unban_scheduler.start_scheduler()
|
||
|
||
# Инициализируем метрики
|
||
metrics_manager = MetricsManager(host="0.0.0.0", port=8000)
|
||
|
||
# Флаг для корректного завершения
|
||
shutdown_event = asyncio.Event()
|
||
|
||
def signal_handler(signum, frame):
|
||
"""Обработчик сигналов для корректного завершения"""
|
||
print(f"\nПолучен сигнал {signum}, завершаем работу...")
|
||
shutdown_event.set()
|
||
|
||
# Регистрируем обработчики сигналов
|
||
signal.signal(signal.SIGINT, signal_handler)
|
||
signal.signal(signal.SIGTERM, signal_handler)
|
||
|
||
# Запускаем бота, мониторинг и метрики
|
||
bot_task = asyncio.create_task(start_bot(bdf))
|
||
monitor_task = asyncio.create_task(monitor.monitor_loop())
|
||
metrics_task = asyncio.create_task(metrics_manager.start())
|
||
|
||
try:
|
||
# Ждем сигнала завершения
|
||
await shutdown_event.wait()
|
||
print("Начинаем корректное завершение...")
|
||
|
||
except KeyboardInterrupt:
|
||
print("Получен сигнал завершения...")
|
||
finally:
|
||
print("Отправляем сообщение об отключении...")
|
||
try:
|
||
# Отправляем сообщение об отключении
|
||
await monitor.send_shutdown_message()
|
||
except Exception as e:
|
||
print(f"Ошибка при отправке сообщения об отключении: {e}")
|
||
|
||
print("Останавливаем планировщик автоматического разбана...")
|
||
auto_unban_scheduler.stop_scheduler()
|
||
|
||
print("Останавливаем метрики...")
|
||
await metrics_manager.stop()
|
||
|
||
print("Останавливаем задачи...")
|
||
# Отменяем задачи
|
||
bot_task.cancel()
|
||
monitor_task.cancel()
|
||
metrics_task.cancel()
|
||
|
||
# Ждем завершения задач
|
||
try:
|
||
await asyncio.gather(bot_task, monitor_task, metrics_task, return_exceptions=True)
|
||
except Exception as e:
|
||
print(f"Ошибка при остановке задач: {e}")
|
||
|
||
# Закрываем сессию бота
|
||
await monitor_bot.session.close()
|
||
print("Бот корректно остановлен")
|
||
|
||
|
||
if __name__ == '__main__':
|
||
try:
|
||
asyncio.run(main())
|
||
except AttributeError:
|
||
# Fallback for Python 3.6-3.7
|
||
loop = asyncio.get_event_loop()
|
||
try:
|
||
loop.run_until_complete(main())
|
||
finally:
|
||
loop.close()
|