coder / coder/clistat

HostCPU() always reports 100% on long-running Linux hosts with many cores (int64 overflow in go-sysinfo CPUTime conversion)

Open
#36 1 comment 0 reactions 0 assignees View on GitHub
Bug
Dominant language
Go
Stars
12
Forks
2
PR merge metrics
No merged PRs in 30d

Description

## Summary

On Linux hosts with high core counts and long uptimes, `HostCPU()` consistently
returns `100%` regardless of actual CPU usage.

## Root cause

`host_linux.go` in `go-sysinfo` converts each `/proc/stat` field to
`time.Duration` like this:

```go
Idle: time.Duration(stat.CPUTotal.Idle * float64(time.Second)),
```

On a long running system with many cores this can overflow.

## Example

```
package main

import (
"fmt"
"math"
"os"
"strconv"
"strings"
"time"

"github.com/elastic/go-sysinfo"
)

func main() {
// Read raw idle jiffies from /proc/stat before go-sysinfo converts them.
raw, _ := os.ReadFile("/proc/stat")
fields := strings.Fields(strings.SplitN(string(raw), "\n", 2)[0])
idleJiffies, _ := strconv.ParseInt(fields[4], 10, 64)
idleNS := float64(idleJiffies) / 100.0 * float64(time.Second)

h, _ := sysinfo.Host()
c1, _ := h.CPUTime()
time.Sleep(100 * time.Millisecond)
c2, _ := h.CPUTime()

total := c2.Total() - c1.Total()
idle := c2.Idle - c1.Idle
used := total - idle

fmt.Printf("idle jiffies: %d\n", idleJiffies)
fmt.Printf("idle as ns: %.4e (int64 max: %.4e)\n", idleNS, float64(math.MaxInt64))
fmt.Printf("overflows int64: %v\n\n", idleNS > float64(math.MaxInt64))

fmt.Printf("c1.Idle (ns): %d\n", int64(c1.Idle))
fmt.Printf("c2.Idle (ns): %d\n\n", int64(c2.Idle))

fmt.Printf("delta total: %v\n", total)
fmt.Printf("delta idle: %v (lost if both samples overflowed)\n", idle)
fmt.Printf("delta used: %v\n\n", used)

if total > 0 {
pct := used.Seconds() / total.Seconds() * 100
fmt.Printf("HostCPU() result: %.0f%%\n", pct)
}
}
```

```
idle jiffies: 965604832415
idle as ns: 9.6560e+18 (int64 max: 9.2234e+18)
overflows int64: true

c1.Idle (ns): -9223372036854775808
c2.Idle (ns): -9223372036854775808

delta total: 18.61s
delta idle: 0s (lost if both samples overflowed)
delta used: 18.61s

HostCPU() result: 100%
```

## Environment

- Linux kernel 6.8.0-84-generic
- 512 logical CPUs (`nproc`)
- Cgroup v2, running inside a Docker container (Docker-in-Docker workspace)
- go-sysinfo v1.15.1 (via clistat v1.2.1)
- `coder stat` reports `512/512 cores (100%)` consistently while actual host
load is 35-65% and container usage is ~0.01-0.03 cores

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.