diff --git a/server/api_server/health_endpoint.py b/server/api_server/health_endpoint.py index b4ca8730..322d8e94 100644 --- a/server/api_server/health_endpoint.py +++ b/server/api_server/health_endpoint.py @@ -54,6 +54,7 @@ def get_mem_usage_pct(): mylog("verbose", [f"[health] Error calculating memory usage: {e}"]) return None + def get_load_avg_1m(): """ Get 1-minute load average. @@ -90,6 +91,7 @@ def get_storage_pct(): mylog("verbose", [f"[health] Error calculating storage usage: {e}"]) return None + def get_cpu_temp(): """ Get CPU temperature from hardware sensors if available. @@ -117,6 +119,42 @@ def get_cpu_temp(): return None +def get_mem_mb(): + """ + Get total system memory in MB. + + Returns: + int: Total memory in MB, or None on error. + """ + try: + vm = psutil.virtual_memory() + total_mb = int(vm.total / (1024 * 1024)) + return total_mb + + except Exception as e: + mylog("verbose", [f"[health] Error getting memory size: {e}"]) + return None + + +def get_storage_gb(): + """ + Get total storage size of /data in GB. + + Returns: + float: Total storage in GB, or None on error. + """ + try: + stat = os.statvfs(dataPath) + total = stat.f_blocks * stat.f_frsize + + gb = round(total / (1024 ** 3), 2) + return gb + + except Exception as e: + mylog("verbose", [f"[health] Error getting storage size: {e}"]) + return None + + # =============================================================================== # Aggregator # =============================================================================== @@ -134,4 +172,6 @@ def get_health_status(): "load_1m": get_load_avg_1m(), "storage_pct": get_storage_pct(), "cpu_temp": get_cpu_temp(), + "storage_gb": get_storage_gb(), + "mem_mb": get_mem_mb(), } diff --git a/server/api_server/openapi/schemas.py b/server/api_server/openapi/schemas.py index cb4e1dc1..7adf76f4 100644 --- a/server/api_server/openapi/schemas.py +++ b/server/api_server/openapi/schemas.py @@ -667,7 +667,9 @@ class HealthCheckResponse(BaseResponse): "mem_usage_pct": 65, "load_1m": 2.15, "storage_pct": 42, - "cpu_temp": 58 + "cpu_temp": 58, + "storage_gb": 8, + "mem_mb" : 8192 }] } ) @@ -677,6 +679,8 @@ class HealthCheckResponse(BaseResponse): load_1m: float = Field(..., description="1-minute load average") storage_pct: Optional[int] = Field(None, ge=0, le=100, description="Disk usage percentage of /data mount (0-100, nullable if unavailable)") cpu_temp: Optional[int] = Field(None, description="CPU temperature in Celsius (nullable if unavailable)") + storage_gb: Optional[int] = Field(..., description="Storage size in GB") + mem_mb: Optional[int] = Field(..., description="Installed memory size in MB") # ============================================================================= diff --git a/test/api_endpoints/test_health_endpoints.py b/test/api_endpoints/test_health_endpoints.py index f34c89d9..d1df0b54 100644 --- a/test/api_endpoints/test_health_endpoints.py +++ b/test/api_endpoints/test_health_endpoints.py @@ -82,6 +82,8 @@ def test_health_response_structure(client, api_token): assert "load_1m" in data assert "storage_pct" in data assert "cpu_temp" in data + assert "storage_gb" in data + assert "mem_mb" in data def test_health_db_size_type(client, api_token): @@ -204,6 +206,8 @@ def test_health_multiple_calls_consistency(client, api_token): assert "load_1m" in data assert "storage_pct" in data assert "cpu_temp" in data + assert "storage_gb" in data + assert "mem_mb" in data # ========================================================================