Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

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

Đang mở
#36 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức phù hợp với người mới
48/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
go
Lĩnh vực
observability-sre

Hướng nghiên cứu

Bắt đầu với host_linux.go trong go-sysinfo và tái hiện lỗi tràn số đã được báo cáo bằng ví dụ /proc/stat được cung cấp trên một máy chủ Linux đã chạy trong thời gian dài. Truy vết cách clistat lấy HostCPU và xác định vị trí cần xử lý việc chuyển đổi thời gian CPU. Hoàn thành khi các delta CPU vẫn hợp lệ và HostCPU báo cáo mức sử dụng thực tế thay vì 100%.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Bug

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:

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
Ngôn ngữ chính
Go
Star
11
Fork
2
Merge trung bình
2 ngày 21 giờ
Pull request đã merge (30 ngày)
1

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của coder/clistat

Tất cả issue của coder/clistat

Issue tương tự

Thêm issue về Go

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.