Scripting
Diagnose and doctor
--diagnose#
One line that says what the Mac is doing, the evidence for it, and what was checked. This one is from the M5 Pro while it ran plottypus’s own test suite (the busy process is a cargo test binary):
$ plottypus --diagnose
Busy: plottypus_ui-807fb56e02002983 using 7.7 cores
- cpu active: 100%
- top process: plottypus_ui-807fb56e02002983 (pid 478) at 7.7 cores
checked:
cpu 100% active, top plottypus_ui-807fb56e02002983 at 7.7 cores
memory 18.3G of 24.0G used, 719M swapped, pressure nominal
thermal nominal, cpu 86 °COn a quiet Mac:
$ plottypus --demo --diagnose
All normal
checked:
cpu 10% active, top WindowServer at 0.1 cores
memory 12.8G of 24.0G used, 820M swapped, pressure nominal
thermal nominal, cpu 43 °CLike --json, it waits one interval to measure rates, and for the slow collectors to report, before it answers. It exits 0 whatever the verdict, so read the first line, or use plottypus --json | jq -r .verdict.kind for a machine-readable kind.
The verdict#
The same verdict sits in the footer of the dashboard (click a Busy: verdict to select that process). The first rule that matches wins:
| Order | Kind | Headline | When |
|---|---|---|---|
| 1 | throttling |
Throttling: thermal pressure is serious |
macOS thermal pressure is serious or critical |
| 2 | memory_tight |
Memory tight: 2.1G swapped or Memory tight: pressure warn |
memory pressure is warn or critical, or swap is growing by 1 MiB/s or more |
| 3 | busy |
Busy: Safari using 3.1 cores or Busy: CPU at 90% |
one process uses 1.5 cores or more, or the whole CPU is 75% or more active |
| 4 | normal |
All normal |
none of the above |
The kind battery_drain exists in the JSON schema, but 1.0.0 never produces it.
In the dashboard, a new kind of verdict has to hold for 5 seconds before it replaces the one shown, so a one-tick spike never flips the footer.
“Cores” in a headline is per-core CPU divided by 100: Busy: … using 7.7 cores means that process was using about 7.7 cores’ worth of CPU time.
doctor#
plottypus doctor prints what this Mac exposes: the model and chip, how many SMC keys of each kind, every HID temperature service, how many processes are readable without root, which collectors are working, and what plottypus itself costs. It samples for a couple of seconds and exits. Paste it into bug reports, especially from a chip we have not seen.
From the M5 Pro development machine, trimmed, captured while it was running a test suite at 100% CPU (which is why self-cost reads high):
plottypus 1.0.0
[machine]
model Mac17,8
chip Apple M5 Pro
macos 27.0 (26A428)
chip table curated
cores 0E + 12P + 6S, 20 GPU cores, 24 GB
[smc]
keys 3626 (285 temperature, 51 fan, 77 power)
types flt:2091 hex_:311 ui16:268 ui8:260 ui32:246 si32:138 …
[hid temperature services]
1 NAND CH0 temp
3 PMU tdie1
…
6 gas gauge battery
[processes]
readable 608 of 904 (296 need root)
[collectors]
cpu Ok
memory Ok
gpu Ok
network Ok
disk Ok
processes Ok
sensors Ok
fans Ok
thermal Ok
battery Ok
[self-cost]
cpu 2.19% over 8 ticks at 250 ms (mean tick 1.3 ms)What to look at:
chip tableiscuratedwhen plottypus has a temperature-sensor table for this model or chip, andnone (prefix fallback)when it is guessing zones from SMC key name prefixes.[smc]is the size of this Mac’s SMC key list. A fanless Air has no fans to count; that is expected.[processes]is the count behind the—rows in the process table: processes the kernel will not describe to a normal user. See Processes.[collectors]shows which readings work on this Mac. A collector for hardware the Mac does not have shows as absent rather than failed.[self-cost]is measured on the spot at the fastest interval, 250 ms, while doctor runs. The dashboard at its 500 ms default costs less, and draws nothing while idle.
doctor cannot be combined with --demo: it describes real hardware only.
Doctor output contains your Mac’s model, macOS build and process counts; it contains no process names, user names or serial numbers. Read it before you paste it anywhere.