Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose s390x CPU Topology to Prometheus #3610

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions info/v1/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,12 @@ type MachineInfo struct {
// The number of cpu sockets in this machine.
NumSockets int `json:"num_sockets"`

// The number of cpu books in this machine.
NumBooks int `json:"num_books,omitempty"`

// The number of cpu drawers in this machine.
NumDrawers int `json:"num_drawers,omitempty"`

// Maximum clock speed for the cores, in KHz.
CpuFrequency uint64 `json:"cpu_frequency_khz"`

Expand Down Expand Up @@ -263,6 +269,8 @@ func (m *MachineInfo) Clone() *MachineInfo {
NumCores: m.NumCores,
NumPhysicalCores: m.NumPhysicalCores,
NumSockets: m.NumSockets,
NumBooks: m.NumBooks,
NumDrawers: m.NumDrawers,
CpuFrequency: m.CpuFrequency,
MemoryCapacity: m.MemoryCapacity,
SwapCapacity: m.SwapCapacity,
Expand Down
2 changes: 2 additions & 0 deletions info/v1/machine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ func getFakeMachineInfo() MachineInfo {
NumCores: 1,
NumPhysicalCores: 2,
NumSockets: 3,
NumBooks: 1,
NumDrawers: 1,
CpuFrequency: 4,
MemoryCapacity: 5,
SwapCapacity: 6,
Expand Down
2 changes: 2 additions & 0 deletions machine/info.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ func Info(sysFs sysfs.SysFs, fsInfo fs.FsInfo, inHostNamespace bool) (*info.Mach
NumCores: numCores,
NumPhysicalCores: GetPhysicalCores(cpuinfo),
NumSockets: GetSockets(cpuinfo),
NumBooks: GetBooks(cpuinfo),
NumDrawers: GetDrawers(cpuinfo),
CpuFrequency: clockSpeed,
MemoryCapacity: memoryCapacity,
MemoryByType: memoryByType,
Expand Down
38 changes: 38 additions & 0 deletions machine/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"os"
"path"
"regexp"
"runtime"

"strconv"
"strings"
Expand All @@ -37,6 +38,8 @@ import (
var (
coreRegExp = regexp.MustCompile(`(?m)^core id\s*:\s*([0-9]+)$`)
nodeRegExp = regexp.MustCompile(`(?m)^physical id\s*:\s*([0-9]+)$`)
bookRegExp = regexp.MustCompile(`(?m)^book id\s*:\s*([0-9]+)$`)
drawerRegExp = regexp.MustCompile(`(?m)^drawer id\s*:\s*([0-9]+)$`)
// Power systems have a different format so cater for both
cpuClockSpeedMHz = regexp.MustCompile(`(?:cpu MHz|CPU MHz|clock)\s*:\s*([0-9]+\.[0-9]+)(?:MHz)?`)
memoryCapacityRegexp = regexp.MustCompile(`MemTotal:\s*([0-9]+) kB`)
Expand Down Expand Up @@ -96,6 +99,41 @@ func GetSockets(procInfo []byte) int {
return numSocket
}

// GetBooks returns number of CPU books reading from sysfs cpu path
func GetBooks(procInfo []byte) int {
if runtime.GOARCH != "s390x" {
return 0
}
numBook := getUniqueMatchesCount(string(procInfo), bookRegExp)
if numBook == 0 {
// read number of books from /sys/bus/cpu/devices/cpu*/topology/book_id to deal with processors
// for which 'book id' is not available in /proc/cpuinfo
numBook = sysfs.GetUniqueCPUPropertyCount(cpuAttributesPath, sysfs.CPUBookID)
}
if numBook == 0 {
klog.Errorf("Cannot read number of books correctly, number of books set to %d", numBook)
}
return numBook
}

// GetDrawer returns number of CPU drawerss reading from sysfs cpu path
func GetDrawers(procInfo []byte) int {
if runtime.GOARCH != "s390x" {
return 0
}
numDrawer := getUniqueMatchesCount(string(procInfo), drawerRegExp)
if numDrawer == 0 {
// read number of books from /sys/bus/cpu/devices/cpu*/topology/book_id to deal with processors
// read number of drawers from /sys/bus/cpu/devices/cpu*/topology/drawer_id to deal with processors
// for which 'drawer id' is not available in /proc/cpuinfo
numDrawer = sysfs.GetUniqueCPUPropertyCount(cpuAttributesPath, sysfs.CPUDrawerID)
}
if numDrawer == 0 {
klog.Errorf("Cannot read number of drawers correctly, number of drawers set to %d", numDrawer)
}
return numDrawer
}

// GetClockSpeed returns the CPU clock speed, given a []byte formatted as the /proc/cpuinfo file.
func GetClockSpeed(procInfo []byte) (uint64, error) {
// First look through sys to find a max supported cpu frequency.
Expand Down
16 changes: 16 additions & 0 deletions metrics/prometheus_machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,22 @@ func NewPrometheusMachineCollector(i infoProvider, includedMetrics container.Met
return metricValues{{value: float64(machineInfo.NumSockets), timestamp: machineInfo.Timestamp}}
},
},
{
name: "machine_cpu_books",
help: "Number of CPU books.",
valueType: prometheus.GaugeValue,
getValues: func(machineInfo *info.MachineInfo) metricValues {
return metricValues{{value: float64(machineInfo.NumBooks), timestamp: machineInfo.Timestamp}}
},
},
{
name: "machine_cpu_drawers",
help: "Number of CPU drawers.",
valueType: prometheus.GaugeValue,
getValues: func(machineInfo *info.MachineInfo) metricValues {
return metricValues{{value: float64(machineInfo.NumDrawers), timestamp: machineInfo.Timestamp}}
},
},
{
name: "machine_memory_bytes",
help: "Amount of memory installed on the machine.",
Expand Down
6 changes: 6 additions & 0 deletions metrics/testdata/prometheus_machine_metrics
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# HELP machine_cpu_books Number of CPU books.
# TYPE machine_cpu_books gauge
machine_cpu_books{boot_id="boot-id-test",machine_id="machine-id-test",system_uuid="system-uuid-test"} 0 1395066363000
# HELP machine_cpu_cache_capacity_bytes Cache size in bytes assigned to NUMA node and CPU core.
# TYPE machine_cpu_cache_capacity_bytes gauge
machine_cpu_cache_capacity_bytes{boot_id="boot-id-test",core_id="",level="3",machine_id="machine-id-test",node_id="1",system_uuid="system-uuid-test",type="Unified"} 8.388608e+06 1395066363000
Expand Down Expand Up @@ -28,6 +31,9 @@ machine_cpu_cache_capacity_bytes{boot_id="boot-id-test",core_id="7",level="2",ma
# HELP machine_cpu_cores Number of logical CPU cores.
# TYPE machine_cpu_cores gauge
machine_cpu_cores{boot_id="boot-id-test",machine_id="machine-id-test",system_uuid="system-uuid-test"} 4 1395066363000
# HELP machine_cpu_drawers Number of CPU drawers.
# TYPE machine_cpu_drawers gauge
machine_cpu_drawers{boot_id="boot-id-test",machine_id="machine-id-test",system_uuid="system-uuid-test"} 0 1395066363000
# HELP machine_cpu_physical_cores Number of physical CPU cores.
# TYPE machine_cpu_physical_cores gauge
machine_cpu_physical_cores{boot_id="boot-id-test",machine_id="machine-id-test",system_uuid="system-uuid-test"} 1 1395066363000
Expand Down
6 changes: 6 additions & 0 deletions utils/sysfs/sysfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ const (
// (rather than the kernel's). The actual value is architecture and platform dependent.
CPUCoreID = "core_id"

// On some architecture there exists additional level of book and drawer id
// CPUBookID is the book ID of cpu#. Typically corresponds to a physical book number.
CPUBookID = "book_id"
// CPUDrawerID is the drawer ID of cpu#. Typically corresponds to a physical drawer number.
CPUDrawerID = "drawer_id"

coreIDFilePath = "/" + sysFsCPUTopology + "/core_id"
packageIDFilePath = "/" + sysFsCPUTopology + "/physical_package_id"
bookIDFilePath = "/" + sysFsCPUTopology + "/book_id"
Expand Down