""" Schedule 3 — 系統狀態(每日 08:00) Part A: 基礎設施服務功能驗證(traefik/keycloak/mail/db) Part B: 伺服器 ping 檢查 """ import logging from datetime import datetime from sqlalchemy.orm import Session from app.models.server import SystemStatusLog, ServerStatusLog, Server logger = logging.getLogger(__name__) # Fixed 8 services: environment × service_name SERVICES = [ {"environment": "test", "service_name": "traefik", "service_desc": "測試環境反向代理", "host": "localhost", "port": 8080}, {"environment": "test", "service_name": "keycloak", "service_desc": "測試環境 SSO", "url": "https://auth.lab.taipei", "realm": "master"}, {"environment": "test", "service_name": "mail", "service_desc": "測試環境 Mail Server", "host": "localhost", "port": 587}, {"environment": "test", "service_name": "db", "service_desc": "10.1.0.20:5433 PostgreSQL", "db_host": "10.1.0.20", "db_port": 5433}, {"environment": "prod", "service_name": "traefik", "service_desc": "正式環境反向代理", "host": "localhost", "port": 8080}, {"environment": "prod", "service_name": "keycloak", "service_desc": "正式環境 SSO", "url": "https://auth.ease.taipei", "realm": "master"}, {"environment": "prod", "service_name": "mail", "service_desc": "正式環境 Mail Server", "host": "10.1.0.254", "port": 587}, {"environment": "prod", "service_name": "db", "service_desc": "10.1.0.254:5432 PostgreSQL", "db_host": "10.1.0.254", "db_port": 5432}, ] def run_system_status(schedule_log_id: int, db: Session): from app.services.system_checker import SystemChecker checker = SystemChecker() # Part A: Infrastructure services for svc in SERVICES: result = False fail_reason = None try: if svc["service_name"] == "traefik": result = checker.check_traefik(svc["host"], svc["port"]) elif svc["service_name"] == "keycloak": result = checker.check_keycloak(svc["url"], svc["realm"]) elif svc["service_name"] == "mail": result = checker.check_smtp(svc["host"], svc["port"]) elif svc["service_name"] == "db": result = checker.check_postgres(svc["db_host"], svc["db_port"]) except Exception as e: result = False fail_reason = str(e) db.add(SystemStatusLog( schedule_log_id=schedule_log_id, environment=svc["environment"], service_name=svc["service_name"], service_desc=svc["service_desc"], result=result, fail_reason=fail_reason, recorded_at=datetime.utcnow(), )) # Part B: Server ping servers = db.query(Server).filter(Server.is_active == True).order_by(Server.sort_order).all() for server in servers: response_time = None fail_reason = None try: response_time = checker.ping_server(server.ip_address) result = response_time is not None if not result: fail_reason = "No response" except Exception as e: result = False fail_reason = str(e) db.add(ServerStatusLog( schedule_log_id=schedule_log_id, server_id=server.id, result=result, response_time=response_time, fail_reason=fail_reason, recorded_at=datetime.utcnow(), )) db.commit() logger.info(f"System status check done: {len(SERVICES)} services + {len(servers)} servers")