import json
from typing import Any, Dict, List, Union
def extract_metrics_from_sample(sample: Union[str, Dict[str, Any]]) -> Dict[str, Any]:
if isinstance(sample, str):
try:
sample = json.loads(sample)
except json.JSONDecodeError:
return {}
if not isinstance(sample, dict):
return {}
if all(key in sample for key in ["pid", "cmd", "executable", "t0_ms"]):
return {}
if "cpu_usage" in sample and "mem_rss_kb" in sample:
return sample
if "aggregated" in sample and isinstance(sample["aggregated"], dict):
return sample["aggregated"]
return {}
def is_valid_metrics_sample(sample: Union[str, Dict[str, Any]]) -> bool:
metrics = extract_metrics_from_sample(sample)
required_fields = ["cpu_usage", "mem_rss_kb", "ts_ms"]
return all(field in metrics for field in required_fields)
def filter_metrics_samples(samples: List[Union[str, Dict[str, Any]]]) -> List[Dict[str, Any]]:
return [extract_metrics_from_sample(sample) for sample in samples if is_valid_metrics_sample(sample)]
def assert_valid_metrics(metrics: Dict[str, Any]) -> None:
required_fields = ["cpu_usage", "mem_rss_kb", "ts_ms"]
for field in required_fields:
assert field in metrics, f"Missing required field: {field}"
assert isinstance(metrics["cpu_usage"], (int, float)), "cpu_usage must be numeric"
assert metrics["cpu_usage"] >= 0, "cpu_usage must be non-negative"
assert isinstance(metrics["mem_rss_kb"], (int, float)), "mem_rss_kb must be numeric"
assert metrics["mem_rss_kb"] >= 0, "mem_rss_kb must be non-negative"
assert isinstance(metrics["ts_ms"], (int, float)), "ts_ms must be numeric"
assert metrics["ts_ms"] > 0, "ts_ms must be positive"
def create_sample_metrics(count: int = 5) -> List[Dict[str, Any]]:
base_time = 1000
metrics = []
for i in range(count):
sample = {
"ts_ms": base_time + (i * 100),
"cpu_usage": 10.0 + (i * 5.0),
"mem_rss_kb": 5000 + (i * 1000),
"mem_vms_kb": 10000 + (i * 2000),
"disk_read_bytes": 1024 * (i + 1),
"disk_write_bytes": 2048 * (i + 1),
"net_rx_bytes": 512 * (i + 1),
"net_tx_bytes": 256 * (i + 1),
"thread_count": 2 + i,
"uptime_secs": 10 + i,
}
metrics.append(sample)
return metrics