Remove PID management functionality from the bot, including related endpoints and references in the codebase. Update Dockerfile to optimize the build process by separating build and runtime stages. Enhance healthcheck implementation in Dockerfile to use Python instead of curl. Update README to reflect the removal of PID file management and related endpoints.
This commit is contained in:
@@ -7,7 +7,6 @@ from .logger import get_logger, setup_logging
|
||||
from .metrics import MetricsService, get_metrics_service
|
||||
from .metrics_updater import MetricsUpdater, get_metrics_updater, start_metrics_updater, stop_metrics_updater
|
||||
from .db_metrics_decorator import track_db_operation, track_db_connection
|
||||
from .pid_manager import PIDManager, get_pid_manager, cleanup_pid_file
|
||||
from .logging_decorators import (
|
||||
log_function_call, log_business_event, log_fsm_transition,
|
||||
log_handler, log_service, log_business, log_fsm,
|
||||
@@ -25,7 +24,6 @@ __all__ = [
|
||||
'MetricsService', 'get_metrics_service',
|
||||
'MetricsUpdater', 'get_metrics_updater', 'start_metrics_updater', 'stop_metrics_updater',
|
||||
'track_db_operation', 'track_db_connection',
|
||||
'PIDManager', 'get_pid_manager', 'cleanup_pid_file',
|
||||
'log_function_call', 'log_business_event', 'log_fsm_transition',
|
||||
'log_handler', 'log_service', 'log_business', 'log_fsm',
|
||||
'log_quiet', 'log_middleware', 'log_utility',
|
||||
|
||||
@@ -31,7 +31,6 @@ class HTTPServer:
|
||||
self.app.router.add_get('/metrics', self.metrics_handler)
|
||||
self.app.router.add_get('/health', self.health_handler)
|
||||
self.app.router.add_get('/ready', self.ready_handler)
|
||||
self.app.router.add_get('/status', self.status_handler)
|
||||
self.app.router.add_get('/', self.root_handler)
|
||||
|
||||
async def metrics_handler(self, request: Request) -> Response:
|
||||
@@ -167,95 +166,6 @@ class HTTPServer:
|
||||
status=HTTP_STATUS_INTERNAL_SERVER_ERROR
|
||||
)
|
||||
|
||||
async def status_handler(self, request: Request) -> Response:
|
||||
"""Handle /status endpoint for process status information."""
|
||||
try:
|
||||
import os
|
||||
import time
|
||||
import psutil
|
||||
|
||||
# Получаем PID текущего процесса
|
||||
current_pid = os.getpid()
|
||||
|
||||
try:
|
||||
# Получаем информацию о процессе
|
||||
process = psutil.Process(current_pid)
|
||||
create_time = process.create_time()
|
||||
uptime_seconds = time.time() - create_time
|
||||
|
||||
# Логируем для диагностики
|
||||
import datetime
|
||||
create_time_str = datetime.datetime.fromtimestamp(create_time).strftime('%Y-%m-%d %H:%M:%S')
|
||||
current_time_str = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||||
logger.info(f"Process PID {current_pid}: created at {create_time_str}, current time {current_time_str}, uptime {uptime_seconds:.1f}s")
|
||||
|
||||
# Форматируем uptime
|
||||
if uptime_seconds < 60:
|
||||
uptime_str = f"{int(uptime_seconds)}с"
|
||||
elif uptime_seconds < 3600:
|
||||
minutes = int(uptime_seconds // 60)
|
||||
uptime_str = f"{minutes}м"
|
||||
elif uptime_seconds < 86400:
|
||||
hours = int(uptime_seconds // 3600)
|
||||
minutes = int((uptime_seconds % 3600) // 60)
|
||||
uptime_str = f"{hours}ч {minutes}м"
|
||||
else:
|
||||
days = int(uptime_seconds // 86400)
|
||||
hours = int((uptime_seconds % 86400) // 3600)
|
||||
uptime_str = f"{days}д {hours}ч"
|
||||
|
||||
# Проверяем, что процесс активен
|
||||
if process.is_running():
|
||||
status = "running"
|
||||
else:
|
||||
status = "stopped"
|
||||
|
||||
# Формируем ответ
|
||||
response_data = {
|
||||
"status": status,
|
||||
"pid": current_pid,
|
||||
"uptime": uptime_str,
|
||||
"memory_usage_mb": round(process.memory_info().rss / 1024 / 1024, 2),
|
||||
"cpu_percent": process.cpu_percent(),
|
||||
"timestamp": time.time()
|
||||
}
|
||||
|
||||
import json
|
||||
return Response(
|
||||
text=json.dumps(response_data, ensure_ascii=False),
|
||||
content_type='application/json',
|
||||
status=200
|
||||
)
|
||||
|
||||
except psutil.NoSuchProcess:
|
||||
# Процесс не найден
|
||||
response_data = {
|
||||
"status": "not_found",
|
||||
"error": "Process not found",
|
||||
"timestamp": time.time()
|
||||
}
|
||||
|
||||
import json
|
||||
return Response(
|
||||
text=json.dumps(response_data, ensure_ascii=False),
|
||||
content_type='application/json',
|
||||
status=404
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Status check failed: {e}")
|
||||
import json
|
||||
response_data = {
|
||||
"status": "error",
|
||||
"error": str(e),
|
||||
"timestamp": time.time()
|
||||
}
|
||||
|
||||
return Response(
|
||||
text=json.dumps(response_data, ensure_ascii=False),
|
||||
content_type='application/json',
|
||||
status=500
|
||||
)
|
||||
|
||||
async def root_handler(self, request: Request) -> Response:
|
||||
"""Обработчик корневого эндпоинта"""
|
||||
@@ -268,8 +178,7 @@ class HTTPServer:
|
||||
"endpoints": {
|
||||
"metrics": "/metrics",
|
||||
"health": "/health",
|
||||
"ready": "/ready",
|
||||
"status": "/status"
|
||||
"ready": "/ready"
|
||||
},
|
||||
"uptime": time.time() - self.start_time
|
||||
}
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
"""
|
||||
PID менеджер для управления PID файлом процесса
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from loguru import logger
|
||||
|
||||
|
||||
class PIDManager:
|
||||
"""Менеджер для управления PID файлом процесса"""
|
||||
|
||||
def __init__(self, service_name: str = "anon_bot", pid_dir: str = "/tmp"):
|
||||
self.service_name = service_name
|
||||
self.pid_dir = Path(pid_dir)
|
||||
self.pid_file_path = self.pid_dir / f"{service_name}.pid"
|
||||
self.pid: Optional[int] = None
|
||||
|
||||
def create_pid_file(self) -> bool:
|
||||
"""Создать PID файл"""
|
||||
try:
|
||||
# Создаем директорию для PID файлов, если она не существует
|
||||
self.pid_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Проверяем, не запущен ли уже процесс
|
||||
if self.pid_file_path.exists():
|
||||
try:
|
||||
with open(self.pid_file_path, 'r') as f:
|
||||
existing_pid = int(f.read().strip())
|
||||
|
||||
# Проверяем, жив ли процесс с этим PID
|
||||
if self._is_process_running(existing_pid):
|
||||
logger.error(f"Процесс {self.service_name} уже запущен с PID {existing_pid}")
|
||||
return False
|
||||
else:
|
||||
logger.warning(f"Найден устаревший PID файл для {existing_pid}, удаляем его")
|
||||
self.pid_file_path.unlink()
|
||||
|
||||
except (ValueError, OSError) as e:
|
||||
logger.warning(f"Не удалось прочитать существующий PID файл: {e}, удаляем его")
|
||||
self.pid_file_path.unlink()
|
||||
|
||||
# Получаем PID текущего процесса
|
||||
self.pid = os.getpid()
|
||||
|
||||
# Создаем PID файл
|
||||
with open(self.pid_file_path, 'w') as f:
|
||||
f.write(str(self.pid))
|
||||
|
||||
logger.info(f"PID файл создан: {self.pid_file_path} (PID: {self.pid})")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Не удалось создать PID файл: {e}")
|
||||
return False
|
||||
|
||||
def cleanup_pid_file(self) -> None:
|
||||
"""Очистить PID файл"""
|
||||
try:
|
||||
if self.pid_file_path.exists():
|
||||
# Проверяем, что PID файл принадлежит нашему процессу
|
||||
with open(self.pid_file_path, 'r') as f:
|
||||
file_pid = int(f.read().strip())
|
||||
|
||||
if file_pid == self.pid:
|
||||
self.pid_file_path.unlink()
|
||||
logger.info(f"PID файл удален: {self.pid_file_path}")
|
||||
else:
|
||||
logger.warning(f"PID файл содержит другой PID ({file_pid}), не удаляем")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Ошибка при удалении PID файла: {e}")
|
||||
|
||||
def get_pid(self) -> Optional[int]:
|
||||
"""Получить PID процесса"""
|
||||
return self.pid
|
||||
|
||||
def get_pid_file_path(self) -> Path:
|
||||
"""Получить путь к PID файлу"""
|
||||
return self.pid_file_path
|
||||
|
||||
|
||||
def _is_process_running(self, pid: int) -> bool:
|
||||
"""Проверить, запущен ли процесс с указанным PID"""
|
||||
try:
|
||||
# В Unix-системах отправляем сигнал 0 для проверки существования процесса
|
||||
os.kill(pid, 0)
|
||||
return True
|
||||
except (OSError, ProcessLookupError):
|
||||
return False
|
||||
|
||||
|
||||
|
||||
# Глобальный экземпляр PID менеджера
|
||||
_pid_manager: Optional[PIDManager] = None
|
||||
|
||||
|
||||
def get_pid_manager(service_name: str = "anon_bot", pid_dir: str = "/tmp") -> PIDManager:
|
||||
"""Получить экземпляр PID менеджера"""
|
||||
global _pid_manager
|
||||
if _pid_manager is None:
|
||||
_pid_manager = PIDManager(service_name, pid_dir)
|
||||
return _pid_manager
|
||||
|
||||
|
||||
def create_pid_file(service_name: str = "anon_bot", pid_dir: str = "/tmp") -> bool:
|
||||
"""Создать PID файл"""
|
||||
pid_manager = get_pid_manager(service_name, pid_dir)
|
||||
return pid_manager.create_pid_file()
|
||||
|
||||
|
||||
def cleanup_pid_file() -> None:
|
||||
"""Очистить PID файл"""
|
||||
if _pid_manager:
|
||||
_pid_manager.cleanup_pid_file()
|
||||
Reference in New Issue
Block a user