mirror of
https://github.com/prometheus/node_exporter.git
synced 2024-11-09 23:24:09 -08:00
Merge branch 'master' into entropy
Signed-off-by: binjip978 <binjip978@gmail.com>
This commit is contained in:
commit
488d10ef48
|
@ -3,7 +3,7 @@
|
||||||
* [CHANGE] Improve filter flag names.
|
* [CHANGE] Improve filter flag names.
|
||||||
* [CHANGE]
|
* [CHANGE]
|
||||||
* [FEATURE]
|
* [FEATURE]
|
||||||
* [ENHANCEMENT]
|
* [ENHANCEMENT] Include TCP OutRsts in netstat metrics
|
||||||
* [BUGFIX]
|
* [BUGFIX]
|
||||||
|
|
||||||
## 1.0.1 / 2020-06-15
|
## 1.0.1 / 2020-06-15
|
||||||
|
|
|
@ -84,7 +84,7 @@ func parseARPEntries(data io.Reader) (map[string]uint32, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := scanner.Err(); err != nil {
|
if err := scanner.Err(); err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse ARP info: %s", err)
|
return nil, fmt.Errorf("failed to parse ARP info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return entries, nil
|
return entries, nil
|
||||||
|
@ -93,7 +93,7 @@ func parseARPEntries(data io.Reader) (map[string]uint32, error) {
|
||||||
func (c *arpCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *arpCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
entries, err := getARPEntries()
|
entries, err := getARPEntries()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not get ARP entries: %s", err)
|
return fmt.Errorf("could not get ARP entries: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for device, entryCount := range entries {
|
for device, entryCount := range entries {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
@ -59,7 +60,7 @@ func (c *bondingCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
statusfile := sysFilePath("class/net")
|
statusfile := sysFilePath("class/net")
|
||||||
bondingStats, err := readBondingStats(statusfile)
|
bondingStats, err := readBondingStats(statusfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
level.Debug(c.logger).Log("msg", "Not collecting bonding, file does not exist", "file", statusfile)
|
level.Debug(c.logger).Log("msg", "Not collecting bonding, file does not exist", "file", statusfile)
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
|
@ -86,7 +87,7 @@ func readBondingStats(root string) (status map[string][2]int, err error) {
|
||||||
sstat := [2]int{0, 0}
|
sstat := [2]int{0, 0}
|
||||||
for _, slave := range strings.Fields(string(slaves)) {
|
for _, slave := range strings.Fields(string(slaves)) {
|
||||||
state, err := ioutil.ReadFile(filepath.Join(root, master, fmt.Sprintf("lower_%s", slave), "bonding_slave", "mii_status"))
|
state, err := ioutil.ReadFile(filepath.Join(root, master, fmt.Sprintf("lower_%s", slave), "bonding_slave", "mii_status"))
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
// some older? kernels use slave_ prefix
|
// some older? kernels use slave_ prefix
|
||||||
state, err = ioutil.ReadFile(filepath.Join(root, master, fmt.Sprintf("slave_%s", slave), "bonding_slave", "mii_status"))
|
state, err = ioutil.ReadFile(filepath.Join(root, master, fmt.Sprintf("slave_%s", slave), "bonding_slave", "mii_status"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,7 @@ func init() {
|
||||||
func NewBtrfsCollector(logger log.Logger) (Collector, error) {
|
func NewBtrfsCollector(logger log.Logger) (Collector, error) {
|
||||||
fs, err := btrfs.NewFS(*sysPath)
|
fs, err := btrfs.NewFS(*sysPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to open sysfs: %v", err)
|
return nil, fmt.Errorf("failed to open sysfs: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &btrfsCollector{
|
return &btrfsCollector{
|
||||||
|
@ -51,7 +51,7 @@ func NewBtrfsCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *btrfsCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *btrfsCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
stats, err := c.fs.Stats()
|
stats, err := c.fs.Stats()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to retrieve Btrfs stats: %v", err)
|
return fmt.Errorf("failed to retrieve Btrfs stats: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, s := range stats {
|
for _, s := range stats {
|
||||||
|
|
|
@ -59,7 +59,7 @@ func NewBuddyinfoCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *buddyinfoCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *buddyinfoCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
buddyInfo, err := c.fs.BuddyInfo()
|
buddyInfo, err := c.fs.BuddyInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get buddyinfo: %s", err)
|
return fmt.Errorf("couldn't get buddyinfo: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
level.Debug(c.logger).Log("msg", "Set node_buddy", "buddyInfo", buddyInfo)
|
level.Debug(c.logger).Log("msg", "Set node_buddy", "buddyInfo", buddyInfo)
|
||||||
|
|
|
@ -189,7 +189,7 @@ func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
diskStats, err := iostat.ReadDriveStats()
|
diskStats, err := iostat.ReadDriveStats()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get diskstats: %s", err)
|
return fmt.Errorf("couldn't get diskstats: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, stats := range diskStats {
|
for _, stats := range diskStats {
|
||||||
|
|
|
@ -187,7 +187,7 @@ func NewDiskstatsCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
diskStats, err := getDiskStats()
|
diskStats, err := getDiskStats()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get diskstats: %s", err)
|
return fmt.Errorf("couldn't get diskstats: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for dev, stats := range diskStats {
|
for dev, stats := range diskStats {
|
||||||
|
@ -203,7 +203,7 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
}
|
}
|
||||||
v, err := strconv.ParseFloat(value, 64)
|
v, err := strconv.ParseFloat(value, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid value %s in diskstats: %s", value, err)
|
return fmt.Errorf("invalid value %s in diskstats: %w", value, err)
|
||||||
}
|
}
|
||||||
ch <- c.descs[i].mustNewConstMetric(v, dev)
|
ch <- c.descs[i].mustNewConstMetric(v, dev)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -188,7 +189,7 @@ func (c *drbdCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
statsFile := procFilePath("drbd")
|
statsFile := procFilePath("drbd")
|
||||||
file, err := os.Open(statsFile)
|
file, err := os.Open(statsFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
level.Debug(c.logger).Log("msg", "stats file does not exist, skipping", "file", statsFile, "err", err)
|
level.Debug(c.logger).Log("msg", "stats file does not exist, skipping", "file", statsFile, "err", err)
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,28 +86,28 @@ func (c *edacCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
|
|
||||||
value, err := readUintFromFile(filepath.Join(controller, "ce_count"))
|
value, err := readUintFromFile(filepath.Join(controller, "ce_count"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get ce_count for controller %s: %s", controllerNumber, err)
|
return fmt.Errorf("couldn't get ce_count for controller %s: %w", controllerNumber, err)
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.ceCount, prometheus.CounterValue, float64(value), controllerNumber)
|
c.ceCount, prometheus.CounterValue, float64(value), controllerNumber)
|
||||||
|
|
||||||
value, err = readUintFromFile(filepath.Join(controller, "ce_noinfo_count"))
|
value, err = readUintFromFile(filepath.Join(controller, "ce_noinfo_count"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get ce_noinfo_count for controller %s: %s", controllerNumber, err)
|
return fmt.Errorf("couldn't get ce_noinfo_count for controller %s: %w", controllerNumber, err)
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.csRowCECount, prometheus.CounterValue, float64(value), controllerNumber, "unknown")
|
c.csRowCECount, prometheus.CounterValue, float64(value), controllerNumber, "unknown")
|
||||||
|
|
||||||
value, err = readUintFromFile(filepath.Join(controller, "ue_count"))
|
value, err = readUintFromFile(filepath.Join(controller, "ue_count"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get ue_count for controller %s: %s", controllerNumber, err)
|
return fmt.Errorf("couldn't get ue_count for controller %s: %w", controllerNumber, err)
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.ueCount, prometheus.CounterValue, float64(value), controllerNumber)
|
c.ueCount, prometheus.CounterValue, float64(value), controllerNumber)
|
||||||
|
|
||||||
value, err = readUintFromFile(filepath.Join(controller, "ue_noinfo_count"))
|
value, err = readUintFromFile(filepath.Join(controller, "ue_noinfo_count"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get ue_noinfo_count for controller %s: %s", controllerNumber, err)
|
return fmt.Errorf("couldn't get ue_noinfo_count for controller %s: %w", controllerNumber, err)
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.csRowUECount, prometheus.CounterValue, float64(value), controllerNumber, "unknown")
|
c.csRowUECount, prometheus.CounterValue, float64(value), controllerNumber, "unknown")
|
||||||
|
@ -126,14 +126,14 @@ func (c *edacCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
|
|
||||||
value, err = readUintFromFile(filepath.Join(csrow, "ce_count"))
|
value, err = readUintFromFile(filepath.Join(csrow, "ce_count"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get ce_count for controller/csrow %s/%s: %s", controllerNumber, csrowNumber, err)
|
return fmt.Errorf("couldn't get ce_count for controller/csrow %s/%s: %w", controllerNumber, csrowNumber, err)
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.csRowCECount, prometheus.CounterValue, float64(value), controllerNumber, csrowNumber)
|
c.csRowCECount, prometheus.CounterValue, float64(value), controllerNumber, csrowNumber)
|
||||||
|
|
||||||
value, err = readUintFromFile(filepath.Join(csrow, "ue_count"))
|
value, err = readUintFromFile(filepath.Join(csrow, "ue_count"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get ue_count for controller/csrow %s/%s: %s", controllerNumber, csrowNumber, err)
|
return fmt.Errorf("couldn't get ue_count for controller/csrow %s/%s: %w", controllerNumber, csrowNumber, err)
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.csRowUECount, prometheus.CounterValue, float64(value), controllerNumber, csrowNumber)
|
c.csRowUECount, prometheus.CounterValue, float64(value), controllerNumber, csrowNumber)
|
||||||
|
|
|
@ -46,12 +46,12 @@ func NewFileFDStatCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *fileFDStatCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *fileFDStatCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
fileFDStat, err := parseFileFDStats(procFilePath("sys/fs/file-nr"))
|
fileFDStat, err := parseFileFDStats(procFilePath("sys/fs/file-nr"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get file-nr: %s", err)
|
return fmt.Errorf("couldn't get file-nr: %w", err)
|
||||||
}
|
}
|
||||||
for name, value := range fileFDStat {
|
for name, value := range fileFDStat {
|
||||||
v, err := strconv.ParseFloat(value, 64)
|
v, err := strconv.ParseFloat(value, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid value %s in file-nr: %s", value, err)
|
return fmt.Errorf("invalid value %s in file-nr: %w", value, err)
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
prometheus.NewDesc(
|
prometheus.NewDesc(
|
||||||
|
|
|
@ -17,6 +17,7 @@ package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -139,7 +140,7 @@ func stuckMountWatcher(mountPoint string, success chan struct{}, logger log.Logg
|
||||||
|
|
||||||
func mountPointDetails(logger log.Logger) ([]filesystemLabels, error) {
|
func mountPointDetails(logger log.Logger) ([]filesystemLabels, error) {
|
||||||
file, err := os.Open(procFilePath("1/mounts"))
|
file, err := os.Open(procFilePath("1/mounts"))
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
// Fallback to `/proc/mounts` if `/proc/1/mounts` is missing due hidepid.
|
// Fallback to `/proc/mounts` if `/proc/1/mounts` is missing due hidepid.
|
||||||
level.Debug(logger).Log("msg", "Reading root mounts failed, falling back to system mounts", "err", err)
|
level.Debug(logger).Log("msg", "Reading root mounts failed, falling back to system mounts", "err", err)
|
||||||
file, err = os.Open(procFilePath("mounts"))
|
file, err = os.Open(procFilePath("mounts"))
|
||||||
|
|
|
@ -1886,6 +1886,9 @@ node_netstat_Tcp_InErrs 5
|
||||||
# HELP node_netstat_Tcp_InSegs Statistic TcpInSegs.
|
# HELP node_netstat_Tcp_InSegs Statistic TcpInSegs.
|
||||||
# TYPE node_netstat_Tcp_InSegs untyped
|
# TYPE node_netstat_Tcp_InSegs untyped
|
||||||
node_netstat_Tcp_InSegs 5.7252008e+07
|
node_netstat_Tcp_InSegs 5.7252008e+07
|
||||||
|
# HELP node_netstat_Tcp_OutRsts Statistic TcpOutRsts.
|
||||||
|
# TYPE node_netstat_Tcp_OutRsts untyped
|
||||||
|
node_netstat_Tcp_OutRsts 1003
|
||||||
# HELP node_netstat_Tcp_OutSegs Statistic TcpOutSegs.
|
# HELP node_netstat_Tcp_OutSegs Statistic TcpOutSegs.
|
||||||
# TYPE node_netstat_Tcp_OutSegs untyped
|
# TYPE node_netstat_Tcp_OutSegs untyped
|
||||||
node_netstat_Tcp_OutSegs 5.4915039e+07
|
node_netstat_Tcp_OutSegs 5.4915039e+07
|
||||||
|
|
|
@ -1958,6 +1958,9 @@ node_netstat_Tcp_InErrs 5
|
||||||
# HELP node_netstat_Tcp_InSegs Statistic TcpInSegs.
|
# HELP node_netstat_Tcp_InSegs Statistic TcpInSegs.
|
||||||
# TYPE node_netstat_Tcp_InSegs untyped
|
# TYPE node_netstat_Tcp_InSegs untyped
|
||||||
node_netstat_Tcp_InSegs 5.7252008e+07
|
node_netstat_Tcp_InSegs 5.7252008e+07
|
||||||
|
# HELP node_netstat_Tcp_OutRsts Statistic TcpOutRsts.
|
||||||
|
# TYPE node_netstat_Tcp_OutRsts untyped
|
||||||
|
node_netstat_Tcp_OutRsts 1003
|
||||||
# HELP node_netstat_Tcp_OutSegs Statistic TcpOutSegs.
|
# HELP node_netstat_Tcp_OutSegs Statistic TcpOutSegs.
|
||||||
# TYPE node_netstat_Tcp_OutSegs untyped
|
# TYPE node_netstat_Tcp_OutSegs untyped
|
||||||
node_netstat_Tcp_OutSegs 5.4915039e+07
|
node_netstat_Tcp_OutSegs 5.4915039e+07
|
||||||
|
|
|
@ -424,7 +424,7 @@ func (c *hwMonCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
|
|
||||||
hwmonFiles, err := ioutil.ReadDir(hwmonPathName)
|
hwmonFiles, err := ioutil.ReadDir(hwmonPathName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
level.Debug(c.logger).Log("msg", "hwmon collector metrics are not available for this system")
|
level.Debug(c.logger).Log("msg", "hwmon collector metrics are not available for this system")
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -108,11 +109,11 @@ func (c *infinibandCollector) pushCounter(ch chan<- prometheus.Metric, name stri
|
||||||
func (c *infinibandCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *infinibandCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
devices, err := c.fs.InfiniBandClass()
|
devices, err := c.fs.InfiniBandClass()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
level.Debug(c.logger).Log("msg", "infiniband statistics not found, skipping")
|
level.Debug(c.logger).Log("msg", "infiniband statistics not found, skipping")
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
return fmt.Errorf("error obtaining InfiniBand class info: %s", err)
|
return fmt.Errorf("error obtaining InfiniBand class info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, device := range devices {
|
for _, device := range devices {
|
||||||
|
|
|
@ -34,13 +34,13 @@ var (
|
||||||
func (c *interruptsCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
func (c *interruptsCollector) Update(ch chan<- prometheus.Metric) (err error) {
|
||||||
interrupts, err := getInterrupts()
|
interrupts, err := getInterrupts()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get interrupts: %s", err)
|
return fmt.Errorf("couldn't get interrupts: %w", err)
|
||||||
}
|
}
|
||||||
for name, interrupt := range interrupts {
|
for name, interrupt := range interrupts {
|
||||||
for cpuNo, value := range interrupt.values {
|
for cpuNo, value := range interrupt.values {
|
||||||
fv, err := strconv.ParseFloat(value, 64)
|
fv, err := strconv.ParseFloat(value, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid value %s in interrupts: %s", value, err)
|
return fmt.Errorf("invalid value %s in interrupts: %w", value, err)
|
||||||
}
|
}
|
||||||
ch <- c.desc.mustNewConstMetric(fv, strconv.Itoa(cpuNo), name, interrupt.info, interrupt.devices)
|
ch <- c.desc.mustNewConstMetric(fv, strconv.Itoa(cpuNo), name, interrupt.info, interrupt.devices)
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,7 +101,7 @@ var (
|
||||||
func (c *interruptsCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *interruptsCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
interrupts, err := getInterrupts()
|
interrupts, err := getInterrupts()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get interrupts: %s", err)
|
return fmt.Errorf("couldn't get interrupts: %w", err)
|
||||||
}
|
}
|
||||||
for dev, interrupt := range interrupts {
|
for dev, interrupt := range interrupts {
|
||||||
for cpuNo, value := range interrupt.values {
|
for cpuNo, value := range interrupt.values {
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
|
@ -140,11 +141,11 @@ func (c *ipvsCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
ipvsStats, err := c.fs.IPVSStats()
|
ipvsStats, err := c.fs.IPVSStats()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Cannot access ipvs metrics, report no error.
|
// Cannot access ipvs metrics, report no error.
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
level.Debug(c.logger).Log("msg", "ipvs collector metrics are not available for this system")
|
level.Debug(c.logger).Log("msg", "ipvs collector metrics are not available for this system")
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
return fmt.Errorf("could not get IPVS stats: %s", err)
|
return fmt.Errorf("could not get IPVS stats: %w", err)
|
||||||
}
|
}
|
||||||
ch <- c.connections.mustNewConstMetric(float64(ipvsStats.Connections))
|
ch <- c.connections.mustNewConstMetric(float64(ipvsStats.Connections))
|
||||||
ch <- c.incomingPackets.mustNewConstMetric(float64(ipvsStats.IncomingPackets))
|
ch <- c.incomingPackets.mustNewConstMetric(float64(ipvsStats.IncomingPackets))
|
||||||
|
@ -154,7 +155,7 @@ func (c *ipvsCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
|
|
||||||
backendStats, err := c.fs.IPVSBackendStatus()
|
backendStats, err := c.fs.IPVSBackendStatus()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not get backend status: %s", err)
|
return fmt.Errorf("could not get backend status: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sums := map[string]ipvsBackendStatus{}
|
sums := map[string]ipvsBackendStatus{}
|
||||||
|
|
|
@ -48,7 +48,7 @@ func NewLoadavgCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
loads, err := getLoad()
|
loads, err := getLoad()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get load: %s", err)
|
return fmt.Errorf("couldn't get load: %w", err)
|
||||||
}
|
}
|
||||||
for i, load := range loads {
|
for i, load := range loads {
|
||||||
level.Debug(c.logger).Log("msg", "return load", "index", i, "load", load)
|
level.Debug(c.logger).Log("msg", "return load", "index", i, "load", load)
|
||||||
|
|
|
@ -45,7 +45,7 @@ func parseLoad(data string) (loads []float64, err error) {
|
||||||
for i, load := range parts[0:3] {
|
for i, load := range parts[0:3] {
|
||||||
loads[i], err = strconv.ParseFloat(load, 64)
|
loads[i], err = strconv.ParseFloat(load, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not parse load '%s': %s", load, err)
|
return nil, fmt.Errorf("could not parse load '%s': %w", load, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return loads, nil
|
return loads, nil
|
||||||
|
|
|
@ -92,7 +92,7 @@ func NewLogindCollector(logger log.Logger) (Collector, error) {
|
||||||
func (lc *logindCollector) Update(ch chan<- prometheus.Metric) error {
|
func (lc *logindCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
c, err := newDbus()
|
c, err := newDbus()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to connect to dbus: %s", err)
|
return fmt.Errorf("unable to connect to dbus: %w", err)
|
||||||
}
|
}
|
||||||
defer c.conn.Close()
|
defer c.conn.Close()
|
||||||
|
|
||||||
|
@ -102,12 +102,12 @@ func (lc *logindCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
func collectMetrics(ch chan<- prometheus.Metric, c logindInterface) error {
|
func collectMetrics(ch chan<- prometheus.Metric, c logindInterface) error {
|
||||||
seats, err := c.listSeats()
|
seats, err := c.listSeats()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get seats: %s", err)
|
return fmt.Errorf("unable to get seats: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionList, err := c.listSessions()
|
sessionList, err := c.listSessions()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get sessions: %s", err)
|
return fmt.Errorf("unable to get sessions: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sessions := make(map[logindSession]float64)
|
sessions := make(map[logindSession]float64)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -94,21 +95,21 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
fs, errFs := procfs.NewFS(*procPath)
|
fs, err := procfs.NewFS(*procPath)
|
||||||
|
|
||||||
if errFs != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to open procfs: %w", errFs)
|
return fmt.Errorf("failed to open procfs: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mdStats, err := fs.MDStat()
|
mdStats, err := fs.MDStat()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
level.Debug(c.logger).Log("msg", "Not collecting mdstat, file does not exist", "file", *procPath)
|
level.Debug(c.logger).Log("msg", "Not collecting mdstat, file does not exist", "file", *procPath)
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Errorf("error parsing mdstatus: %s", err)
|
return fmt.Errorf("error parsing mdstatus: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, mdStat := range mdStats {
|
for _, mdStat := range mdStats {
|
||||||
|
|
|
@ -48,7 +48,7 @@ func (c *meminfoCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
var metricType prometheus.ValueType
|
var metricType prometheus.ValueType
|
||||||
memInfo, err := c.getMemInfo()
|
memInfo, err := c.getMemInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get meminfo: %s", err)
|
return fmt.Errorf("couldn't get meminfo: %w", err)
|
||||||
}
|
}
|
||||||
level.Debug(c.logger).Log("msg", "Set node_mem", "memInfo", memInfo)
|
level.Debug(c.logger).Log("msg", "Set node_mem", "memInfo", memInfo)
|
||||||
for k, v := range memInfo {
|
for k, v := range memInfo {
|
||||||
|
|
|
@ -54,7 +54,7 @@ func parseMemInfo(r io.Reader) (map[string]float64, error) {
|
||||||
}
|
}
|
||||||
fv, err := strconv.ParseFloat(parts[1], 64)
|
fv, err := strconv.ParseFloat(parts[1], 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid value in meminfo: %s", err)
|
return nil, fmt.Errorf("invalid value in meminfo: %w", err)
|
||||||
}
|
}
|
||||||
key := parts[0][:len(parts[0])-1] // remove trailing : from key
|
key := parts[0][:len(parts[0])-1] // remove trailing : from key
|
||||||
// Active(anon) -> Active_anon
|
// Active(anon) -> Active_anon
|
||||||
|
|
|
@ -62,7 +62,7 @@ func NewMeminfoNumaCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *meminfoNumaCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *meminfoNumaCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
metrics, err := getMemInfoNuma()
|
metrics, err := getMemInfoNuma()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get NUMA meminfo: %s", err)
|
return fmt.Errorf("couldn't get NUMA meminfo: %w", err)
|
||||||
}
|
}
|
||||||
for _, v := range metrics {
|
for _, v := range metrics {
|
||||||
desc, ok := c.metricDescs[v.metricName]
|
desc, ok := c.metricDescs[v.metricName]
|
||||||
|
@ -137,7 +137,7 @@ func parseMemInfoNuma(r io.Reader) ([]meminfoMetric, error) {
|
||||||
|
|
||||||
fv, err := strconv.ParseFloat(parts[3], 64)
|
fv, err := strconv.ParseFloat(parts[3], 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid value in meminfo: %s", err)
|
return nil, fmt.Errorf("invalid value in meminfo: %w", err)
|
||||||
}
|
}
|
||||||
switch l := len(parts); {
|
switch l := len(parts); {
|
||||||
case l == 4: // no unit
|
case l == 4: // no unit
|
||||||
|
@ -174,7 +174,7 @@ func parseMemInfoNumaStat(r io.Reader, nodeNumber string) ([]meminfoMetric, erro
|
||||||
|
|
||||||
fv, err := strconv.ParseFloat(parts[1], 64)
|
fv, err := strconv.ParseFloat(parts[1], 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("invalid value in numastat: %s", err)
|
return nil, fmt.Errorf("invalid value in numastat: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
numaStat = append(numaStat, meminfoMetric{parts[0] + "_total", prometheus.CounterValue, nodeNumber, fv})
|
numaStat = append(numaStat, meminfoMetric{parts[0] + "_total", prometheus.CounterValue, nodeNumber, fv})
|
||||||
|
|
|
@ -62,7 +62,7 @@ func (c *meminfoCollector) getMemInfo() (map[string]float64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := C.sysctl_bcstats(&bcstats); err != nil {
|
if _, err := C.sysctl_bcstats(&bcstats); err != nil {
|
||||||
return nil, fmt.Errorf("sysctl CTL_VFS VFS_GENERIC VFS_BCACHESTAT failed: %v", err)
|
return nil, fmt.Errorf("sysctl CTL_VFS VFS_GENERIC VFS_BCACHESTAT failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ps := float64(uvmexp.pagesize)
|
ps := float64(uvmexp.pagesize)
|
||||||
|
|
|
@ -43,7 +43,7 @@ func init() {
|
||||||
func NewMemoryCollector(logger log.Logger) (Collector, error) {
|
func NewMemoryCollector(logger log.Logger) (Collector, error) {
|
||||||
tmp32, err := unix.SysctlUint32("vm.stats.vm.v_page_size")
|
tmp32, err := unix.SysctlUint32("vm.stats.vm.v_page_size")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("sysctl(vm.stats.vm.v_page_size) failed: %s", err)
|
return nil, fmt.Errorf("sysctl(vm.stats.vm.v_page_size) failed: %w", err)
|
||||||
}
|
}
|
||||||
size := float64(tmp32)
|
size := float64(tmp32)
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ func (c *memoryCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
for _, m := range c.sysctls {
|
for _, m := range c.sysctls {
|
||||||
v, err := m.Value()
|
v, err := m.Value()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get memory: %s", err)
|
return fmt.Errorf("couldn't get memory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Most are gauges.
|
// Most are gauges.
|
||||||
|
@ -154,7 +154,7 @@ func (c *memoryCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
|
|
||||||
swapUsed, err := c.kvm.SwapUsedPages()
|
swapUsed, err := c.kvm.SwapUsedPages()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get kvm: %s", err)
|
return fmt.Errorf("couldn't get kvm: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
|
|
@ -61,7 +61,7 @@ func NewNetClassCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *netClassCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *netClassCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
netClass, err := c.getNetClassInfo()
|
netClass, err := c.getNetClassInfo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not get net class info: %s", err)
|
return fmt.Errorf("could not get net class info: %w", err)
|
||||||
}
|
}
|
||||||
for _, ifaceInfo := range netClass {
|
for _, ifaceInfo := range netClass {
|
||||||
upDesc := prometheus.NewDesc(
|
upDesc := prometheus.NewDesc(
|
||||||
|
@ -175,7 +175,7 @@ func (c *netClassCollector) getNetClassInfo() (sysfs.NetClass, error) {
|
||||||
netClass, err := c.fs.NetClass()
|
netClass, err := c.fs.NetClass()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return netClass, fmt.Errorf("error obtaining net class info: %s", err)
|
return netClass, fmt.Errorf("error obtaining net class info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for device := range netClass {
|
for device := range netClass {
|
||||||
|
|
|
@ -95,7 +95,7 @@ func NewNetDevCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
netDev, err := getNetDevStats(c.deviceExcludePattern, c.deviceIncludePattern, c.logger)
|
netDev, err := getNetDevStats(c.deviceExcludePattern, c.deviceIncludePattern, c.logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get netstats: %s", err)
|
return fmt.Errorf("couldn't get netstats: %w", err)
|
||||||
}
|
}
|
||||||
for dev, devStats := range netDev {
|
for dev, devStats := range netDev {
|
||||||
for key, value := range devStats {
|
for key, value := range devStats {
|
||||||
|
@ -111,7 +111,7 @@ func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
}
|
}
|
||||||
v, err := strconv.ParseFloat(value, 64)
|
v, err := strconv.ParseFloat(value, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid value %s in netstats: %s", value, err)
|
return fmt.Errorf("invalid value %s in netstats: %w", value, err)
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(desc, prometheus.CounterValue, v, dev)
|
ch <- prometheus.MustNewConstMetric(desc, prometheus.CounterValue, v, dev)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
@ -34,7 +35,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
netStatFields = kingpin.Flag("collector.netstat.fields", "Regexp of fields to return for netstat collector.").Default("^(.*_(InErrors|InErrs)|Ip_Forwarding|Ip(6|Ext)_(InOctets|OutOctets)|Icmp6?_(InMsgs|OutMsgs)|TcpExt_(Listen.*|Syncookies.*|TCPSynRetrans)|Tcp_(ActiveOpens|InSegs|OutSegs|PassiveOpens|RetransSegs|CurrEstab)|Udp6?_(InDatagrams|OutDatagrams|NoPorts|RcvbufErrors|SndbufErrors))$").String()
|
netStatFields = kingpin.Flag("collector.netstat.fields", "Regexp of fields to return for netstat collector.").Default("^(.*_(InErrors|InErrs)|Ip_Forwarding|Ip(6|Ext)_(InOctets|OutOctets)|Icmp6?_(InMsgs|OutMsgs)|TcpExt_(Listen.*|Syncookies.*|TCPSynRetrans)|Tcp_(ActiveOpens|InSegs|OutSegs|OutRsts|PassiveOpens|RetransSegs|CurrEstab)|Udp6?_(InDatagrams|OutDatagrams|NoPorts|RcvbufErrors|SndbufErrors))$").String()
|
||||||
)
|
)
|
||||||
|
|
||||||
type netStatCollector struct {
|
type netStatCollector struct {
|
||||||
|
@ -59,15 +60,15 @@ func NewNetStatCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *netStatCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *netStatCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
netStats, err := getNetStats(procFilePath("net/netstat"))
|
netStats, err := getNetStats(procFilePath("net/netstat"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get netstats: %s", err)
|
return fmt.Errorf("couldn't get netstats: %w", err)
|
||||||
}
|
}
|
||||||
snmpStats, err := getNetStats(procFilePath("net/snmp"))
|
snmpStats, err := getNetStats(procFilePath("net/snmp"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get SNMP stats: %s", err)
|
return fmt.Errorf("couldn't get SNMP stats: %w", err)
|
||||||
}
|
}
|
||||||
snmp6Stats, err := getSNMP6Stats(procFilePath("net/snmp6"))
|
snmp6Stats, err := getSNMP6Stats(procFilePath("net/snmp6"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get SNMP6 stats: %s", err)
|
return fmt.Errorf("couldn't get SNMP6 stats: %w", err)
|
||||||
}
|
}
|
||||||
// Merge the results of snmpStats into netStats (collisions are possible, but
|
// Merge the results of snmpStats into netStats (collisions are possible, but
|
||||||
// we know that the keys are always unique for the given use case).
|
// we know that the keys are always unique for the given use case).
|
||||||
|
@ -82,7 +83,7 @@ func (c *netStatCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
key := protocol + "_" + name
|
key := protocol + "_" + name
|
||||||
v, err := strconv.ParseFloat(value, 64)
|
v, err := strconv.ParseFloat(value, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid value %s in netstats: %s", value, err)
|
return fmt.Errorf("invalid value %s in netstats: %w", value, err)
|
||||||
}
|
}
|
||||||
if !c.fieldPattern.MatchString(key) {
|
if !c.fieldPattern.MatchString(key) {
|
||||||
continue
|
continue
|
||||||
|
@ -140,7 +141,7 @@ func getSNMP6Stats(fileName string) (map[string]map[string]string, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// On systems with IPv6 disabled, this file won't exist.
|
// On systems with IPv6 disabled, this file won't exist.
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
@ -97,7 +98,7 @@ func NewNfsCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *nfsCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *nfsCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
stats, err := c.fs.ClientRPCStats()
|
stats, err := c.fs.ClientRPCStats()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
level.Debug(c.logger).Log("msg", "Not collecting NFS metrics", "err", err)
|
level.Debug(c.logger).Log("msg", "Not collecting NFS metrics", "err", err)
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -63,7 +64,7 @@ func NewNFSdCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *nfsdCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *nfsdCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
stats, err := c.fs.ServerRPCStats()
|
stats, err := c.fs.ServerRPCStats()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
level.Debug(c.logger).Log("msg", "Not collecting NFSd metrics", "err", err)
|
level.Debug(c.logger).Log("msg", "Not collecting NFSd metrics", "err", err)
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ func (c *ntpCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
Timeout: time.Second, // default `ntpdate` timeout
|
Timeout: time.Second, // default `ntpdate` timeout
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get SNTP reply: %s", err)
|
return fmt.Errorf("couldn't get SNTP reply: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- c.stratum.mustNewConstMetric(float64(resp.Stratum))
|
ch <- c.stratum.mustNewConstMetric(float64(resp.Stratum))
|
||||||
|
|
|
@ -59,7 +59,7 @@ func (c *powerSupplyClassCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
return fmt.Errorf("could not get power_supply class info: %s", err)
|
return fmt.Errorf("could not get power_supply class info: %w", err)
|
||||||
}
|
}
|
||||||
for _, powerSupply := range powerSupplyClass {
|
for _, powerSupply := range powerSupplyClass {
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -75,13 +76,13 @@ func NewProcessStatCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *processCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *processCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
pids, states, threads, err := c.getAllocatedThreads()
|
pids, states, threads, err := c.getAllocatedThreads()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retrieve number of allocated threads: %q", err)
|
return fmt.Errorf("unable to retrieve number of allocated threads: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(c.threadAlloc, prometheus.GaugeValue, float64(threads))
|
ch <- prometheus.MustNewConstMetric(c.threadAlloc, prometheus.GaugeValue, float64(threads))
|
||||||
maxThreads, err := readUintFromFile(procFilePath("sys/kernel/threads-max"))
|
maxThreads, err := readUintFromFile(procFilePath("sys/kernel/threads-max"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retrieve limit number of threads: %q", err)
|
return fmt.Errorf("unable to retrieve limit number of threads: %w", err)
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(c.threadLimit, prometheus.GaugeValue, float64(maxThreads))
|
ch <- prometheus.MustNewConstMetric(c.threadLimit, prometheus.GaugeValue, float64(maxThreads))
|
||||||
|
|
||||||
|
@ -91,7 +92,7 @@ func (c *processCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
|
|
||||||
pidM, err := readUintFromFile(procFilePath("sys/kernel/pid_max"))
|
pidM, err := readUintFromFile(procFilePath("sys/kernel/pid_max"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to retrieve limit number of maximum pids alloved: %q", err)
|
return fmt.Errorf("unable to retrieve limit number of maximum pids alloved: %w", err)
|
||||||
}
|
}
|
||||||
ch <- prometheus.MustNewConstMetric(c.pidUsed, prometheus.GaugeValue, float64(pids))
|
ch <- prometheus.MustNewConstMetric(c.pidUsed, prometheus.GaugeValue, float64(pids))
|
||||||
ch <- prometheus.MustNewConstMetric(c.pidMax, prometheus.GaugeValue, float64(pidM))
|
ch <- prometheus.MustNewConstMetric(c.pidMax, prometheus.GaugeValue, float64(pidM))
|
||||||
|
@ -110,7 +111,7 @@ func (c *processCollector) getAllocatedThreads() (int, map[string]int32, int, er
|
||||||
for _, pid := range p {
|
for _, pid := range p {
|
||||||
stat, err := pid.Stat()
|
stat, err := pid.Stat()
|
||||||
// PIDs can vanish between getting the list and getting stats.
|
// PIDs can vanish between getting the list and getting stats.
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
level.Debug(c.logger).Log("msg", "file not found when retrieving stats for pid", "pid", pid, "err", err)
|
level.Debug(c.logger).Log("msg", "file not found when retrieving stats for pid", "pid", pid, "err", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ func init() {
|
||||||
func (c *schedstatCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *schedstatCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
stats, err := c.fs.Schedstat()
|
stats, err := c.fs.Schedstat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
level.Debug(c.logger).Log("msg", "schedstat file does not exist")
|
level.Debug(c.logger).Log("msg", "schedstat file does not exist")
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ func (c *sockStatCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
stat4, err := fs.NetSockstat()
|
stat4, err := fs.NetSockstat()
|
||||||
switch {
|
switch {
|
||||||
case err == nil:
|
case err == nil:
|
||||||
case os.IsNotExist(err):
|
case errors.Is(err, os.ErrNotExist):
|
||||||
level.Debug(c.logger).Log("msg", "IPv4 sockstat statistics not found, skipping")
|
level.Debug(c.logger).Log("msg", "IPv4 sockstat statistics not found, skipping")
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("failed to get IPv4 sockstat data: %w", err)
|
return fmt.Errorf("failed to get IPv4 sockstat data: %w", err)
|
||||||
|
@ -64,7 +65,7 @@ func (c *sockStatCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
stat6, err := fs.NetSockstat6()
|
stat6, err := fs.NetSockstat6()
|
||||||
switch {
|
switch {
|
||||||
case err == nil:
|
case err == nil:
|
||||||
case os.IsNotExist(err):
|
case errors.Is(err, os.ErrNotExist):
|
||||||
level.Debug(c.logger).Log("msg", "IPv6 sockstat statistics not found, skipping")
|
level.Debug(c.logger).Log("msg", "IPv6 sockstat statistics not found, skipping")
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("failed to get IPv6 sockstat data: %w", err)
|
return fmt.Errorf("failed to get IPv6 sockstat data: %w", err)
|
||||||
|
|
|
@ -72,7 +72,7 @@ func NewSoftnetCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *softnetCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *softnetCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
stats, err := c.fs.NetSoftnetStat()
|
stats, err := c.fs.NetSoftnetStat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not get softnet statistics: %s", err)
|
return fmt.Errorf("could not get softnet statistics: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for cpuNumber, cpuStats := range stats {
|
for cpuNumber, cpuStats := range stats {
|
||||||
|
|
|
@ -134,7 +134,7 @@ func (c *supervisordCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
|
|
||||||
res, err := xrpc.Call("supervisor.getAllProcessInfo")
|
res, err := xrpc.Call("supervisor.getAllProcessInfo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to call supervisord: %s", err)
|
return fmt.Errorf("unable to call supervisord: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range res.(xmlrpc.Array) {
|
for _, p := range res.(xmlrpc.Array) {
|
||||||
|
|
|
@ -175,13 +175,13 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
begin := time.Now()
|
begin := time.Now()
|
||||||
conn, err := newSystemdDbusConn()
|
conn, err := newSystemdDbusConn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get dbus connection: %s", err)
|
return fmt.Errorf("couldn't get dbus connection: %w", err)
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
|
||||||
allUnits, err := c.getAllUnits(conn)
|
allUnits, err := c.getAllUnits(conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get units: %s", err)
|
return fmt.Errorf("couldn't get units: %w", err)
|
||||||
}
|
}
|
||||||
level.Debug(c.logger).Log("msg", "getAllUnits took", "duration_seconds", time.Since(begin).Seconds())
|
level.Debug(c.logger).Log("msg", "getAllUnits took", "duration_seconds", time.Since(begin).Seconds())
|
||||||
|
|
||||||
|
@ -413,7 +413,7 @@ func (c *systemdCollector) collectSummaryMetrics(ch chan<- prometheus.Metric, su
|
||||||
func (c *systemdCollector) collectSystemState(conn *dbus.Conn, ch chan<- prometheus.Metric) error {
|
func (c *systemdCollector) collectSystemState(conn *dbus.Conn, ch chan<- prometheus.Metric) error {
|
||||||
systemState, err := conn.GetManagerProperty("SystemState")
|
systemState, err := conn.GetManagerProperty("SystemState")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get system state: %s", err)
|
return fmt.Errorf("couldn't get system state: %w", err)
|
||||||
}
|
}
|
||||||
isSystemRunning := 0.0
|
isSystemRunning := 0.0
|
||||||
if systemState == `"running"` {
|
if systemState == `"running"` {
|
||||||
|
|
|
@ -82,7 +82,7 @@ func NewTCPStatCollector(logger log.Logger) (Collector, error) {
|
||||||
func (c *tcpStatCollector) Update(ch chan<- prometheus.Metric) error {
|
func (c *tcpStatCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
tcpStats, err := getTCPStats(procFilePath("net/tcp"))
|
tcpStats, err := getTCPStats(procFilePath("net/tcp"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get tcpstats: %s", err)
|
return fmt.Errorf("couldn't get tcpstats: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if enabled ipv6 system
|
// if enabled ipv6 system
|
||||||
|
@ -90,7 +90,7 @@ func (c *tcpStatCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
if _, hasIPv6 := os.Stat(tcp6File); hasIPv6 == nil {
|
if _, hasIPv6 := os.Stat(tcp6File); hasIPv6 == nil {
|
||||||
tcp6Stats, err := getTCPStats(tcp6File)
|
tcp6Stats, err := getTCPStats(tcp6File)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get tcp6stats: %s", err)
|
return fmt.Errorf("couldn't get tcp6stats: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for st, value := range tcp6Stats {
|
for st, value := range tcp6Stats {
|
||||||
|
|
|
@ -238,14 +238,14 @@ func (c *textFileCollector) processFile(name string, ch chan<- prometheus.Metric
|
||||||
path := filepath.Join(c.path, name)
|
path := filepath.Join(c.path, name)
|
||||||
f, err := os.Open(path)
|
f, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to open textfile data file %q: %v", path, err)
|
return nil, fmt.Errorf("failed to open textfile data file %q: %w", path, err)
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
var parser expfmt.TextParser
|
var parser expfmt.TextParser
|
||||||
families, err := parser.TextToMetricFamilies(f)
|
families, err := parser.TextToMetricFamilies(f)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to parse textfile data from %q: %v", path, err)
|
return nil, fmt.Errorf("failed to parse textfile data from %q: %w", path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if hasTimestamps(families) {
|
if hasTimestamps(families) {
|
||||||
|
@ -267,7 +267,7 @@ func (c *textFileCollector) processFile(name string, ch chan<- prometheus.Metric
|
||||||
// a failure does not appear fresh.
|
// a failure does not appear fresh.
|
||||||
stat, err := f.Stat()
|
stat, err := f.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to stat %q: %v", path, err)
|
return nil, fmt.Errorf("failed to stat %q: %w", path, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
t := stat.ModTime()
|
t := stat.ModTime()
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package collector
|
package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -41,7 +42,7 @@ func init() {
|
||||||
func NewUDPqueuesCollector(logger log.Logger) (Collector, error) {
|
func NewUDPqueuesCollector(logger log.Logger) (Collector, error) {
|
||||||
fs, err := procfs.NewFS(*procPath)
|
fs, err := procfs.NewFS(*procPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to open procfs: %v", err)
|
return nil, fmt.Errorf("failed to open procfs: %w", err)
|
||||||
}
|
}
|
||||||
return &udpQueuesCollector{
|
return &udpQueuesCollector{
|
||||||
fs: fs,
|
fs: fs,
|
||||||
|
@ -61,10 +62,10 @@ func (c *udpQueuesCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
ch <- prometheus.MustNewConstMetric(c.desc, prometheus.GaugeValue, float64(s4.TxQueueLength), "tx", "v4")
|
ch <- prometheus.MustNewConstMetric(c.desc, prometheus.GaugeValue, float64(s4.TxQueueLength), "tx", "v4")
|
||||||
ch <- prometheus.MustNewConstMetric(c.desc, prometheus.GaugeValue, float64(s4.RxQueueLength), "rx", "v4")
|
ch <- prometheus.MustNewConstMetric(c.desc, prometheus.GaugeValue, float64(s4.RxQueueLength), "rx", "v4")
|
||||||
} else {
|
} else {
|
||||||
if os.IsNotExist(errIPv4) {
|
if errors.Is(errIPv4, os.ErrNotExist) {
|
||||||
level.Debug(c.logger).Log("msg", "not collecting ipv4 based metrics")
|
level.Debug(c.logger).Log("msg", "not collecting ipv4 based metrics")
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("couldn't get upd queued bytes: %s", errIPv4)
|
return fmt.Errorf("couldn't get upd queued bytes: %w", errIPv4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,14 +74,14 @@ func (c *udpQueuesCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
ch <- prometheus.MustNewConstMetric(c.desc, prometheus.GaugeValue, float64(s6.TxQueueLength), "tx", "v6")
|
ch <- prometheus.MustNewConstMetric(c.desc, prometheus.GaugeValue, float64(s6.TxQueueLength), "tx", "v6")
|
||||||
ch <- prometheus.MustNewConstMetric(c.desc, prometheus.GaugeValue, float64(s6.RxQueueLength), "rx", "v6")
|
ch <- prometheus.MustNewConstMetric(c.desc, prometheus.GaugeValue, float64(s6.RxQueueLength), "rx", "v6")
|
||||||
} else {
|
} else {
|
||||||
if os.IsNotExist(errIPv6) {
|
if errors.Is(errIPv6, os.ErrNotExist) {
|
||||||
level.Debug(c.logger).Log("msg", "not collecting ipv6 based metrics")
|
level.Debug(c.logger).Log("msg", "not collecting ipv6 based metrics")
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf("couldn't get upd6 queued bytes: %s", errIPv6)
|
return fmt.Errorf("couldn't get upd6 queued bytes: %w", errIPv6)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if os.IsNotExist(errIPv4) && os.IsNotExist(errIPv6) {
|
if errors.Is(errIPv4, os.ErrNotExist) && errors.Is(errIPv6, os.ErrNotExist) {
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -17,6 +17,7 @@ package collector
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
|
@ -167,11 +168,11 @@ func (c *wifiCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
stat, err := newWifiStater(*collectorWifi)
|
stat, err := newWifiStater(*collectorWifi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Cannot access wifi metrics, report no error.
|
// Cannot access wifi metrics, report no error.
|
||||||
if os.IsNotExist(err) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
level.Debug(c.logger).Log("msg", "wifi collector metrics are not available for this system")
|
level.Debug(c.logger).Log("msg", "wifi collector metrics are not available for this system")
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
if os.IsPermission(err) {
|
if errors.Is(err, os.ErrPermission) {
|
||||||
level.Debug(c.logger).Log("msg", "wifi collector got permission denied when accessing metrics")
|
level.Debug(c.logger).Log("msg", "wifi collector got permission denied when accessing metrics")
|
||||||
return ErrNoData
|
return ErrNoData
|
||||||
}
|
}
|
||||||
|
@ -201,14 +202,14 @@ func (c *wifiCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
)
|
)
|
||||||
|
|
||||||
// When a statistic is not available for a given interface, package wifi
|
// When a statistic is not available for a given interface, package wifi
|
||||||
// returns an error compatible with os.IsNotExist. We leverage this to
|
// returns a os.ErrNotExist error. We leverage this to only export
|
||||||
// only export metrics which are actually valid for given interface types.
|
// metrics which are actually valid for given interface types.
|
||||||
|
|
||||||
bss, err := stat.BSS(ifi)
|
bss, err := stat.BSS(ifi)
|
||||||
switch {
|
switch {
|
||||||
case err == nil:
|
case err == nil:
|
||||||
c.updateBSSStats(ch, ifi.Name, bss)
|
c.updateBSSStats(ch, ifi.Name, bss)
|
||||||
case os.IsNotExist(err):
|
case errors.Is(err, os.ErrNotExist):
|
||||||
level.Debug(c.logger).Log("msg", "BSS information not found for wifi device", "name", ifi.Name)
|
level.Debug(c.logger).Log("msg", "BSS information not found for wifi device", "name", ifi.Name)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("failed to retrieve BSS for device %s: %v",
|
return fmt.Errorf("failed to retrieve BSS for device %s: %v",
|
||||||
|
@ -221,7 +222,7 @@ func (c *wifiCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
for _, station := range stations {
|
for _, station := range stations {
|
||||||
c.updateStationStats(ch, ifi.Name, station)
|
c.updateStationStats(ch, ifi.Name, station)
|
||||||
}
|
}
|
||||||
case os.IsNotExist(err):
|
case errors.Is(err, os.ErrNotExist):
|
||||||
level.Debug(c.logger).Log("msg", "station information not found for wifi device", "name", ifi.Name)
|
level.Debug(c.logger).Log("msg", "station information not found for wifi device", "name", ifi.Name)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("failed to retrieve station info for device %q: %v",
|
return fmt.Errorf("failed to retrieve station info for device %q: %v",
|
||||||
|
|
|
@ -250,7 +250,7 @@ func (c *zfsCollector) Update(ch chan<- prometheus.Metric) error {
|
||||||
for _, m := range c.sysctls {
|
for _, m := range c.sysctls {
|
||||||
v, err := m.Value()
|
v, err := m.Value()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("couldn't get sysctl: %s", err)
|
return fmt.Errorf("couldn't get sysctl: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ch <- prometheus.MustNewConstMetric(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
|
|
|
@ -187,7 +187,7 @@ func (c *zfsCollector) parsePoolProcfsFile(reader io.Reader, zpoolPath string, h
|
||||||
|
|
||||||
value, err := strconv.ParseUint(line[i], 10, 64)
|
value, err := strconv.ParseUint(line[i], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not parse expected integer value for %q: %v", key, err)
|
return fmt.Errorf("could not parse expected integer value for %q: %w", key, err)
|
||||||
}
|
}
|
||||||
handler(zpoolName, zfsSysctl(key), value)
|
handler(zpoolName, zfsSysctl(key), value)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue