Files

69 lines
2.3 KiB
Python
Raw Permalink Normal View History

"""Per-server metric parsing and offline segment merging."""
from __future__ import annotations
import json
from typing import Any
from server.utils.fleet_metrics import _metric_from_system_info
def parse_system_info_metrics(system_info: dict[str, Any] | str | None) -> tuple[int | None, int | None]:
"""Extract CPU/mem integer percentages from Agent system_info."""
if system_info is None:
return None, None
info: dict[str, Any]
if isinstance(system_info, str):
try:
parsed = json.loads(system_info)
except json.JSONDecodeError:
return None, None
info = parsed if isinstance(parsed, dict) else {}
elif isinstance(system_info, dict):
info = system_info
else:
return None, None
cpu = _metric_from_system_info(info, "cpu_usage", "cpu")
mem = _metric_from_system_info(info, "mem_usage", "mem")
cpu_i = round(cpu) if cpu is not None else None
mem_i = round(mem) if mem is not None else None
return cpu_i, mem_i
def sample_from_redis_heartbeat(data: dict[str, Any]) -> tuple[bool, int | None, int | None]:
"""Map Redis heartbeat hash to (is_online, cpu_pct, mem_pct) for one flush sample."""
is_online = data.get("is_online") == "True"
if not is_online:
return False, None, None
cpu, mem = parse_system_info_metrics(data.get("system_info"))
return True, cpu, mem
def merge_offline_segments(points: list[dict[str, Any]]) -> list[dict[str, str]]:
"""Merge consecutive is_online=false points into {from, to} segments (recorded_at strings)."""
if not points:
return []
segments: list[dict[str, str]] = []
seg_start: str | None = None
prev_at: str | None = None
for point in points:
recorded_at = str(point.get("recorded_at") or "")
if not recorded_at:
continue
is_online = bool(point.get("is_online"))
if not is_online:
if seg_start is None:
seg_start = recorded_at
elif seg_start is not None and prev_at is not None:
segments.append({"from": seg_start, "to": prev_at})
seg_start = None
prev_at = recorded_at
if seg_start is not None and prev_at is not None:
segments.append({"from": seg_start, "to": prev_at})
return segments