"""Uptime monitoring service — performs HTTP health checks.""" import time from datetime import datetime import httpx from sqlalchemy.ext.asyncio import AsyncSession from app.models.models import Monitor, MonitorResult async def check_monitor(monitor: Monitor, db: AsyncSession) -> MonitorResult: """Perform a single HTTP health check for a monitor and store the result.""" start = time.monotonic() try: async with httpx.AsyncClient() as client: response = await client.request( method=monitor.method, url=monitor.url, timeout=monitor.timeout_seconds, follow_redirects=True, ) elapsed_ms = int((time.monotonic() - start) * 1000) if response.status_code == monitor.expected_status: # Check response time threshold for "degraded" status = "up" if elapsed_ms < 5000 else "degraded" result = MonitorResult( monitor_id=monitor.id, status=status, response_time_ms=elapsed_ms, status_code=response.status_code, error_message=None, checked_at=datetime.utcnow(), ) else: result = MonitorResult( monitor_id=monitor.id, status="down", response_time_ms=elapsed_ms, status_code=response.status_code, error_message=f"Expected {monitor.expected_status}, got {response.status_code}", checked_at=datetime.utcnow(), ) except Exception as exc: elapsed_ms = int((time.monotonic() - start) * 1000) result = MonitorResult( monitor_id=monitor.id, status="down", response_time_ms=elapsed_ms, status_code=None, error_message=str(exc)[:500], checked_at=datetime.utcnow(), ) db.add(result) await db.flush() return result