Report per-core CPU percentages alongside the overall figure

Derived from the same percpu psutil.cpu_percent() call rather than a
second blocking call, so the aggregate and the per-core breakdown
describe the same sampling window.
This commit is contained in:
2026-07-29 21:13:00 +02:00
parent ef6b313d47
commit fbae64a11a
2 changed files with 8 additions and 2 deletions

View File

@@ -70,7 +70,7 @@ Every endpoint except `/api/health` requires an `X-API-Key` header.
"hostname": "myserver",
"timestamp": "2026-07-29T20:15:00+00:00",
"uptimeSeconds": 123456,
"cpu": { "percent": 12.3, "cores": 4, "model": "Intel(R) Xeon(R) ...", "loadAverage": [0.12, 0.34, 0.20] },
"cpu": { "percent": 12.3, "cores": 4, "model": "Intel(R) Xeon(R) ...", "loadAverage": [0.12, 0.34, 0.20], "perCore": [9.1, 15.4, 8.0, 16.7] },
"memory": { "totalBytes": 0, "usedBytes": 0, "availableBytes": 0, "percent": 0, "swapTotalBytes": 0, "swapUsedBytes": 0, "swapPercent": 0 },
"disks": [
{ "mountpoint": "/", "device": "/dev/sda1", "fstype": "ext4", "totalBytes": 0, "usedBytes": 0, "freeBytes": 0, "percent": 0 }

View File

@@ -183,7 +183,12 @@ def _network() -> dict:
def collect() -> dict:
cpu_percent = psutil.cpu_percent(interval=0.3)
# A single percpu=True call gives every core's percent over the same
# sampling window; the overall figure is derived from it (its mean)
# instead of a second separate blocking call, so both numbers describe
# the same 0.3s window rather than two slightly different ones.
per_core_percent = psutil.cpu_percent(interval=0.3, percpu=True)
cpu_percent = round(sum(per_core_percent) / len(per_core_percent), 1) if per_core_percent else 0.0
vm = psutil.virtual_memory()
swap = psutil.swap_memory()
boot_time = psutil.boot_time()
@@ -197,6 +202,7 @@ def collect() -> dict:
"cores": psutil.cpu_count(logical=True) or 0,
"model": _cpu_model(),
"loadAverage": _load_average(),
"perCore": per_core_percent,
},
"memory": {
"totalBytes": vm.total,