Manages multiple system services with logging and health monitoring.
| 83 | return f"{timestamp} {colored_service} {colored_level}: {record.getMessage()}" |
| 84 | |
| 85 | class ServiceManager: |
| 86 | """Manages multiple system services with logging and health monitoring.""" |
| 87 | |
| 88 | def __init__(self, mode: str = "dev", logs_dir: str = "logs"): |
| 89 | self.mode = mode |
| 90 | self.logs_dir = Path(logs_dir) |
| 91 | self.logs_dir.mkdir(exist_ok=True) |
| 92 | |
| 93 | self.processes: Dict[str, subprocess.Popen] = {} |
| 94 | self.log_threads: Dict[str, threading.Thread] = {} |
| 95 | self.running = False |
| 96 | |
| 97 | # Setup logging |
| 98 | self.setup_logging() |
| 99 | |
| 100 | # Service configurations |
| 101 | self.services = self._get_service_configs() |
| 102 | |
| 103 | # Register signal handlers for graceful shutdown |
| 104 | signal.signal(signal.SIGINT, self._signal_handler) |
| 105 | signal.signal(signal.SIGTERM, self._signal_handler) |
| 106 | |
| 107 | def setup_logging(self): |
| 108 | """Setup centralized logging with colors.""" |
| 109 | # Create main logger |
| 110 | self.logger = logging.getLogger('system') |
| 111 | self.logger.setLevel(logging.INFO) |
| 112 | |
| 113 | # Console handler with colors |
| 114 | console_handler = logging.StreamHandler(sys.stdout) |
| 115 | console_handler.setFormatter(ColoredFormatter()) |
| 116 | self.logger.addHandler(console_handler) |
| 117 | |
| 118 | # File handler for system logs |
| 119 | file_handler = logging.FileHandler(self.logs_dir / 'system.log') |
| 120 | file_handler.setFormatter(logging.Formatter( |
| 121 | '%(asctime)s [%(levelname)s] %(message)s' |
| 122 | )) |
| 123 | self.logger.addHandler(file_handler) |
| 124 | |
| 125 | def _get_service_configs(self) -> Dict[str, ServiceConfig]: |
| 126 | """Define service configurations based on mode.""" |
| 127 | base_configs = { |
| 128 | 'ollama': ServiceConfig( |
| 129 | name='ollama', |
| 130 | command=['ollama', 'serve'], |
| 131 | port=11434, |
| 132 | startup_delay=5, |
| 133 | required=True |
| 134 | ), |
| 135 | 'rag-api': ServiceConfig( |
| 136 | name='rag-api', |
| 137 | command=[sys.executable, '-m', 'rag_system.api_server'], |
| 138 | port=8001, |
| 139 | startup_delay=3, |
| 140 | required=True |
| 141 | ), |
| 142 | 'backend': ServiceConfig( |