Files
fleet/orbit/pkg/platform/platform_linux.go
Lucas Manuel Rodriguez 3e4cf63d31 Fix polling of /proc/stat on Linux by caching (#48750)
Resolves #46461.

- [X] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.

---

Verification command (checks how many times /proc/stat is read):
```
sudo bpftrace -e '
tracepoint:syscalls:sys_enter_openat
/str(args->filename) == "/proc/stat" || str(args->filename) == "/proc/uptime"/
{ @[comm, str(args->filename)] = count(); }
interval:s:60 { exit(); }'
```

1.57.0 outputs:
```
@[orbit, /proc/stat]: 1084
```
fleetd built with changes in this PR (and I had to trigger a restart,
otherwise it's 0):
```
@[orbit, /proc/stat]: 3
[...]
@[fleet-desktop, /proc/stat]: 6
```

## Testing

- [X] QA'd all new/changed functionality manually

## fleetd/orbit/Fleet Desktop

- [x] Verified compatibility with the latest released version of Fleet
(see [Must
rule](https://github.com/fleetdm/fleet/blob/main/docs/Contributing/workflows/fleetd-development-and-release-strategy.md))
- [X] If the change applies to only one platform, confirmed that
`runtime.GOOS` is used as needed to isolate changes
- [X] Verified that fleetd runs on macOS, Linux and Windows
- [X] Verified auto-update works from the released version of component
to the new version (see [tools/tuf/test](../tools/tuf/test/README.md))


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved process listing performance on Linux by reducing repeated
system boot-time reads.
* Prevented unnecessary refreshes during frequent process checks,
helping watchdog-style polling run more efficiently.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-07-06 16:31:21 -03:00

36 lines
1.5 KiB
Go

//go:build linux
package platform
import (
gopsutil_process "github.com/shirou/gopsutil/v4/process"
)
func init() {
// Enable gopsutil's boot-time cache (Linux only).
//
// gopsutil_process.Processes() builds a Process for every PID, and the
// constructor (NewProcess -> CreateTime -> fillFromStat) computes each
// process' creation time, which requires the system boot time. By default
// gopsutil does NOT cache the boot time, so on Linux it re-reads /proc/stat
// (or /proc/uptime on containerized hosts) once per process, on every call.
//
// orbit enumerates the full process table on a recurring basis (e.g. the
// Fleet Desktop watchdog polls every 15s via GetProcessesByName), so this
// caused the host-wide /proc/stat file to be read N times per poll, where N
// is the total number of running processes. The btime field lives near the
// end of /proc/stat, so each read scans the entire file just to recover a
// single constant value.
//
// The system boot time does not change for the lifetime of the orbit
// process, so caching it is safe and collapses those repeated reads into a
// single one. This is scoped to Linux because that is where the redundant
// file reads occur; macOS and Windows obtain boot time via syscall/sysctl.
//
// Note: orbit only reads process Name/Pid and never a process' CreateTime,
// so the cache cannot surface a stale value (the gopsutil README warns that
// a cached boot time can drift if NTP steps the clock after boot, which only
// affects CreateTime).
gopsutil_process.EnableBootTimeCache(true)
}