Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
dbe4c8c
improving nvme collector
ShashwatHiregoudar May 9, 2025
4ed3590
correcting the logger
ShashwatHiregoudar May 9, 2025
875c524
Fix macos filesystem collector cgo memory leak (#3315)
charlie0129 May 15, 2025
bcfdb0a
fix: darwin netdev i/o bytes metric (#3336)
siavashs May 18, 2025
bfef503
build(deps): bump github.com/mdlayher/wifi from 0.3.1 to 0.5.0 (#3323)
dependabot[bot] May 18, 2025
f3de6d8
Fix ethtool returning 0 for sanitized metrics (#3335)
quatre May 19, 2025
cbdaefa
build(deps): bump golang.org/x/sys from 0.30.0 to 0.32.0 (#3324)
dependabot[bot] May 19, 2025
b224f49
chore: fix some typos (#3316)
ncharaf May 21, 2025
543263b
AIX: Add physical cpu, runqueue and flag metrics
discordianfish Mar 29, 2025
0cc7a80
AIX: Add more disk metrics
discordianfish Apr 3, 2025
048a8ab
AIX: Add paging memory metrics
discordianfish Apr 22, 2025
f48bc4d
AIX: Add transmit_queue_overflow metric to netdev collector
discordianfish Apr 22, 2025
9c0ca73
AIX: Add netadapter collision counters
discordianfish May 22, 2025
1292993
AIX: Add partition stats
discordianfish May 23, 2025
f365644
AIX: Add context switches to cpu collector
discordianfish May 23, 2025
ed39f60
AIX: Fix physical cpu usage calculation
discordianfish May 26, 2025
c230ccf
AIX: Remove redundant disk blocks metric, fix times
discordianfish May 26, 2025
53cfd7a
AIX: Fix disk blocks to bytes conversion
discordianfish May 26, 2025
f28f871
AIX: Add netinterface collector
discordianfish May 26, 2025
822731c
build(deps): bump github.com/prometheus/common from 0.62.0 to 0.63.0
dependabot[bot] May 30, 2025
9c892a9
go.mod: bump procfs to 0.16.1, go mod tidy
mfuller-lambda May 20, 2025
3ad6089
chore: Lint with golangci-lint v2 (#3301)
mrueg May 31, 2025
5919d9d
fix:use %w to wrap error (#3345)
mengxunQAQ Jun 11, 2025
7453335
correction
Jun 17, 2025
6cc12c3
making sure the tests pass
Jun 17, 2025
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
2 changes: 1 addition & 1 deletion collector/btrfs_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func (c *btrfsCollector) Update(ch chan<- prometheus.Metric) error {

for _, s := range stats {
// match up procfs and ioctl info by filesystem UUID (without dashes)
var fsUUID = strings.Replace(s.UUID, "-", "", -1)
var fsUUID = strings.ReplaceAll(s.UUID, "-", "")
ioctlStats := ioctlStatsMap[fsUUID]
c.updateBtrfsStats(ch, s, ioctlStats)
}
Expand Down
80 changes: 68 additions & 12 deletions collector/cpu_aix.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,33 +30,73 @@ import (
"github.com/prometheus/client_golang/prometheus"
)

var (
nodeCPUPhysicalSecondsDesc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "physical_seconds_total"),
"Seconds the physical CPUs spent in each mode.",
[]string{"cpu", "mode"}, nil,
)
nodeCPUSRunQueueDesc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "runqueue"),
"Length of the run queue.", []string{"cpu"}, nil,
)
nodeCPUFlagsDesc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "flags"),
"CPU flags.",
[]string{"cpu", "flag"}, nil,
)
nodeCPUContextSwitchDesc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, cpuCollectorSubsystem, "context_switches_total"),
"Number of context switches.",
[]string{"cpu"}, nil,
)
)

type cpuCollector struct {
cpu typedDesc
logger *slog.Logger
tickPerSecond int64
cpu typedDesc
cpuPhysical typedDesc
cpuRunQueue typedDesc
cpuFlags typedDesc
cpuContextSwitch typedDesc

logger *slog.Logger
tickPerSecond float64
purrTicksPerSecond float64
}

func init() {
registerCollector("cpu", defaultEnabled, NewCpuCollector)
}

func tickPerSecond() (int64, error) {
func tickPerSecond() (float64, error) {
ticks, err := C.sysconf(C._SC_CLK_TCK)
if ticks == -1 || err != nil {
return 0, fmt.Errorf("failed to get clock ticks per second: %v", err)
}
return int64(ticks), nil
return float64(ticks), nil
}

func NewCpuCollector(logger *slog.Logger) (Collector, error) {
ticks, err := tickPerSecond()
if err != nil {
return nil, err
}

pconfig, err := perfstat.PartitionStat()

if err != nil {
return nil, err
}

return &cpuCollector{
cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue},
logger: logger,
tickPerSecond: ticks,
cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue},
cpuPhysical: typedDesc{nodeCPUPhysicalSecondsDesc, prometheus.CounterValue},
cpuRunQueue: typedDesc{nodeCPUSRunQueueDesc, prometheus.GaugeValue},
cpuFlags: typedDesc{nodeCPUFlagsDesc, prometheus.GaugeValue},
cpuContextSwitch: typedDesc{nodeCPUContextSwitchDesc, prometheus.CounterValue},
logger: logger,
tickPerSecond: ticks,
purrTicksPerSecond: float64(pconfig.ProcessorMhz * 1e6),
}, nil
}

Expand All @@ -67,10 +107,26 @@ func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error {
}

for n, stat := range stats {
ch <- c.cpu.mustNewConstMetric(float64(stat.User/c.tickPerSecond), strconv.Itoa(n), "user")
ch <- c.cpu.mustNewConstMetric(float64(stat.Sys/c.tickPerSecond), strconv.Itoa(n), "system")
ch <- c.cpu.mustNewConstMetric(float64(stat.Idle/c.tickPerSecond), strconv.Itoa(n), "idle")
ch <- c.cpu.mustNewConstMetric(float64(stat.Wait/c.tickPerSecond), strconv.Itoa(n), "wait")
// LPAR metrics
ch <- c.cpu.mustNewConstMetric(float64(stat.User)/c.tickPerSecond, strconv.Itoa(n), "user")
ch <- c.cpu.mustNewConstMetric(float64(stat.Sys)/c.tickPerSecond, strconv.Itoa(n), "system")
ch <- c.cpu.mustNewConstMetric(float64(stat.Idle)/c.tickPerSecond, strconv.Itoa(n), "idle")
ch <- c.cpu.mustNewConstMetric(float64(stat.Wait)/c.tickPerSecond, strconv.Itoa(n), "wait")

// Physical CPU metrics
ch <- c.cpuPhysical.mustNewConstMetric(float64(stat.PIdle)/c.purrTicksPerSecond, strconv.Itoa(n), "pidle")
ch <- c.cpuPhysical.mustNewConstMetric(float64(stat.PUser)/c.purrTicksPerSecond, strconv.Itoa(n), "puser")
ch <- c.cpuPhysical.mustNewConstMetric(float64(stat.PSys)/c.purrTicksPerSecond, strconv.Itoa(n), "psys")
ch <- c.cpuPhysical.mustNewConstMetric(float64(stat.PWait)/c.purrTicksPerSecond, strconv.Itoa(n), "pwait")

// Run queue length
ch <- c.cpuRunQueue.mustNewConstMetric(float64(stat.RunQueue), strconv.Itoa(n))

// Flags
ch <- c.cpuFlags.mustNewConstMetric(float64(stat.SpurrFlag), strconv.Itoa(n), "spurr")

// Context switches
ch <- c.cpuContextSwitch.mustNewConstMetric(float64(stat.CSwitches), strconv.Itoa(n))
}
return nil
}
2 changes: 1 addition & 1 deletion collector/cpu_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func NewCPUCollector(logger *slog.Logger) (Collector, error) {
isolcpus, err := sfs.IsolatedCPUs()
if err != nil {
if !os.IsNotExist(err) {
return nil, fmt.Errorf("Unable to get isolated cpus: %w", err)
return nil, fmt.Errorf("unable to get isolated cpus: %w", err)
}
logger.Debug("Could not open isolated file", "error", err)
}
Expand Down
2 changes: 1 addition & 1 deletion collector/cpu_netbsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func getCPUTemperatures() (map[int]float64, error) {
}

keys := sortFilterSysmonProperties(props, "coretemp")
for idx, _ := range keys {
for idx := range keys {
convertTemperatures(props[keys[idx]], res)
}

Expand Down
6 changes: 3 additions & 3 deletions collector/cpu_vulnerabilities_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ import (
)

const (
cpuVulerabilitiesCollector = "cpu_vulnerabilities"
cpuVulnerabilitiesCollectorSubsystem = "cpu_vulnerabilities"
)

var (
vulnerabilityDesc = prometheus.NewDesc(
prometheus.BuildFQName(namespace, cpuVulerabilitiesCollector, "info"),
prometheus.BuildFQName(namespace, cpuVulnerabilitiesCollectorSubsystem, "info"),
"Details of each CPU vulnerability reported by sysfs. The value of the series is an int encoded state of the vulnerability. The same state is stored as a string in the label",
[]string{"codename", "state", "mitigation"},
nil,
Expand All @@ -37,7 +37,7 @@ var (
type cpuVulnerabilitiesCollector struct{}

func init() {
registerCollector(cpuVulerabilitiesCollector, defaultDisabled, NewVulnerabilitySysfsCollector)
registerCollector(cpuVulnerabilitiesCollectorSubsystem, defaultDisabled, NewVulnerabilitySysfsCollector)
}

func NewVulnerabilitySysfsCollector(logger *slog.Logger) (Collector, error) {
Expand Down
67 changes: 65 additions & 2 deletions collector/diskstats_aix.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,19 @@ type diskstatsCollector struct {
rbytes typedDesc
wbytes typedDesc
time typedDesc
bsize typedDesc
qdepth typedDesc

rserv typedDesc
wserv typedDesc

xfers typedDesc
xrate typedDesc

deviceFilter deviceFilter
logger *slog.Logger

tickPerSecond int64
tickPerSecond float64
}

func init() {
Expand All @@ -57,6 +65,54 @@ func NewDiskstatsCollector(logger *slog.Logger) (Collector, error) {
wbytes: typedDesc{writtenBytesDesc, prometheus.CounterValue},
time: typedDesc{ioTimeSecondsDesc, prometheus.CounterValue},

bsize: typedDesc{
prometheus.NewDesc(
prometheus.BuildFQName(namespace, diskSubsystem, "block_size_bytes"),
"Size of the block device in bytes.",
diskLabelNames, nil,
),
prometheus.GaugeValue,
},
qdepth: typedDesc{
prometheus.NewDesc(
prometheus.BuildFQName(namespace, diskSubsystem, "queue_depth"),
"Number of requests in the queue.",
diskLabelNames, nil,
),
prometheus.GaugeValue,
},
rserv: typedDesc{
prometheus.NewDesc(
prometheus.BuildFQName(namespace, diskSubsystem, "read_time_seconds_total"),
"The total time spent servicing read requests.",
diskLabelNames, nil,
),
prometheus.CounterValue,
},
wserv: typedDesc{
prometheus.NewDesc(
prometheus.BuildFQName(namespace, diskSubsystem, "write_time_seconds_total"),
"The total time spent servicing write requests.",
diskLabelNames, nil,
),
prometheus.CounterValue,
},
xfers: typedDesc{
prometheus.NewDesc(
prometheus.BuildFQName(namespace, diskSubsystem, "transfers_total"),
"The total number of transfers to/from disk.",
diskLabelNames, nil,
),
prometheus.CounterValue,
},
xrate: typedDesc{
prometheus.NewDesc(
prometheus.BuildFQName(namespace, diskSubsystem, "transfers_to_disk_total"),
"The total number of transfers from disk.",
diskLabelNames, nil,
),
prometheus.CounterValue,
},
deviceFilter: deviceFilter,
logger: logger,

Expand All @@ -76,7 +132,14 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
}
ch <- c.rbytes.mustNewConstMetric(float64(stat.Rblks*512), stat.Name)
ch <- c.wbytes.mustNewConstMetric(float64(stat.Wblks*512), stat.Name)
ch <- c.time.mustNewConstMetric(float64(stat.Time/c.tickPerSecond), stat.Name)
ch <- c.time.mustNewConstMetric(float64(stat.Time)/float64(c.tickPerSecond), stat.Name)

ch <- c.bsize.mustNewConstMetric(float64(stat.BSize), stat.Name)
ch <- c.qdepth.mustNewConstMetric(float64(stat.QDepth), stat.Name)
ch <- c.rserv.mustNewConstMetric(float64(stat.Rserv)/1e9, stat.Name)
ch <- c.wserv.mustNewConstMetric(float64(stat.Wserv)/1e9, stat.Name)
ch <- c.xfers.mustNewConstMetric(float64(stat.Xfers), stat.Name)
ch <- c.xrate.mustNewConstMetric(float64(stat.XRate), stat.Name)
}
return nil
}
5 changes: 4 additions & 1 deletion collector/ethtool_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ func (c *ethtoolCollector) Update(ch chan<- prometheus.Metric) error {

// Sanitizing the metric names can lead to duplicate metric names. Therefore check for clashes beforehand.
metricFQNames := make(map[string]string)
renamedStats := make(map[string]uint64, len(stats))
for metric := range stats {
metricName := SanitizeMetricName(metric)
if !c.metricsPattern.MatchString(metricName) {
Expand All @@ -467,6 +468,8 @@ func (c *ethtoolCollector) Update(ch chan<- prometheus.Metric) error {
metricFQNames[metricFQName] = ""
} else {
metricFQNames[metricFQName] = metricName
// Later we'll go look for the stat with the "sanitized" metric name, so we can copy it there already
renamedStats[metricName] = stats[metric]
}
}

Expand All @@ -484,7 +487,7 @@ func (c *ethtoolCollector) Update(ch chan<- prometheus.Metric) error {
continue
}

val := stats[metric]
val := renamedStats[metric]

// Check to see if this metric exists; if not then create it and store it in c.entries.
entry := c.entryWithCreate(metric, metricFQName)
Expand Down
14 changes: 10 additions & 4 deletions collector/ethtool_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,16 +212,18 @@ func (e *EthtoolFixture) LinkInfo(intf string) (ethtool.EthtoolCmd, error) {

items := strings.Split(line, ": ")
if items[0] == "Supported pause frame use" {
if items[1] == "Symmetric" {
switch items[1] {
case "Symmetric":
res.Supported |= (1 << unix.ETHTOOL_LINK_MODE_Pause_BIT)
} else if items[1] == "Receive-only" {
case "Receive-only":
res.Supported |= (1 << unix.ETHTOOL_LINK_MODE_Asym_Pause_BIT)
}
}
if items[0] == "Advertised pause frame use" {
if items[1] == "Symmetric" {
switch items[1] {
case "Symmetric":
res.Advertising |= (1 << unix.ETHTOOL_LINK_MODE_Pause_BIT)
} else if items[1] == "Receive-only" {
case "Receive-only":
res.Advertising |= (1 << unix.ETHTOOL_LINK_MODE_Asym_Pause_BIT)
}
}
Expand Down Expand Up @@ -269,6 +271,7 @@ func NewEthtoolTestCollector(logger *slog.Logger) (Collector, error) {

func TestBuildEthtoolFQName(t *testing.T) {
testcases := map[string]string{
"port.rx_errors": "node_ethtool_port_received_errors",
"rx_errors": "node_ethtool_received_errors",
"Queue[0] AllocFails": "node_ethtool_queue_0_allocfails",
"Tx LPI entry count": "node_ethtool_transmitted_lpi_entry_count",
Expand All @@ -292,6 +295,9 @@ node_ethtool_align_errors{device="eth0"} 0
# HELP node_ethtool_info A metric with a constant '1' value labeled by bus_info, device, driver, expansion_rom_version, firmware_version, version.
# TYPE node_ethtool_info gauge
node_ethtool_info{bus_info="0000:00:1f.6",device="eth0",driver="e1000e",expansion_rom_version="",firmware_version="0.5-4",version="5.11.0-22-generic"} 1
# HELP node_ethtool_port_received_dropped Network interface port_rx_dropped
# TYPE node_ethtool_port_received_dropped untyped
node_ethtool_port_received_dropped{device="eth0"} 12028
# HELP node_ethtool_received_broadcast Network interface rx_broadcast
# TYPE node_ethtool_received_broadcast untyped
node_ethtool_received_broadcast{device="eth0"} 5792
Expand Down
6 changes: 3 additions & 3 deletions collector/filesystem_aix.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) {
mountPoint: stat.MountPoint,
fsType: fstype,
},
size: float64(stat.TotalBlocks / 512.0),
free: float64(stat.FreeBlocks / 512.0),
avail: float64(stat.FreeBlocks / 512.0), // AIX doesn't distinguish between free and available blocks.
size: float64(stat.TotalBlocks * 512.0),
free: float64(stat.FreeBlocks * 512.0),
avail: float64(stat.FreeBlocks * 512.0), // AIX doesn't distinguish between free and available blocks.
files: float64(stat.TotalInodes),
filesFree: float64(stat.FreeInodes),
ro: ro,
Expand Down
4 changes: 2 additions & 2 deletions collector/filesystem_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ func parseFilesystemLabels(r io.Reader) ([]filesystemLabels, error) {

// Ensure we handle the translation of \040 and \011
// as per fstab(5).
parts[4] = strings.Replace(parts[4], "\\040", " ", -1)
parts[4] = strings.Replace(parts[4], "\\011", "\t", -1)
parts[4] = strings.ReplaceAll(parts[4], "\\040", " ")
parts[4] = strings.ReplaceAll(parts[4], "\\011", "\t")

filesystems = append(filesystems, filesystemLabels{
device: parts[m+3],
Expand Down
Loading