Commit Graph

243 Commits

Author SHA1 Message Date
Aditya Raj Singh
fa9de55433 fix(agent): warn on critical ATA SMART attributes (#2275) 2026-08-30 11:23:52 -04:00
Aditya Raj Singh
7c60f02802 fix(agent): don't read host CPU and memory totals from a Docker VM (#2272)
refreshSystemDetails() takes NCPU and MemTotal from the Docker daemon's
/info response. That only describes this machine when the daemon shares its
kernel. On macOS and Windows Docker runs inside a Linux VM, so the system
details header shows the VM's memory as the host total, and the VM's CPU
count clamps both cores and threads through the lxc branch below it.

Only consult Docker's host info on platforms where the daemon runs natively.
Everything else already falls back to gopsutil, which reads this host.
2026-08-30 11:09:39 -04:00
Ryan Chou
6fe268e463 fix(agent): read TOKEN_FILE like KEY_FILE instead of sending the whole file (#2276) 2026-08-30 10:16:43 -04:00
henrygd
0ad707288a fix windows sensor mocks and data directory tests 2026-08-26 11:50:19 -04:00
Aditya Raj Singh
0bc5470f08 fix(agent): count swap cache as used space (#2267)
SwapCached pages have been read back into memory but still occupy allocated swap slots. Subtracting them from SwapTotal - SwapFree underreported swap usage compared with free, Glances, and gopsutil's canonical SwapMemory metric.
2026-08-26 11:42:40 -04:00
Luke Wass
4c48fe0c41 fix(agent): carry Intel GPU averages forward between samples (#2256)
Intel GPUs (intel_gpu_top) never report temperature or memory, so the
"suspended card" heuristic in calculateGPUAverage (temp == 0 &&
memoryUsed == 0) fired on every collection that landed between samples.

intel_gpu_top samples every 3.3s (intelGpuStatsInterval) while the hub's
realtime worker collects every 1s, so most realtime collections had no
new sample (delta count 0) and returned an empty GPUData with power
omitted (json "p"/"pp" are omitempty). The frontend derives the GPU
Power Draw series and legend from the latest sample, so the chart and
legend blanked on roughly two of every three or four one-second cycles.

NVIDIA/AMD were unaffected because they report temperature even when
idle, so the heuristic never fired and the last average was already
carried forward.

Gate the zero-return on non-engine (discrete) GPUs so Intel GPUs carry
the last average forward during between-sample gaps, matching the
existing NVIDIA/AMD behavior. Add a regression test.
2026-08-24 10:33:00 -04:00
Aditya Raj Singh
f1e5797c76 fix(agent): round load average to two decimals (#2245)
Every other metric in getSystemStats is stored through utils.TwoDecimals.
The load averages were assigned straight from gopsutil, so whatever the
platform reported was recorded verbatim.

On Linux that goes unnoticed because /proc/loadavg is already two decimal
places. Everywhere else it is not. macOS and BSD divide a fixed point
value by fscale and produce numbers like 2.55322265625, and the Windows
implementation synthesises the average as a decaying EWMA over the
processor queue length counter, so an idle machine reports values like
1.3667392689044936e-73 instead of 0.

The hub already treats two decimals as the canonical precision for this
field, since records.go rounds the load average when it averages records.
That left the raw agent records as the only place carrying full precision.
2026-08-21 17:30:19 -04:00
Toomore Chiang
aa1d67a122 fix(agent): strip invalid UTF-8 from battery names (#2241)
Battery names come from firmware (sysfs model_name on Linux), which does not
guarantee valid UTF-8. The hub decodes agent payloads using the default
fxamacker/cbor decode mode, which rejects invalid UTF-8, so a single bad byte
in a battery name makes the hub drop the entire payload and mark the system
down until the agent is downgraded.
2026-08-19 11:02:33 -04:00
Alec Rubin
68a3f8962a fix(agent): read /proc/uptime on linux instead of sysinfo(2) (#2180)
gopsutil's host.Uptime() calls the sysinfo(2) syscall. Inside an LXC
container lxcfs virtualizes /proc/uptime but cannot intercept a
syscall, so every container reported the host's uptime.

Reads /proc/uptime on linux and falls back to host.Uptime() if the file
is missing or unparseable, so other platforms are unchanged.
2026-08-18 15:18:33 -04:00
Ilya Muratov
0eb3426619 fix(agent): discover fans on legacy hwmon parent devices (#2238) 2026-08-18 11:32:52 -04:00
Jan Dziąsło
96beadc8c9 fix(agent): add fallback for CPU model detection on MIPS architectures (#2138)
gopsutil's cpu.Info() does not parse the 'cpu model' field from
/proc/cpuinfo, which is the only source of CPU model names on MIPS.
Add a fallback that reads /proc/cpuinfo directly and combines
'cpu model' (e.g. 'MIPS 1004Kc V2.15') with 'system type'
(e.g. 'MediaTek MT7621 ver:1 eco:3') for a complete identifier.

The fallback only triggers when gopsutil returns an empty ModelName,
so x86/ARM/other architectures are unaffected.
2026-08-18 10:34:41 -04:00
Sven van Ginkel
65a6f60304 fix(agent): fix QNAP MD RAID arrays incorrectly reported as FAILED (#2065) 2026-08-18 10:10:12 -04:00
Pavel Artsishevsky
2df1f722e4 fix(agent): use time-based CPU calc for Podman containers (#2131) 2026-08-17 17:08:57 -04:00
henrygd
89ad51d4ce fix(agent): distinguish SMART devices sharing the same path
Co-authored-by: Digital <github@crni.xyz>
2026-08-17 13:55:27 -04:00
henrygd
ae037b278e agent: simplify FreeBSD temperature sensor names 2026-08-16 21:16:12 -04:00
QuantumFlux21
9f1128933f feat: Add support for reading CPU (dev.cpu.*.temperature) and ACPI thermal zone (hw.acpi.thermal.tz*) temperature sensors on FreeBSD systems. (#2227)
Co-authored-by: roib <roib@elsec.us>
2026-08-16 20:58:41 -04:00
henrygd
87405c5f10 feat: add multi-battery monitoring
- Report battery data for individual devices
- Select a representative battery for legacy fields and alerts
- Average named battery data independently
- Display multiple batteries in system charts
- Add cross-platform coverage and transport tests
2026-08-16 13:52:29 -04:00
Miłosz Kolber
bfa6a1e361 feat(agent): monitor Intel Arc (xe) GPUs via nvtop (#2223)
intel_gpu_top does not support the xe driver, so skip it for xe devices
and let the existing nvtop last-resort collector handle them. nvtop leaves
device_name unset on xe, so name the GPU from its PCI device id ("Intel GPU
(<id>)"). Adds nvtop to the Intel agent image (gputop already ships with
igt-gpu-tools).
2026-08-16 11:41:28 -04:00
T.J. Tarazevits
3688b2d033 Add Intel sysfs GPU power collector (Xe/i915 hwmon energy counters) (#2020) 2026-08-16 11:20:43 -04:00
Maxim Lepekha
eebcd56462 feat: fan RPM monitoring (#2032)
Adds fan RPM monitoring as a peer to the existing temperature collection, addressing #1918.

---------

Co-authored-by: henrygd <hank@henrygd.me>
2026-08-15 15:59:07 -04:00
Sven van Ginkel
eb5dd230cf fix(hub): remove stale smart_devices records when a drive is no longer reported (#2178)
* Fix duplicate /dev/sdg-style entries

* only prune devices after complete refreshes

---------

Co-authored-by: henrygd <hank@henrygd.me>
2026-08-15 13:40:30 -04:00
Sven van Ginkel
b68acea5a8 fix(agent): show all IP:port mappings for containers bound to multiple IPs (#1993)
* feat: support multiple docker ips

* deduplicate wildcard docker bindings

---------

Co-authored-by: henrygd <hank@henrygd.me>
2026-08-15 11:50:20 -04:00
Yvan Wang
d50c09176f fix(agent): honor explicit SMART_DEVICES type hint instead of scan-detected type (#2102)
When SMART_DEVICES specifies an explicit type (e.g. /dev/sda:scsi), the
agent resolved the device type correctly but smartctlArgs dropped the -d
flag for scsi/ata (the #1345 scan-misdetection workaround), so smartctl
re-detected the wrong type (sat) and collection failed on USB drives
whose bridge does not support SAT passthrough.

Mark types that come from an explicit SMART_DEVICES hint and always pass
them through via -d, while still letting scan-detected scsi/ata
auto-detect as before. Adds regression tests for the arg building, the
full parse -> merge -> args path, and flag preservation across rescans.

Fixes #2072
2026-08-14 14:13:33 -04:00
Vito Cappello
cf90249519 Clamp Linux battery capacity percentage (#1957) 2026-08-14 10:17:38 -04:00
henrygd
ac4436bea3 fix(tests): align error message after merging #2011 2026-08-13 19:27:33 -04:00
Sven van Ginkel
fa5cda83c2 fix(agent): validate HUB_URL host to prevent misleading "lookup api" DNS error (#2011) 2026-08-13 19:25:12 -04:00
Ryan Chou
98e86b4c9c fix(agent): treat a backwards container CPU counter as a new baseline (#2205)
CalculateCpuPercentLinux subtracted the stored previous counters from the
current ones without checking direction. When a stats response is processed
after a newer one for the same container, or an accounting counter resets,
the current total reads lower and the unsigned subtraction wraps to ~2^64
instead of going negative.

On the container counter that surfaces as the reported error, and the sample
is discarded along with the container's network stats:

    cpu pct greater than 100: 1.15292150348562e+13

On the system counter it is quieter and worse: the wrapped value inflates the
divisor, so the percentage collapses toward zero and is stored as a healthy
sample rather than rejected. A synthetic rollback measures 2.7e-12 percent.

Both directions are now treated as a new baseline (0% for one sample), which
matches how the function already handles the first-run case.

CalculateCpuPercentWindows had the same unguarded subtraction and is fixed
the same way.

Fixes #2149

Co-authored-by: Ryan Chou <ryanchou1994@users.noreply.github.com>
2026-08-13 18:14:30 -04:00
henrygd
d40372842b fix(agent): guard against unsigned underflow in memory calculations (closes #1978)
Extract host memory derivation into calculateHostMemoryUsage and use
saturating subtraction to prevent uint64 underflow caused by race
conditions when reading /proc/meminfo. Also ensure UsedPercent guards
against division by zero.

Co-authored-by: Sven van Ginkel <svenvanginkel@icloud.com>
2026-08-13 17:06:10 -04:00
Sven van Ginkel
01efba50a5 fix(agent): remove unsynchronized hubVersions cache causing concurrent map write panic (#2153) 2026-08-11 17:14:59 -04:00
Quadrubo
7ffc6e81ce fix(agent): prevent a malformed Docker response from permanently breaking container stats (#2066)
decode() reused a single json.Decoder across responses. Once a decode errored on a truncated or malformed body (e.g. a container removed mid-request), the decoder stayed desynced and every subsequent decode failed, silently stopping all container stats until the agent was restarted. Decode the buffered bytes with json.Unmarshal instead, which keeps the reusable read buffer but holds no cross-call state.

Regression from d67d638.
2026-08-11 16:40:24 -04:00
Vito Cappello
bd52134558 fix(agent): don't warn on mdraid consistency checks (#2067) 2026-08-11 15:50:58 -04:00
Uğur Tafralı
a71617e058 feat(agent): Add EXIT_ON_DNS_ERROR environment variable (#1929)
Co-authored-by: henrygd <hank@henrygd.me>
2026-04-17 19:26:11 -04:00
henrygd
981c788d6f agent: make sure prefixed ALL_PROXY env var works (#1919) 2026-04-14 14:46:43 -04:00
Rafael Marmelo
f5576759de agent: Allow agent to connect to hub via SOCKS5 proxy 2026-04-14 14:46:43 -04:00
Lars Lehtonen
1556e53926 fix(agent): dropped linux battery error (#1908) 2026-04-10 18:33:42 -04:00
FlintyLemming
3793b27958 fix(agent): use nvme_total_capacity fallback for NVMe disk size (#1899)
Some enterprise NVMe drives (e.g. Dell Ent NVMe CM7 U.2) report capacity
via nvme_total_capacity instead of user_capacity.bytes in smartctl output.
The NVMe SMART parser now falls back to nvme_total_capacity when
user_capacity.bytes is zero.
2026-04-09 15:50:59 -04:00
henrygd
0ae8c42ae0 fix(hub): System.HasUser - return true if SHARE_ALL_SYSTEMS=true (#1891)
- move hub's GetEnv function to new utils package to more easily share
across different hub packages
- change System.HasUser to take core.Record instead of user ID string
- add tests
2026-04-08 20:13:39 -04:00
henrygd
ea80f3c5a2 fix(agent): add safety check for read returning negative bytes (#1799) 2026-04-07 18:41:22 -04:00
Sven van Ginkel
c4009f2b43 feat: add more disk I/O metrics (#1866)
Co-authored-by: henrygd <hank@henrygd.me>
2026-04-04 18:28:05 -04:00
henrygd
6b5e6ffa9a agent: small refactoring and tests for battery package (#1872) 2026-04-02 21:07:14 -04:00
henrygd
d656036d3b agent: refactor new battery package (#1872) 2026-04-02 21:07:14 -04:00
svenvg93
80b73c7faf feat: implement the battery diectly instead of depency 2026-04-02 21:07:14 -04:00
Sven van Ginkel
7f565a3086 fix(agent): show correct NVMe capacity for Apple SSDs (#1873)
Co-authored-by: henrygd <hank@henrygd.me>
2026-04-02 15:36:05 -04:00
henrygd
f670e868e4 agent: add SENSORS_TIMEOUT env var (#1871) 2026-04-02 15:10:49 -04:00
henrygd
7f4f14b505 fix(agent,windows): raise timeout on first sensor collection to allow LHM to start 2026-03-31 16:10:59 -04:00
henrygd
2fda4ff264 agent: update LibreHardwareMonitorLib to 0.9.6 2026-03-31 15:55:02 -04:00
henrygd
cef09d7cb1 fix(agent): fix windows root disk detection if exe not running on root disk (#1863) 2026-03-31 12:58:42 -04:00
Sven van Ginkel
80135fdad3 fix(agent): exclude nested virtual fs when mounting host root to /extra-filesystems in Docker (#1859) 2026-03-30 13:48:54 -04:00
henrygd
6a207c33fa agent: change disk.Partitions(false) to true - likely fixes empty partition list in docker as of gopsutil 4.26.2 2026-03-29 12:33:45 -04:00
henrygd
afdc3f7779 fix(agent): allow GPU_COLLECTOR=nvml without nvidia-smi (#1849) 2026-03-28 18:58:16 -04:00