Repository: prometheus/procfs
Pull request #644 (2024-05-30 03:31:31)

enhancement: Expose CPU online status
Required for https://github.com/prometheus/node_exporter/issues/873.


Patch:
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 018c8e1..684eb15 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -46,6 +46,7 @@ workflows:
         matrix:
           parameters:
             go_version:
+            - "1.20"
             - "1.21"
             - "1.22"
     - test:
@@ -55,5 +56,6 @@ workflows:
         matrix:
           parameters:
             go_version:
+            - "1.20"
             - "1.21"
             - "1.22"
diff --git a/.golangci.yml b/.golangci.yml
index c24864a..126df9e 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -1,9 +1,16 @@
 ---
 linters:
   enable:
+  - errcheck
   - godot
+  - gosimple
+  - govet
+  - ineffassign
   - misspell
   - revive
+  - staticcheck
+  - testifylint
+  - unused
 
 linter-settings:
   godot:
diff --git a/go.mod b/go.mod
index af4361a..6e9fd6f 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module github.com/prometheus/procfs
 
-go 1.21
+go 1.20
 
 require (
 	github.com/google/go-cmp v0.6.0
diff --git a/sysfs/system_cpu.go b/sysfs/system_cpu.go
index 5b1bec8..a68c6d9 100644
--- a/sysfs/system_cpu.go
+++ b/sysfs/system_cpu.go
@@ -132,6 +132,16 @@ func (c CPU) ThermalThrottle() (*CPUThermalThrottle, error) {
 	return t, nil
 }
 
+// Online returns the online status of a CPU from `/sys/devices/system/cpu/cpuN/online`.
+func (c CPU) Online() (bool, error) {
+	cpuPath := filepath.Join(string(c), "online")
+	str, err := util.SysReadFile(cpuPath)
+	if err != nil {
+		return false, err
+	}
+	return str == "1", nil
+}
+
 func parseCPUThermalThrottle(cpuPath string) (*CPUThermalThrottle, error) {
 	t := CPUThermalThrottle{}
 	var err error


Test patch:
diff --git a/sysfs/system_cpu_test.go b/sysfs/system_cpu_test.go
index 577c118..a39c570 100644
--- a/sysfs/system_cpu_test.go
+++ b/sysfs/system_cpu_test.go
@@ -18,6 +18,7 @@ package sysfs
 
 import (
 	"errors"
+	"os"
 	"reflect"
 	"testing"
 )
@@ -63,6 +64,34 @@ func TestCPUTopology(t *testing.T) {
 	}
 }
 
+func TestCPUOnline(t *testing.T) {
+	fs, err := NewFS(sysTestFixtures)
+	if err != nil {
+		t.Fatal(err)
+	}
+	cpus, err := fs.CPUs()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if want, have := 3, len(cpus); want != have {
+		t.Errorf("incorrect number of CPUs, have %v, want %v", want, have)
+	}
+	cpu0Online, err := cpus[0].Online()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if want, have := true, cpu0Online; want != have {
+		t.Errorf("incorrect online status, have %v, want %v", want, have)
+	}
+	cpu1Online, err := cpus[1].Online()
+	if err != nil && !errors.Is(err, os.ErrNotExist) {
+		t.Fatal(err)
+	}
+	if want, have := false, cpu1Online; want != have {
+		t.Errorf("incorrect online status, have %v, want %v", want, have)
+	}
+}
+
 func TestCPUThermalThrottle(t *testing.T) {
 	fs, err := NewFS(sysTestFixtures)
 	if err != nil {
diff --git a/testdata/fixtures.ttar b/testdata/fixtures.ttar
index a998b27..61e879e 100644
--- a/testdata/fixtures.ttar
+++ b/testdata/fixtures.ttar
@@ -13441,6 +13441,11 @@ Mode: 775
 Path: fixtures/sys/devices/system/cpu/cpu0/cpufreq
 SymlinkTo: ../cpufreq/policy0
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/devices/system/cpu/cpu0/online
+Lines: 1
+1EOF
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Directory: fixtures/sys/devices/system/cpu/cpu0/thermal_throttle
 Mode: 755
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -