Bug
sysstat-post-process.py sets a single default-aggregation: avg for all mpstat metrics at line 332:
desc = {"class": "percentage", "source": "mpstat", "default-aggregation": "avg"}
This descriptor is reused for both Busy-CPU and NonBusy-CPU. For Busy-CPU, the underlying data is stored as one sample per CPU type (usr, sys, soft, irq, nice, guest, steal — one names entry per type). When a CDM query requests Busy-CPU broken out by CPU number but not by type, the API must aggregate across the types. With avg it returns the average of the individual type values (~25% when four types each contribute ~25%) instead of the correct total utilization.
Observed impact
Querying mpstat::Busy-CPU with breakout=["hostname", "num=195"] returned 24.8% for a CPU that was in fact 99.3% busy. The error was diagnosed by adding type to the breakout (which bypasses aggregation) and confirmed by overriding the aggregation method to sum via the CDM API, which returned the correct 99.3%.
Root cause
The CPU type fields (usr, sys, soft, irq, …) are mutually exclusive time slices of a single CPU's total time — they sum to the total CPU utilization by definition. The correct aggregation when collapsing across types is sum, not avg.
Fix
Change the aggregation per metric type inside the loop rather than relying on a single top-level default:
if cpu_type in ("idle", "iowait", "steal"):
desc["type"] = "NonBusy-CPU"
desc["default-aggregation"] = "avg"
else:
desc["type"] = "Busy-CPU"
desc["default-aggregation"] = "sum"
Or more simply, set default-aggregation: sum for Busy-CPU at the point it is assigned.
CDM skill note
Until this is fixed, queries against mpstat::Busy-CPU must either:
- Include
type in the breakout to get per-type values (then sum manually), or
- Pass
"aggregation": "sum" as an override in the CDM API request
The skills/crucible/cdm-query-guide.md skill should be updated to document this workaround.
Bug
sysstat-post-process.pysets a singledefault-aggregation: avgfor all mpstat metrics at line 332:This descriptor is reused for both
Busy-CPUandNonBusy-CPU. ForBusy-CPU, the underlying data is stored as one sample per CPU type (usr, sys, soft, irq, nice, guest, steal — onenamesentry per type). When a CDM query requestsBusy-CPUbroken out by CPU number but not by type, the API must aggregate across the types. Withavgit returns the average of the individual type values (~25% when four types each contribute ~25%) instead of the correct total utilization.Observed impact
Querying
mpstat::Busy-CPUwithbreakout=["hostname", "num=195"]returned 24.8% for a CPU that was in fact 99.3% busy. The error was diagnosed by addingtypeto the breakout (which bypasses aggregation) and confirmed by overriding the aggregation method tosumvia the CDM API, which returned the correct 99.3%.Root cause
The CPU type fields (usr, sys, soft, irq, …) are mutually exclusive time slices of a single CPU's total time — they sum to the total CPU utilization by definition. The correct aggregation when collapsing across types is
sum, notavg.Fix
Change the aggregation per metric type inside the loop rather than relying on a single top-level default:
Or more simply, set
default-aggregation: sumforBusy-CPUat the point it is assigned.CDM skill note
Until this is fixed, queries against
mpstat::Busy-CPUmust either:typein the breakout to get per-type values (then sum manually), or"aggregation": "sum"as an override in the CDM API requestThe
skills/crucible/cdm-query-guide.mdskill should be updated to document this workaround.