diff --git a/collector/arp_linux.go b/collector/arp_linux.go index cd61d9a7..8f42d380 100644 --- a/collector/arp_linux.go +++ b/collector/arp_linux.go @@ -32,10 +32,7 @@ type arpCollector struct { } func init() { - registerCollector("arp", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - arpConfig := config.(ArpConfig) - return NewARPCollector(arpConfig, logger) - }) + registerCollector("arp", defaultEnabled, NewARPCollector) } type ArpConfig struct { @@ -44,15 +41,15 @@ type ArpConfig struct { } // NewARPCollector returns a new Collector exposing ARP stats. -func NewARPCollector(config ArpConfig, logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewARPCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } return &arpCollector{ fs: fs, - deviceFilter: newDeviceFilter(*config.DeviceExclude, *config.DeviceInclude), + deviceFilter: newDeviceFilter(*config.Arp.DeviceExclude, *config.Arp.DeviceInclude), entries: prometheus.NewDesc( prometheus.BuildFQName(namespace, "arp", "entries"), "ARP entries by device", diff --git a/collector/bcache_linux.go b/collector/bcache_linux.go index 0102a15f..e5a24c91 100644 --- a/collector/bcache_linux.go +++ b/collector/bcache_linux.go @@ -25,17 +25,15 @@ import ( ) func init() { - registerCollector("bcache", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - bcacheConfig := config.(BcacheConfig) - return NewBcacheCollector(bcacheConfig, logger) - }) + registerCollector("bcache", defaultEnabled, NewBcacheCollector) + } // A bcacheCollector is a Collector which gathers metrics from Linux bcache. type bcacheCollector struct { fs bcache.FS logger log.Logger - config BcacheConfig + config NodeCollectorConfig } type BcacheConfig struct { @@ -44,8 +42,8 @@ type BcacheConfig struct { // NewBcacheCollector returns a newly allocated bcacheCollector. // It exposes a number of Linux bcache statistics. -func NewBcacheCollector(config BcacheConfig, logger log.Logger) (Collector, error) { - fs, err := bcache.NewFS(*sysPath) +func NewBcacheCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := bcache.NewFS(*config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } @@ -62,7 +60,7 @@ func NewBcacheCollector(config BcacheConfig, logger log.Logger) (Collector, erro func (c *bcacheCollector) Update(ch chan<- prometheus.Metric) error { var stats []*bcache.Stats var err error - if *c.config.PriorityStats { + if *c.config.Bcache.PriorityStats { stats, err = c.fs.Stats() } else { stats, err = c.fs.StatsWithoutPriority() @@ -321,7 +319,7 @@ func (c *bcacheCollector) updateBcacheStats(ch chan<- prometheus.Metric, s *bcac extraLabelValue: cache.Name, }, } - if *c.config.PriorityStats { + if *c.config.Bcache.PriorityStats { // metrics in /sys/fs/bcache///priority_stats priorityStatsMetrics := []bcacheMetric{ { diff --git a/collector/bonding_linux.go b/collector/bonding_linux.go index 36752266..5735eae2 100644 --- a/collector/bonding_linux.go +++ b/collector/bonding_linux.go @@ -31,17 +31,16 @@ import ( type bondingCollector struct { slaves, active typedDesc logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("bonding", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewBondingCollector(logger) - }) + registerCollector("bonding", defaultEnabled, NewBondingCollector) } // NewBondingCollector returns a newly allocated bondingCollector. // It exposes the number of configured and active slave of linux bonding interfaces. -func NewBondingCollector(logger log.Logger) (Collector, error) { +func NewBondingCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &bondingCollector{ slaves: typedDesc{prometheus.NewDesc( prometheus.BuildFQName(namespace, "bonding", "slaves"), @@ -54,12 +53,13 @@ func NewBondingCollector(logger log.Logger) (Collector, error) { []string{"master"}, nil, ), prometheus.GaugeValue}, logger: logger, + config: config, }, nil } // Update reads and exposes bonding states, implements Collector interface. Caution: This works only on linux. func (c *bondingCollector) Update(ch chan<- prometheus.Metric) error { - statusfile := sysFilePath("class/net") + statusfile := c.config.Path.sysFilePath("class/net") bondingStats, err := readBondingStats(statusfile) if err != nil { if errors.Is(err, os.ErrNotExist) { diff --git a/collector/boot_time_bsd.go b/collector/boot_time_bsd.go index 06b8807a..9d2600f4 100644 --- a/collector/boot_time_bsd.go +++ b/collector/boot_time_bsd.go @@ -28,13 +28,11 @@ type bootTimeCollector struct { } func init() { - registerCollector("boottime", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return newBootTimeCollector(logger) - }) + registerCollector("boottime", defaultEnabled, newBootTimeCollector(logger)) } // newBootTimeCollector returns a new Collector exposing system boot time on BSD systems. -func newBootTimeCollector(logger log.Logger) (Collector, error) { +func newBootTimeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &bootTimeCollector{ logger: logger, }, nil diff --git a/collector/boot_time_solaris.go b/collector/boot_time_solaris.go index 0271571a..6782cd72 100644 --- a/collector/boot_time_solaris.go +++ b/collector/boot_time_solaris.go @@ -28,12 +28,10 @@ type bootTimeCollector struct { } func init() { - registerCollector("boottime", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return newBootTimeCollector(logger) - }) + registerCollector("boottime", defaultEnabled, newBootTimeCollector) } -func newBootTimeCollector(logger log.Logger) (Collector, error) { +func newBootTimeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &bootTimeCollector{ boottime: typedDesc{ prometheus.NewDesc( diff --git a/collector/btrfs_linux.go b/collector/btrfs_linux.go index d9279c53..cebf5b30 100644 --- a/collector/btrfs_linux.go +++ b/collector/btrfs_linux.go @@ -33,17 +33,16 @@ import ( type btrfsCollector struct { fs btrfs.FS logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("btrfs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewBtrfsCollector(logger) - }) + registerCollector("btrfs", defaultEnabled, NewBtrfsCollector) } // NewBtrfsCollector returns a new Collector exposing Btrfs statistics. -func NewBtrfsCollector(logger log.Logger) (Collector, error) { - fs, err := btrfs.NewFS(*sysPath) +func NewBtrfsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := btrfs.NewFS(*config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } @@ -51,6 +50,7 @@ func NewBtrfsCollector(logger log.Logger) (Collector, error) { return &btrfsCollector{ fs: fs, logger: logger, + config: config, }, nil } @@ -105,7 +105,7 @@ type btrfsIoctlFsStats struct { func (c *btrfsCollector) getIoctlStats() (map[string]*btrfsIoctlFsStats, error) { // Instead of introducing more ioctl calls to scan for all btrfs // filesystems re-use our mount point utils to find known mounts - mountsList, err := mountPointDetails(c.logger) + mountsList, err := mountPointDetails(c.config, c.logger) if err != nil { return nil, err } @@ -125,7 +125,7 @@ func (c *btrfsCollector) getIoctlStats() (map[string]*btrfsIoctlFsStats, error) continue } - mountPath := rootfsFilePath(mount.mountPoint) + mountPath := c.config.Path.rootfsFilePath(mount.mountPoint) fs, err := dennwc.Open(mountPath, true) if err != nil { diff --git a/collector/buddyinfo.go b/collector/buddyinfo.go index af442b5e..42869082 100644 --- a/collector/buddyinfo.go +++ b/collector/buddyinfo.go @@ -37,19 +37,17 @@ type buddyinfoCollector struct { } func init() { - registerCollector("buddyinfo", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewBuddyinfoCollector(logger) - }) + registerCollector("buddyinfo", defaultDisabled, NewBuddyinfoCollector) } // NewBuddyinfoCollector returns a new Collector exposing buddyinfo stats. -func NewBuddyinfoCollector(logger log.Logger) (Collector, error) { +func NewBuddyinfoCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { desc := prometheus.NewDesc( prometheus.BuildFQName(namespace, buddyInfoSubsystem, "blocks"), "Count of free blocks according to size.", []string{"node", "zone", "size"}, nil, ) - fs, err := procfs.NewFS(*procPath) + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/cgroups_linux.go b/collector/cgroups_linux.go index 87501368..eaa68013 100644 --- a/collector/cgroups_linux.go +++ b/collector/cgroups_linux.go @@ -34,14 +34,12 @@ type cgroupSummaryCollector struct { } func init() { - registerCollector(cgroupsCollectorSubsystem, defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewCgroupSummaryCollector(logger) - }) + registerCollector(cgroupsCollectorSubsystem, defaultDisabled, NewCgroupSummaryCollector) } // NewCgroupSummaryCollector returns a new Collector exposing a summary of cgroups. -func NewCgroupSummaryCollector(logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewCgroupSummaryCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/collector.go b/collector/collector.go index 59d12464..85c9a5f4 100644 --- a/collector/collector.go +++ b/collector/collector.go @@ -50,14 +50,14 @@ const ( ) var ( - factories = make(map[string]func(config any, logger log.Logger) (Collector, error)) + factories = make(map[string]func(config NodeCollectorConfig, logger log.Logger) (Collector, error)) initiatedCollectorsMtx = sync.Mutex{} initiatedCollectors = make(map[string]Collector) collectorState = make(map[string]*bool) forcedCollectors = map[string]bool{} // collectors which have been explicitly enabled or disabled ) -func registerCollector(collector string, isDefaultEnabled bool, factory func(config any, logger log.Logger) (Collector, error)) { +func registerCollector(collector string, isDefaultEnabled bool, factory func(config NodeCollectorConfig, logger log.Logger) (Collector, error)) { var helpDefaultState string if isDefaultEnabled { helpDefaultState = "enabled" diff --git a/collector/config.go b/collector/config.go index 7abd93a8..40ef137f 100644 --- a/collector/config.go +++ b/collector/config.go @@ -29,6 +29,7 @@ type NodeCollectorConfig struct { NetDev NetDevConfig NetStat NetStatConfig NTP NTPConfig + Path PathConfig Perf PerfConfig PowerSupplyClass PowerSupplyClassConfig Qdisc QdiscConfig diff --git a/collector/conntrack_linux.go b/collector/conntrack_linux.go index 7a221216..cd6ceb8b 100644 --- a/collector/conntrack_linux.go +++ b/collector/conntrack_linux.go @@ -39,6 +39,7 @@ type conntrackCollector struct { earlyDrop *prometheus.Desc searchRestart *prometheus.Desc logger log.Logger + config NodeCollectorConfig } type conntrackStatistics struct { @@ -53,13 +54,11 @@ type conntrackStatistics struct { } func init() { - registerCollector("conntrack", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewConntrackCollector(logger) - }) + registerCollector("conntrack", defaultEnabled, NewConntrackCollector) } // NewConntrackCollector returns a new Collector exposing conntrack stats. -func NewConntrackCollector(logger log.Logger) (Collector, error) { +func NewConntrackCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &conntrackCollector{ current: prometheus.NewDesc( prometheus.BuildFQName(namespace, "", "nf_conntrack_entries"), @@ -112,25 +111,26 @@ func NewConntrackCollector(logger log.Logger) (Collector, error) { nil, nil, ), logger: logger, + config: config, }, nil } func (c *conntrackCollector) Update(ch chan<- prometheus.Metric) error { - value, err := readUintFromFile(procFilePath("sys/net/netfilter/nf_conntrack_count")) + value, err := readUintFromFile(c.config.Path.procFilePath("sys/net/netfilter/nf_conntrack_count")) if err != nil { return c.handleErr(err) } ch <- prometheus.MustNewConstMetric( c.current, prometheus.GaugeValue, float64(value)) - value, err = readUintFromFile(procFilePath("sys/net/netfilter/nf_conntrack_max")) + value, err = readUintFromFile(c.config.Path.procFilePath("sys/net/netfilter/nf_conntrack_max")) if err != nil { return c.handleErr(err) } ch <- prometheus.MustNewConstMetric( c.limit, prometheus.GaugeValue, float64(value)) - conntrackStats, err := getConntrackStatistics() + conntrackStats, err := getConntrackStatistics(c.config) if err != nil { return c.handleErr(err) } @@ -162,10 +162,10 @@ func (c *conntrackCollector) handleErr(err error) error { return fmt.Errorf("failed to retrieve conntrack stats: %w", err) } -func getConntrackStatistics() (*conntrackStatistics, error) { +func getConntrackStatistics(config NodeCollectorConfig) (*conntrackStatistics, error) { c := conntrackStatistics{} - fs, err := procfs.NewFS(*procPath) + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/cpu_darwin.go b/collector/cpu_darwin.go index df21148b..bacde20a 100644 --- a/collector/cpu_darwin.go +++ b/collector/cpu_darwin.go @@ -57,13 +57,11 @@ type statCollector struct { } func init() { - registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewCPUCollector(logger) - }) + registerCollector("cpu", defaultEnabled, NewCPUCollector) } // NewCPUCollector returns a new Collector exposing CPU stats. -func NewCPUCollector(logger log.Logger) (Collector, error) { +func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &statCollector{ cpu: nodeCPUSecondsDesc, logger: logger, diff --git a/collector/cpu_dragonfly.go b/collector/cpu_dragonfly.go index 5d74e7db..1420c436 100644 --- a/collector/cpu_dragonfly.go +++ b/collector/cpu_dragonfly.go @@ -82,13 +82,11 @@ type statCollector struct { } func init() { - registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewStatCollector(logger) - }) + registerCollector("cpu", defaultEnabled, NewStatCollector) } // NewStatCollector returns a new Collector exposing CPU stats. -func NewStatCollector(logger log.Logger) (Collector, error) { +func NewStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &statCollector{ cpu: nodeCPUSecondsDesc, logger: logger, diff --git a/collector/cpu_freebsd.go b/collector/cpu_freebsd.go index 6a44e036..d75b8adc 100644 --- a/collector/cpu_freebsd.go +++ b/collector/cpu_freebsd.go @@ -89,13 +89,11 @@ type statCollector struct { } func init() { - registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewStatCollector(logger) - }) + registerCollector("cpu", defaultEnabled, NewStatCollector) } // NewStatCollector returns a new Collector exposing CPU stats. -func NewStatCollector(logger log.Logger) (Collector, error) { +func NewStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &statCollector{ cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, temp: typedDesc{prometheus.NewDesc( diff --git a/collector/cpu_linux.go b/collector/cpu_linux.go index ebd676fb..f22f6876 100644 --- a/collector/cpu_linux.go +++ b/collector/cpu_linux.go @@ -51,7 +51,7 @@ type cpuCollector struct { cpuFlagsIncludeRegexp *regexp.Regexp cpuBugsIncludeRegexp *regexp.Regexp - config CPUConfig + config NodeCollectorConfig } // Idle jump back limit in seconds. @@ -69,20 +69,17 @@ type CPUConfig struct { } func init() { - registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cpuConfig := config.(CPUConfig) - return NewCPUCollector(cpuConfig, logger) - }) + registerCollector("cpu", defaultEnabled, NewCPUCollector) } // NewCPUCollector returns a new Collector exposing kernel/system statistics. -func NewCPUCollector(config CPUConfig, logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } - sysfs, err := sysfs.NewFS(*sysPath) + sysfs, err := sysfs.NewFS(*config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } @@ -138,7 +135,7 @@ func NewCPUCollector(config CPUConfig, logger log.Logger) (Collector, error) { cpuStats: make(map[int64]procfs.CPUStat), config: config, } - err = c.compileIncludeFlags(c.config.FlagsInclude, c.config.BugsInclude) + err = c.compileIncludeFlags(c.config.CPU.FlagsInclude, c.config.CPU.BugsInclude) if err != nil { return nil, fmt.Errorf("fail to compile --collector.cpu.info.flags-include and --collector.cpu.info.bugs-include, the values of them must be regular expressions: %w", err) } @@ -146,8 +143,8 @@ func NewCPUCollector(config CPUConfig, logger log.Logger) (Collector, error) { } func (c *cpuCollector) compileIncludeFlags(flagsIncludeFlag, bugsIncludeFlag *string) error { - if (*flagsIncludeFlag != "" || *bugsIncludeFlag != "") && !*c.config.EnableCPUInfo { - *c.config.EnableCPUInfo = true + if (*flagsIncludeFlag != "" || *bugsIncludeFlag != "") && !*c.config.CPU.EnableCPUInfo { + *c.config.CPU.EnableCPUInfo = true level.Info(c.logger).Log("msg", "--collector.cpu.info has been set to `true` because you set the following flags, like --collector.cpu.info.flags-include and --collector.cpu.info.bugs-include") } @@ -169,7 +166,7 @@ func (c *cpuCollector) compileIncludeFlags(flagsIncludeFlag, bugsIncludeFlag *st // Update implements Collector and exposes cpu related metrics from /proc/stat and /sys/.../cpu/. func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error { - if *c.config.EnableCPUInfo { + if *c.config.CPU.EnableCPUInfo { if err := c.updateInfo(ch); err != nil { return err } @@ -180,7 +177,7 @@ func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error { if c.isolatedCpus != nil { c.updateIsolated(ch) } - return c.updateThermalThrottle(ch) + return c.updateThermalThrottle(c.config, ch) } // updateInfo reads /proc/cpuinfo @@ -237,8 +234,8 @@ func updateFieldInfo(valueList []string, filter *regexp.Regexp, desc *prometheus } // updateThermalThrottle reads /sys/devices/system/cpu/cpu* and expose thermal throttle statistics. -func (c *cpuCollector) updateThermalThrottle(ch chan<- prometheus.Metric) error { - cpus, err := filepath.Glob(sysFilePath("devices/system/cpu/cpu[0-9]*")) +func (c *cpuCollector) updateThermalThrottle(config NodeCollectorConfig, ch chan<- prometheus.Metric) error { + cpus, err := filepath.Glob(config.Path.sysFilePath("devices/system/cpu/cpu[0-9]*")) if err != nil { return err } @@ -345,7 +342,7 @@ func (c *cpuCollector) updateStat(ch chan<- prometheus.Metric) error { ch <- prometheus.MustNewConstMetric(c.cpu, prometheus.CounterValue, cpuStat.SoftIRQ, cpuNum, "softirq") ch <- prometheus.MustNewConstMetric(c.cpu, prometheus.CounterValue, cpuStat.Steal, cpuNum, "steal") - if *c.config.EnableCPUGuest { + if *c.config.CPU.EnableCPUGuest { // Guest CPU is also accounted for in cpuStat.User and cpuStat.Nice, expose these as separate metrics. ch <- prometheus.MustNewConstMetric(c.cpuGuest, prometheus.CounterValue, cpuStat.Guest, cpuNum, "user") ch <- prometheus.MustNewConstMetric(c.cpuGuest, prometheus.CounterValue, cpuStat.GuestNice, cpuNum, "nice") diff --git a/collector/cpu_netbsd.go b/collector/cpu_netbsd.go index 5b312ab7..4f1e63fb 100644 --- a/collector/cpu_netbsd.go +++ b/collector/cpu_netbsd.go @@ -218,13 +218,11 @@ type statCollector struct { } func init() { - registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewStatCollector(logger) - }) + registerCollector("cpu", defaultEnabled, NewStatCollector) } // NewStatCollector returns a new Collector exposing CPU stats. -func NewStatCollector(logger log.Logger) (Collector, error) { +func NewStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &statCollector{ cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, temp: typedDesc{prometheus.NewDesc( diff --git a/collector/cpu_openbsd.go b/collector/cpu_openbsd.go index 088f1d57..31c3d49e 100644 --- a/collector/cpu_openbsd.go +++ b/collector/cpu_openbsd.go @@ -49,9 +49,7 @@ type cpuCollector struct { } func init() { - registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewCPUCollector(logger) - }) + registerCollector("cpu", defaultEnabled, NewCPUCollector) } func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { diff --git a/collector/cpu_solaris.go b/collector/cpu_solaris.go index ed39d5bb..702ba3f8 100644 --- a/collector/cpu_solaris.go +++ b/collector/cpu_solaris.go @@ -33,12 +33,10 @@ type cpuCollector struct { } func init() { - registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewCPUCollector(logger) - }) + registerCollector("cpu", defaultEnabled, NewCpuCollector) } -func NewCpuCollector(logger log.Logger) (Collector, error) { +func NewCpuCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &cpuCollector{ cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, logger: logger, diff --git a/collector/cpu_vulnerabilities_linux.go b/collector/cpu_vulnerabilities_linux.go index 1f75d43e..afa028c1 100644 --- a/collector/cpu_vulnerabilities_linux.go +++ b/collector/cpu_vulnerabilities_linux.go @@ -34,20 +34,20 @@ var ( ) ) -type cpuVulnerabilitiesCollector struct{} - -func init() { - registerCollector(cpuVulerabilitiesCollector, defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewVulnerabilitySysfsCollector(logger) - }) +type cpuVulnerabilitiesCollector struct { + config NodeCollectorConfig } -func NewVulnerabilitySysfsCollector(logger log.Logger) (Collector, error) { - return &cpuVulnerabilitiesCollector{}, nil +func init() { + registerCollector(cpuVulerabilitiesCollector, defaultDisabled, NewVulnerabilitySysfsCollector) +} + +func NewVulnerabilitySysfsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + return &cpuVulnerabilitiesCollector{config}, nil } func (v *cpuVulnerabilitiesCollector) Update(ch chan<- prometheus.Metric) error { - fs, err := sysfs.NewFS(*sysPath) + fs, err := sysfs.NewFS(*v.config.Path.SysPath) if err != nil { return fmt.Errorf("failed to open sysfs: %w", err) } diff --git a/collector/cpufreq_linux.go b/collector/cpufreq_linux.go index 03ed1b5d..973f416a 100644 --- a/collector/cpufreq_linux.go +++ b/collector/cpufreq_linux.go @@ -31,14 +31,12 @@ type cpuFreqCollector struct { } func init() { - registerCollector("cpufreq", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewCPUFreqCollector(logger) - }) + registerCollector("cpufreq", defaultEnabled, NewCPUFreqCollector) } // NewCPUFreqCollector returns a new Collector exposing kernel/system statistics. -func NewCPUFreqCollector(logger log.Logger) (Collector, error) { - fs, err := sysfs.NewFS(*sysPath) +func NewCPUFreqCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := sysfs.NewFS(*config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } diff --git a/collector/cpufreq_solaris.go b/collector/cpufreq_solaris.go index 37ecdf31..50e2a9f9 100644 --- a/collector/cpufreq_solaris.go +++ b/collector/cpufreq_solaris.go @@ -33,12 +33,10 @@ type cpuFreqCollector struct { } func init() { - registerCollector("cpufreq", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewCPUFreqCollector(logger) - }) + registerCollector("cpufreq", defaultEnabled, NewCPUFreqCollector) } -func NewCpuFreqCollector(logger log.Logger) (Collector, error) { +func NewCpuFreqCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &cpuFreqCollector{ logger: logger, }, nil diff --git a/collector/devstat_dragonfly.go b/collector/devstat_dragonfly.go index 566ffdba..953c9650 100644 --- a/collector/devstat_dragonfly.go +++ b/collector/devstat_dragonfly.go @@ -102,13 +102,11 @@ type devstatCollector struct { } func init() { - registerCollector("devstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewDevstatCollector(logger) - }) + registerCollector("devstat", defaultDisabled,NewDevstatCollector) } // NewDevstatCollector returns a new Collector exposing Device stats. -func NewDevstatCollector(logger log.Logger) (Collector, error) { +func NewDevstatCollector(config NodeCollectorConfiglogger log.Logger) (Collector, error) { return &devstatCollector{ bytesDesc: prometheus.NewDesc( prometheus.BuildFQName(namespace, devstatSubsystem, "bytes_total"), diff --git a/collector/devstat_freebsd.go b/collector/devstat_freebsd.go index 01965004..a8c96a1a 100644 --- a/collector/devstat_freebsd.go +++ b/collector/devstat_freebsd.go @@ -47,9 +47,7 @@ type devstatCollector struct { } func init() { - registerCollector("devstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewDevstatCollector(logger) - }) + registerCollector("devstat", defaultDisabled, NewDevstatCollector) } // NewDevstatCollector returns a new Collector exposing Device stats. diff --git a/collector/diskstats_darwin.go b/collector/diskstats_darwin.go index 01ed064f..00ffa3fc 100644 --- a/collector/diskstats_darwin.go +++ b/collector/diskstats_darwin.go @@ -39,17 +39,14 @@ type diskstatsCollector struct { } func init() { - registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(DiskstatsDeviceFilterConfig) - return NewDiskstatsCollector(cfg, logger) - }) + registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) } // NewDiskstatsCollector returns a new Collector exposing disk device stats. -func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger) (Collector, error) { +func NewDiskstatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { var diskLabelNames = []string{"device"} - deviceFilter, err := newDiskstatsDeviceFilter(config, logger) + deviceFilter, err := newDiskstatsDeviceFilter(config.DiskstatsDeviceFilter, logger) if err != nil { return nil, fmt.Errorf("failed to parse device filter flags: %w", err) } diff --git a/collector/diskstats_linux.go b/collector/diskstats_linux.go index 7390b4d8..33d79f09 100644 --- a/collector/diskstats_linux.go +++ b/collector/diskstats_linux.go @@ -86,26 +86,24 @@ type diskstatsCollector struct { deviceMapperInfoDesc typedFactorDesc ataDescs map[string]typedFactorDesc logger log.Logger - getUdevDeviceProperties func(uint32, uint32) (udevInfo, error) + getUdevDeviceProperties func(NodeCollectorConfig, uint32, uint32) (udevInfo, error) + config NodeCollectorConfig } func init() { - registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(DiskstatsDeviceFilterConfig) - return NewDiskstatsCollector(cfg, logger) - }) + registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) } // NewDiskstatsCollector returns a new Collector exposing disk device stats. // Docs from https://www.kernel.org/doc/Documentation/iostats.txt -func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger) (Collector, error) { +func NewDiskstatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { var diskLabelNames = []string{"device"} - fs, err := blockdevice.NewFS(*procPath, *sysPath) + fs, err := blockdevice.NewFS(*config.Path.ProcPath, *config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } - deviceFilter, err := newDiskstatsDeviceFilter(config, logger) + deviceFilter, err := newDiskstatsDeviceFilter(config.DiskstatsDeviceFilter, logger) if err != nil { return nil, fmt.Errorf("failed to parse device filter flags: %w", err) } @@ -261,11 +259,12 @@ func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger }, }, logger: logger, + config: config, } // Only enable getting device properties from udev if the directory is readable. - if stat, err := os.Stat(*udevDataPath); err != nil || !stat.IsDir() { - level.Error(logger).Log("msg", "Failed to open directory, disabling udev device properties", "path", *udevDataPath) + if stat, err := os.Stat(*config.Path.UdevDataPath); err != nil || !stat.IsDir() { + level.Error(logger).Log("msg", "Failed to open directory, disabling udev device properties", "path", *config.Path.UdevDataPath) } else { collector.getUdevDeviceProperties = getUdevDeviceProperties } @@ -285,7 +284,7 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error { continue } - info, err := getUdevDeviceProperties(stats.MajorNumber, stats.MinorNumber) + info, err := getUdevDeviceProperties(c.config, stats.MajorNumber, stats.MinorNumber) if err != nil { level.Debug(c.logger).Log("msg", "Failed to parse udev info", "err", err) } @@ -373,8 +372,8 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error { return nil } -func getUdevDeviceProperties(major, minor uint32) (udevInfo, error) { - filename := udevDataFilePath(fmt.Sprintf("b%d:%d", major, minor)) +func getUdevDeviceProperties(config NodeCollectorConfig, major, minor uint32) (udevInfo, error) { + filename := config.Path.udevDataFilePath(fmt.Sprintf("b%d:%d", major, minor)) data, err := os.Open(filename) if err != nil { diff --git a/collector/diskstats_openbsd.go b/collector/diskstats_openbsd.go index b5729bdc..90814a00 100644 --- a/collector/diskstats_openbsd.go +++ b/collector/diskstats_openbsd.go @@ -45,15 +45,12 @@ type diskstatsCollector struct { } func init() { - registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(DiskstatsDeviceFilterConfig) - return NewDiskstatsCollector(cfg, logger) - }) + registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) } // NewDiskstatsCollector returns a new Collector exposing disk device stats. -func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger) (Collector, error) { - deviceFilter, err := newDiskstatsDeviceFilter(config, logger) +func NewDiskstatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + deviceFilter, err := newDiskstatsDeviceFilter(config.DiskstatsDeviceFilter, logger) if err != nil { return nil, fmt.Errorf("failed to parse device filter flags: %w", err) } diff --git a/collector/diskstats_openbsd_amd64.go b/collector/diskstats_openbsd_amd64.go index 3d1c72f1..395f714b 100644 --- a/collector/diskstats_openbsd_amd64.go +++ b/collector/diskstats_openbsd_amd64.go @@ -56,15 +56,12 @@ type diskstatsCollector struct { } func init() { - registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(DiskstatsDeviceFilterConfig) - return NewDiskstatsCollector(cfg, logger) - }) + registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) } // NewDiskstatsCollector returns a new Collector exposing disk device stats. -func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger) (Collector, error) { - deviceFilter, err := newDiskstatsDeviceFilter(config, logger) +func NewDiskstatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + deviceFilter, err := newDiskstatsDeviceFilter(config.DiskstatsDeviceFilter, logger) if err != nil { return nil, fmt.Errorf("failed to parse device filter flags: %w", err) } diff --git a/collector/dmi.go b/collector/dmi.go index 30051d7c..dcba329d 100644 --- a/collector/dmi.go +++ b/collector/dmi.go @@ -34,14 +34,12 @@ type dmiCollector struct { } func init() { - registerCollector("dmi", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewDMICollector(logger) - }) + registerCollector("dmi", defaultEnabled, NewDMICollector) } // NewDMICollector returns a new Collector exposing DMI information. -func NewDMICollector(logger log.Logger) (Collector, error) { - fs, err := sysfs.NewFS(*sysPath) +func NewDMICollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := sysfs.NewFS(*config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } diff --git a/collector/drbd_linux.go b/collector/drbd_linux.go index 9d5befa3..9ffd118a 100644 --- a/collector/drbd_linux.go +++ b/collector/drbd_linux.go @@ -80,15 +80,14 @@ type drbdCollector struct { stringPair map[string]drbdStringPairMetric connected *prometheus.Desc logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("drbd", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return newDRBDCollector(logger) - }) + registerCollector("drbd", defaultDisabled, newDRBDCollector) } -func newDRBDCollector(logger log.Logger) (Collector, error) { +func newDRBDCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &drbdCollector{ numerical: map[string]drbdNumericalMetric{ "ns": newDRBDNumericalMetric( @@ -185,11 +184,12 @@ func newDRBDCollector(logger log.Logger) (Collector, error) { nil, ), logger: logger, + config: config, }, nil } func (c *drbdCollector) Update(ch chan<- prometheus.Metric) error { - statsFile := procFilePath("drbd") + statsFile := c.config.Path.procFilePath("drbd") file, err := os.Open(statsFile) if err != nil { if errors.Is(err, os.ErrNotExist) { diff --git a/collector/drm_linux.go b/collector/drm_linux.go index c431afb5..a38eb2fb 100644 --- a/collector/drm_linux.go +++ b/collector/drm_linux.go @@ -42,14 +42,12 @@ type drmCollector struct { } func init() { - registerCollector("drm", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewDrmCollector(logger) - }) + registerCollector("drm", defaultDisabled, NewDrmCollector) } // NewDrmCollector returns a new Collector exposing /sys/class/drm/card?/device stats. -func NewDrmCollector(logger log.Logger) (Collector, error) { - fs, err := sysfs.NewFS(*sysPath) +func NewDrmCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := sysfs.NewFS(*config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } diff --git a/collector/edac_linux.go b/collector/edac_linux.go index 715f0423..bd87f882 100644 --- a/collector/edac_linux.go +++ b/collector/edac_linux.go @@ -40,16 +40,15 @@ type edacCollector struct { csRowCECount *prometheus.Desc csRowUECount *prometheus.Desc logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("edac", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewEdacCollector(logger) - }) + registerCollector("edac", defaultEnabled, NewEdacCollector) } // NewEdacCollector returns a new Collector exposing edac stats. -func NewEdacCollector(logger log.Logger) (Collector, error) { +func NewEdacCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &edacCollector{ ceCount: prometheus.NewDesc( prometheus.BuildFQName(namespace, edacSubsystem, "correctable_errors_total"), @@ -72,11 +71,12 @@ func NewEdacCollector(logger log.Logger) (Collector, error) { []string{"controller", "csrow"}, nil, ), logger: logger, + config: config, }, nil } func (c *edacCollector) Update(ch chan<- prometheus.Metric) error { - memControllers, err := filepath.Glob(sysFilePath("devices/system/edac/mc/mc[0-9]*")) + memControllers, err := filepath.Glob(c.config.Path.sysFilePath("devices/system/edac/mc/mc[0-9]*")) if err != nil { return err } diff --git a/collector/entropy_linux.go b/collector/entropy_linux.go index 7416ff9d..f3a4588f 100644 --- a/collector/entropy_linux.go +++ b/collector/entropy_linux.go @@ -32,14 +32,12 @@ type entropyCollector struct { } func init() { - registerCollector("entropy", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewEntropyCollector(logger) - }) + registerCollector("entropy", defaultEnabled, NewEntropyCollector) } // NewEntropyCollector returns a new Collector exposing entropy stats. -func NewEntropyCollector(logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewEntropyCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/ethtool_linux.go b/collector/ethtool_linux.go index 5243cbfb..e05ed9e1 100644 --- a/collector/ethtool_linux.go +++ b/collector/ethtool_linux.go @@ -87,8 +87,8 @@ type EthtoolConfig struct { // makeEthtoolCollector is the internal constructor for EthtoolCollector. // This allows NewEthtoolTestCollector to override its .ethtool interface // for testing. -func makeEthtoolCollector(config EthtoolConfig, logger log.Logger) (*ethtoolCollector, error) { - fs, err := sysfs.NewFS(*sysPath) +func makeEthtoolCollector(config NodeCollectorConfig, logger log.Logger) (*ethtoolCollector, error) { + fs, err := sysfs.NewFS(*config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } @@ -102,8 +102,8 @@ func makeEthtoolCollector(config EthtoolConfig, logger log.Logger) (*ethtoolColl return ðtoolCollector{ fs: fs, ethtool: ðtoolLibrary{e}, - deviceFilter: newDeviceFilter(*config.DeviceExclude, *config.DeviceInclude), - metricsPattern: regexp.MustCompile(*config.IncludedMetrics), + deviceFilter: newDeviceFilter(*config.Ethtool.DeviceExclude, *config.Ethtool.DeviceInclude), + metricsPattern: regexp.MustCompile(*config.Ethtool.IncludedMetrics), logger: logger, entries: map[string]*prometheus.Desc{ "rx_bytes": prometheus.NewDesc( @@ -203,10 +203,7 @@ func makeEthtoolCollector(config EthtoolConfig, logger log.Logger) (*ethtoolColl } func init() { - registerCollector("ethtool", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(EthtoolConfig) - return NewEthtoolCollector(cfg, logger) - }) + registerCollector("ethtool", defaultDisabled, NewEthtoolCollector) } // Generate the fully-qualified metric name for the ethool metric. @@ -218,7 +215,7 @@ func buildEthtoolFQName(metric string) string { } // NewEthtoolCollector returns a new Collector exposing ethtool stats. -func NewEthtoolCollector(config EthtoolConfig, logger log.Logger) (Collector, error) { +func NewEthtoolCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return makeEthtoolCollector(config, logger) } diff --git a/collector/ethtool_linux_test.go b/collector/ethtool_linux_test.go index 50db2be4..6136ca3d 100644 --- a/collector/ethtool_linux_test.go +++ b/collector/ethtool_linux_test.go @@ -23,6 +23,7 @@ import ( "syscall" "testing" + "github.com/docker/cli/cli/config" "github.com/go-kit/log" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/testutil" @@ -365,7 +366,7 @@ node_network_supported_speed_bytes{device="eth0",duplex="full",mode="10baseT"} 1 node_network_supported_speed_bytes{device="eth0",duplex="half",mode="100baseT"} 1.25e+07 node_network_supported_speed_bytes{device="eth0",duplex="half",mode="10baseT"} 1.25e+06 ` - *sysPath = "fixtures/sys" + *config.Path.SysPath = "fixtures/sys" config := NodeCollectorConfig{} logger := log.NewLogfmtLogger(os.Stderr) diff --git a/collector/exec_bsd.go b/collector/exec_bsd.go index a659328a..06e31865 100644 --- a/collector/exec_bsd.go +++ b/collector/exec_bsd.go @@ -28,13 +28,11 @@ type execCollector struct { } func init() { - registerCollector("exec", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewExecCollector(logger) - }) + registerCollector("exec", defaultEnabled, NewExecCollector) } // NewExecCollector returns a new Collector exposing system execution statistics. -func NewExecCollector(logger log.Logger) (Collector, error) { +func NewExecCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { // From sys/vm/vm_meter.c: // All are of type CTLTYPE_UINT. // diff --git a/collector/fibrechannel_linux.go b/collector/fibrechannel_linux.go index c43605fd..2e50ee36 100644 --- a/collector/fibrechannel_linux.go +++ b/collector/fibrechannel_linux.go @@ -36,17 +36,15 @@ type fibrechannelCollector struct { } func init() { - registerCollector("fibrechannel", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewFibreChannelCollector(logger) - }) + registerCollector("fibrechannel", defaultEnabled, NewFibreChannelCollector) } // NewFibreChannelCollector returns a new Collector exposing FibreChannel stats. -func NewFibreChannelCollector(logger log.Logger) (Collector, error) { +func NewFibreChannelCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { var i fibrechannelCollector var err error - i.fs, err = sysfs.NewFS(*sysPath) + i.fs, err = sysfs.NewFS(*config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } diff --git a/collector/filefd_linux.go b/collector/filefd_linux.go index 51984a4a..ac6478ac 100644 --- a/collector/filefd_linux.go +++ b/collector/filefd_linux.go @@ -33,21 +33,20 @@ const ( type fileFDStatCollector struct { logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector(fileFDStatSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewFileFDStatCollector(logger) - }) + registerCollector(fileFDStatSubsystem, defaultEnabled, NewFileFDStatCollector) } // NewFileFDStatCollector returns a new Collector exposing file-nr stats. -func NewFileFDStatCollector(logger log.Logger) (Collector, error) { - return &fileFDStatCollector{logger}, nil +func NewFileFDStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + return &fileFDStatCollector{logger, config}, nil } func (c *fileFDStatCollector) Update(ch chan<- prometheus.Metric) error { - fileFDStat, err := parseFileFDStats(procFilePath("sys/fs/file-nr")) + fileFDStat, err := parseFileFDStats(c.config.Path.procFilePath("sys/fs/file-nr")) if err != nil { return fmt.Errorf("couldn't get file-nr: %w", err) } diff --git a/collector/filesystem_common.go b/collector/filesystem_common.go index dbf22876..2470b761 100644 --- a/collector/filesystem_common.go +++ b/collector/filesystem_common.go @@ -47,7 +47,7 @@ type filesystemCollector struct { filesDesc, filesFreeDesc *prometheus.Desc roDesc, deviceErrorDesc *prometheus.Desc logger log.Logger - config FilesystemConfig + config NodeCollectorConfig } type filesystemLabels struct { @@ -70,46 +70,43 @@ type FilesystemConfig struct { } func init() { - registerCollector("filesystem", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(FilesystemConfig) - return NewFilesystemCollector(cfg, logger) - }) + registerCollector("filesystem", defaultEnabled, NewFilesystemCollector) } // NewFilesystemCollector returns a new Collector exposing filesystems stats. -func NewFilesystemCollector(config FilesystemConfig, logger log.Logger) (Collector, error) { - if *config.OldMountPointsExcluded != "" { +func NewFilesystemCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + if *config.Filesystem.OldMountPointsExcluded != "" { if !mountPointsExcludeSet { level.Warn(logger).Log("msg", "--collector.filesystem.ignored-mount-points is DEPRECATED and will be removed in 2.0.0, use --collector.filesystem.mount-points-exclude") - *config.MountPointsExclude = *config.OldMountPointsExcluded + *config.Filesystem.MountPointsExclude = *config.Filesystem.OldMountPointsExcluded } else { return nil, errors.New("--collector.filesystem.ignored-mount-points and --collector.filesystem.mount-points-exclude are mutually exclusive") } } - if *config.MountPointsExclude != "" { - level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.mount-points-exclude", "flag", *config.MountPointsExclude) + if *config.Filesystem.MountPointsExclude != "" { + level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.mount-points-exclude", "flag", *config.Filesystem.MountPointsExclude) } else { - *config.MountPointsExclude = defMountPointsExcluded + *config.Filesystem.MountPointsExclude = defMountPointsExcluded } - if *config.OldFSTypesExcluded != "" { + if *config.Filesystem.OldFSTypesExcluded != "" { if !fsTypesExcludeSet { level.Warn(logger).Log("msg", "--collector.filesystem.ignored-fs-types is DEPRECATED and will be removed in 2.0.0, use --collector.filesystem.fs-types-exclude") - *config.FSTypesExclude = *config.OldFSTypesExcluded + *config.Filesystem.FSTypesExclude = *config.Filesystem.OldFSTypesExcluded } else { return nil, errors.New("--collector.filesystem.ignored-fs-types and --collector.filesystem.fs-types-exclude are mutually exclusive") } } - if *config.FSTypesExclude != "" { - level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.fs-types-exclude", "flag", *config.FSTypesExclude) + if *config.Filesystem.FSTypesExclude != "" { + level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.fs-types-exclude", "flag", *config.Filesystem.FSTypesExclude) } else { - *config.FSTypesExclude = defFSTypesExcluded + *config.Filesystem.FSTypesExclude = defFSTypesExcluded } subsystem := "filesystem" - mountPointPattern := regexp.MustCompile(*config.MountPointsExclude) - filesystemsTypesPattern := regexp.MustCompile(*config.FSTypesExclude) + mountPointPattern := regexp.MustCompile(*config.Filesystem.MountPointsExclude) + filesystemsTypesPattern := regexp.MustCompile(*config.Filesystem.FSTypesExclude) sizeDesc := prometheus.NewDesc( prometheus.BuildFQName(namespace, subsystem, "size_bytes"), diff --git a/collector/filesystem_linux.go b/collector/filesystem_linux.go index 813532d0..c6a924c8 100644 --- a/collector/filesystem_linux.go +++ b/collector/filesystem_linux.go @@ -41,7 +41,7 @@ var stuckMountsMtx = &sync.Mutex{} // GetStats returns filesystem stats. func (c *filesystemCollector) GetStats() ([]filesystemStats, error) { - mps, err := mountPointDetails(c.logger) + mps, err := mountPointDetails(c.config, c.logger) if err != nil { return nil, err } @@ -50,7 +50,7 @@ func (c *filesystemCollector) GetStats() ([]filesystemStats, error) { statChan := make(chan filesystemStats) wg := sync.WaitGroup{} - workerCount := *c.config.StatWorkerCount + workerCount := *c.config.Filesystem.StatWorkerCount if workerCount < 1 { workerCount = 1 } @@ -103,10 +103,10 @@ func (c *filesystemCollector) GetStats() ([]filesystemStats, error) { func (c *filesystemCollector) processStat(labels filesystemLabels) filesystemStats { success := make(chan struct{}) - go stuckMountWatcher(c.config.MountTimeout, labels.mountPoint, success, c.logger) + go stuckMountWatcher(c.config.Filesystem.MountTimeout, labels.mountPoint, success, c.logger) buf := new(unix.Statfs_t) - err := unix.Statfs(rootfsFilePath(labels.mountPoint), buf) + err := unix.Statfs(c.config.Path.rootfsFilePath(labels.mountPoint), buf) stuckMountsMtx.Lock() close(success) @@ -118,7 +118,7 @@ func (c *filesystemCollector) processStat(labels filesystemLabels) filesystemSta stuckMountsMtx.Unlock() if err != nil { - level.Debug(c.logger).Log("msg", "Error on statfs() system call", "rootfs", rootfsFilePath(labels.mountPoint), "err", err) + level.Debug(c.logger).Log("msg", "Error on statfs() system call", "rootfs", c.config.Path.rootfsFilePath(labels.mountPoint), "err", err) return filesystemStats{ labels: labels, deviceError: 1, @@ -166,22 +166,22 @@ func stuckMountWatcher(mountTimeout *time.Duration, mountPoint string, success c } } -func mountPointDetails(logger log.Logger) ([]filesystemLabels, error) { - file, err := os.Open(procFilePath("1/mounts")) +func mountPointDetails(config NodeCollectorConfig, logger log.Logger) ([]filesystemLabels, error) { + file, err := os.Open(config.Path.procFilePath("1/mounts")) if errors.Is(err, os.ErrNotExist) { // 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) - file, err = os.Open(procFilePath("mounts")) + file, err = os.Open(config.Path.procFilePath("mounts")) } if err != nil { return nil, err } defer file.Close() - return parseFilesystemLabels(file) + return parseFilesystemLabels(config, file) } -func parseFilesystemLabels(r io.Reader) ([]filesystemLabels, error) { +func parseFilesystemLabels(config NodeCollectorConfig, r io.Reader) ([]filesystemLabels, error) { var filesystems []filesystemLabels scanner := bufio.NewScanner(r) @@ -199,7 +199,7 @@ func parseFilesystemLabels(r io.Reader) ([]filesystemLabels, error) { filesystems = append(filesystems, filesystemLabels{ device: parts[0], - mountPoint: rootfsStripPrefix(parts[1]), + mountPoint: config.Path.rootfsStripPrefix(parts[1]), fsType: parts[2], options: parts[3], }) diff --git a/collector/hwmon_linux.go b/collector/hwmon_linux.go index e24d77fb..d6c3563e 100644 --- a/collector/hwmon_linux.go +++ b/collector/hwmon_linux.go @@ -43,15 +43,13 @@ var ( ) func init() { - registerCollector("hwmon", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(HwMonConfig) - return NewHwMonCollector(cfg, logger) - }) + registerCollector("hwmon", defaultEnabled, NewHwMonCollector) } type hwMonCollector struct { deviceFilter deviceFilter logger log.Logger + config NodeCollectorConfig } type HwMonConfig struct { @@ -61,11 +59,12 @@ type HwMonConfig struct { // NewHwMonCollector returns a new Collector exposing /sys/class/hwmon stats // (similar to lm-sensors). -func NewHwMonCollector(config HwMonConfig, logger log.Logger) (Collector, error) { +func NewHwMonCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &hwMonCollector{ logger: logger, - deviceFilter: newDeviceFilter(*config.ChipExclude, *config.ChipInclude), + deviceFilter: newDeviceFilter(*config.HwMon.ChipExclude, *config.HwMon.ChipInclude), + config: config, }, nil } @@ -436,7 +435,7 @@ func (c *hwMonCollector) Update(ch chan<- prometheus.Metric) error { // Step 1: scan /sys/class/hwmon, resolve all symlinks and call // updatesHwmon for each folder - hwmonPathName := filepath.Join(sysFilePath("class"), "hwmon") + hwmonPathName := filepath.Join(c.config.Path.sysFilePath("class"), "hwmon") hwmonFiles, err := os.ReadDir(hwmonPathName) if err != nil { diff --git a/collector/infiniband_linux.go b/collector/infiniband_linux.go index e4d7395d..3fe28ab0 100644 --- a/collector/infiniband_linux.go +++ b/collector/infiniband_linux.go @@ -36,17 +36,15 @@ type infinibandCollector struct { } func init() { - registerCollector("infiniband", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewInfiniBandCollector(logger) - }) + registerCollector("infiniband", defaultEnabled, NewInfiniBandCollector) } // NewInfiniBandCollector returns a new Collector exposing InfiniBand stats. -func NewInfiniBandCollector(logger log.Logger) (Collector, error) { +func NewInfiniBandCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { var i infinibandCollector var err error - i.fs, err = sysfs.NewFS(*sysPath) + i.fs, err = sysfs.NewFS(*config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } diff --git a/collector/interrupts_common.go b/collector/interrupts_common.go index 614f4b61..9f2b4166 100644 --- a/collector/interrupts_common.go +++ b/collector/interrupts_common.go @@ -25,16 +25,15 @@ import ( type interruptsCollector struct { desc typedDesc logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("interrupts", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewInterruptsCollector(logger) - }) + registerCollector("interrupts", defaultDisabled, NewInterruptsCollector) } // NewInterruptsCollector returns a new Collector exposing interrupts stats. -func NewInterruptsCollector(logger log.Logger) (Collector, error) { +func NewInterruptsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &interruptsCollector{ desc: typedDesc{prometheus.NewDesc( namespace+"_interrupts_total", @@ -42,5 +41,6 @@ func NewInterruptsCollector(logger log.Logger) (Collector, error) { interruptLabelNames, nil, ), prometheus.CounterValue}, logger: logger, + config: config, }, nil } diff --git a/collector/interrupts_linux.go b/collector/interrupts_linux.go index ede78191..05ff3375 100644 --- a/collector/interrupts_linux.go +++ b/collector/interrupts_linux.go @@ -33,7 +33,7 @@ var ( ) func (c *interruptsCollector) Update(ch chan<- prometheus.Metric) (err error) { - interrupts, err := getInterrupts() + interrupts, err := getInterrupts(c.config) if err != nil { return fmt.Errorf("couldn't get interrupts: %w", err) } @@ -55,8 +55,8 @@ type interrupt struct { values []string } -func getInterrupts() (map[string]interrupt, error) { - file, err := os.Open(procFilePath("interrupts")) +func getInterrupts(config NodeCollectorConfig) (map[string]interrupt, error) { + file, err := os.Open(config.Path.procFilePath("interrupts")) if err != nil { return nil, err } diff --git a/collector/ipvs_linux.go b/collector/ipvs_linux.go index cf67f676..73853fda 100644 --- a/collector/ipvs_linux.go +++ b/collector/ipvs_linux.go @@ -66,10 +66,7 @@ var ( ) func init() { - registerCollector("ipvs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(IPVSConfig) - return NewIPVSCollector(cfg, logger) - }) + registerCollector("ipvs", defaultEnabled, NewIPVSCollector) } type IPVSConfig struct { @@ -78,27 +75,27 @@ type IPVSConfig struct { // NewIPVSCollector sets up a new collector for IPVS metrics. It accepts the // "procfs" config parameter to override the default proc location (/proc). -func NewIPVSCollector(config IPVSConfig, logger log.Logger) (Collector, error) { +func NewIPVSCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return newIPVSCollector(config, logger) } -func newIPVSCollector(config IPVSConfig, logger log.Logger) (*ipvsCollector, error) { +func newIPVSCollector(config NodeCollectorConfig, logger log.Logger) (*ipvsCollector, error) { var ( c ipvsCollector err error subsystem = "ipvs" ) - if *config.Labels == "" { - *config.Labels = strings.Join(fullIpvsBackendLabels, ",") + if *config.IPVS.Labels == "" { + *config.IPVS.Labels = strings.Join(fullIpvsBackendLabels, ",") } - if c.backendLabels, err = c.parseIpvsLabels(*config.Labels); err != nil { + if c.backendLabels, err = c.parseIpvsLabels(*config.IPVS.Labels); err != nil { return nil, err } c.logger = logger - c.fs, err = procfs.NewFS(*procPath) + c.fs, err = procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/ksmd_linux.go b/collector/ksmd_linux.go index f642e5d8..dbdf23d5 100644 --- a/collector/ksmd_linux.go +++ b/collector/ksmd_linux.go @@ -32,12 +32,11 @@ var ( type ksmdCollector struct { metricDescs map[string]*prometheus.Desc logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("ksmd", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewKsmdCollector(logger) - }) + registerCollector("ksmd", defaultDisabled, NewKsmdCollector) } func getCanonicalMetricName(filename string) string { @@ -52,7 +51,7 @@ func getCanonicalMetricName(filename string) string { } // NewKsmdCollector returns a new Collector exposing kernel/system statistics. -func NewKsmdCollector(logger log.Logger) (Collector, error) { +func NewKsmdCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { subsystem := "ksmd" descs := make(map[string]*prometheus.Desc) @@ -61,13 +60,13 @@ func NewKsmdCollector(logger log.Logger) (Collector, error) { prometheus.BuildFQName(namespace, subsystem, getCanonicalMetricName(n)), fmt.Sprintf("ksmd '%s' file.", n), nil, nil) } - return &ksmdCollector{descs, logger}, nil + return &ksmdCollector{descs, logger, config}, nil } // Update implements Collector and exposes kernel and system statistics. func (c *ksmdCollector) Update(ch chan<- prometheus.Metric) error { for _, n := range ksmdFiles { - val, err := readUintFromFile(sysFilePath(filepath.Join("kernel/mm/ksm", n))) + val, err := readUintFromFile(c.config.Path.sysFilePath(filepath.Join("kernel/mm/ksm", n))) if err != nil { return err } diff --git a/collector/lnstat_linux.go b/collector/lnstat_linux.go index a5809d1c..8ac99a22 100644 --- a/collector/lnstat_linux.go +++ b/collector/lnstat_linux.go @@ -27,16 +27,15 @@ import ( type lnstatCollector struct { logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("lnstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewLnstatCollector(logger) - }) + registerCollector("lnstat", defaultDisabled, NewLnstatCollector) } -func NewLnstatCollector(logger log.Logger) (Collector, error) { - return &lnstatCollector{logger}, nil +func NewLnstatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + return &lnstatCollector{logger, config}, nil } func (c *lnstatCollector) Update(ch chan<- prometheus.Metric) error { @@ -44,7 +43,7 @@ func (c *lnstatCollector) Update(ch chan<- prometheus.Metric) error { subsystem = "lnstat" ) - fs, err := procfs.NewFS(*procPath) + fs, err := procfs.NewFS(*c.config.Path.ProcPath) if err != nil { return fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/loadavg.go b/collector/loadavg.go index 259a9f9d..172ec4d0 100644 --- a/collector/loadavg.go +++ b/collector/loadavg.go @@ -28,16 +28,15 @@ import ( type loadavgCollector struct { metric []typedDesc logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("loadavg", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewLoadavgCollector(logger) - }) + registerCollector("loadavg", defaultEnabled, NewLoadavgCollector) } // NewLoadavgCollector returns a new Collector exposing load average stats. -func NewLoadavgCollector(logger log.Logger) (Collector, error) { +func NewLoadavgCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &loadavgCollector{ metric: []typedDesc{ {prometheus.NewDesc(namespace+"_load1", "1m load average.", nil, nil), prometheus.GaugeValue}, @@ -45,11 +44,12 @@ func NewLoadavgCollector(logger log.Logger) (Collector, error) { {prometheus.NewDesc(namespace+"_load15", "15m load average.", nil, nil), prometheus.GaugeValue}, }, logger: logger, + config: config, }, nil } func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) error { - loads, err := getLoad() + loads, err := getLoad(c.config) if err != nil { return fmt.Errorf("couldn't get load: %w", err) } diff --git a/collector/loadavg_linux.go b/collector/loadavg_linux.go index aab11b18..075eb278 100644 --- a/collector/loadavg_linux.go +++ b/collector/loadavg_linux.go @@ -24,12 +24,12 @@ import ( ) // Read loadavg from /proc. -func getLoad() (loads []float64, err error) { - data, err := os.ReadFile(procFilePath("loadavg")) +func getLoad(config NodeCollectorConfig) (loads []float64, err error) { + data, err := os.ReadFile(config.Path.procFilePath("loadavg")) if err != nil { return nil, err } - loads, err = parseLoad(string(data)) + loads, err = parseLoad(config, string(data)) if err != nil { return nil, err } @@ -37,11 +37,11 @@ func getLoad() (loads []float64, err error) { } // Parse /proc loadavg and return 1m, 5m and 15m. -func parseLoad(data string) (loads []float64, err error) { +func parseLoad(config NodeCollectorConfig, data string) (loads []float64, err error) { loads = make([]float64, 3) parts := strings.Fields(data) if len(parts) < 3 { - return nil, fmt.Errorf("unexpected content in %s", procFilePath("loadavg")) + return nil, fmt.Errorf("unexpected content in %s", config.Path.procFilePath("loadavg")) } for i, load := range parts[0:3] { loads[i], err = strconv.ParseFloat(load, 64) diff --git a/collector/logind_linux.go b/collector/logind_linux.go index 42c0da36..0a087fbf 100644 --- a/collector/logind_linux.go +++ b/collector/logind_linux.go @@ -82,13 +82,11 @@ type logindSeatEntry struct { } func init() { - registerCollector("logind", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewLogindCollector(logger) - }) + registerCollector("logind", defaultDisabled, NewLogindCollector) } // NewLogindCollector returns a new Collector exposing logind statistics. -func NewLogindCollector(logger log.Logger) (Collector, error) { +func NewLogindCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &logindCollector{logger}, nil } diff --git a/collector/mdadm_linux.go b/collector/mdadm_linux.go index 7e4eb86f..86c08b57 100644 --- a/collector/mdadm_linux.go +++ b/collector/mdadm_linux.go @@ -29,17 +29,16 @@ import ( type mdadmCollector struct { logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("mdadm", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewMdadmCollector(logger) - }) + registerCollector("mdadm", defaultEnabled, NewMdadmCollector) } // NewMdadmCollector returns a new Collector exposing raid statistics. -func NewMdadmCollector(logger log.Logger) (Collector, error) { - return &mdadmCollector{logger}, nil +func NewMdadmCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + return &mdadmCollector{logger, config}, nil } var ( @@ -104,7 +103,7 @@ var ( ) func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) error { - fs, err := procfs.NewFS(*procPath) + fs, err := procfs.NewFS(*c.config.Path.ProcPath) if err != nil { return fmt.Errorf("failed to open procfs: %w", err) @@ -114,7 +113,7 @@ func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) error { if err != nil { 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", *c.config.Path.ProcPath) return ErrNoData } diff --git a/collector/meminfo.go b/collector/meminfo.go index 72283662..020ff8aa 100644 --- a/collector/meminfo.go +++ b/collector/meminfo.go @@ -32,17 +32,16 @@ const ( type meminfoCollector struct { logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("meminfo", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewMeminfoCollector(logger) - }) + registerCollector("meminfo", defaultEnabled, NewMeminfoCollector) } // NewMeminfoCollector returns a new Collector exposing memory stats. -func NewMeminfoCollector(logger log.Logger) (Collector, error) { - return &meminfoCollector{logger}, nil +func NewMeminfoCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + return &meminfoCollector{logger, config}, nil } // Update calls (*meminfoCollector).getMemInfo to get the platform specific diff --git a/collector/meminfo_linux.go b/collector/meminfo_linux.go index cee29502..c6c24970 100644 --- a/collector/meminfo_linux.go +++ b/collector/meminfo_linux.go @@ -31,7 +31,7 @@ var ( ) func (c *meminfoCollector) getMemInfo() (map[string]float64, error) { - file, err := os.Open(procFilePath("meminfo")) + file, err := os.Open(c.config.Path.procFilePath("meminfo")) if err != nil { return nil, err } diff --git a/collector/meminfo_numa_linux.go b/collector/meminfo_numa_linux.go index f58e5c9a..5725ec86 100644 --- a/collector/meminfo_numa_linux.go +++ b/collector/meminfo_numa_linux.go @@ -46,6 +46,7 @@ type meminfoMetric struct { type meminfoNumaCollector struct { metricDescs map[string]*prometheus.Desc logger log.Logger + config NodeCollectorConfig } func init() { @@ -57,11 +58,12 @@ func NewMeminfoNumaCollector(config NodeCollectorConfig, logger log.Logger) (Col return &meminfoNumaCollector{ metricDescs: map[string]*prometheus.Desc{}, logger: logger, + config: config, }, nil } func (c *meminfoNumaCollector) Update(ch chan<- prometheus.Metric) error { - metrics, err := getMemInfoNuma() + metrics, err := getMemInfoNuma(c.config) if err != nil { return fmt.Errorf("couldn't get NUMA meminfo: %w", err) } @@ -79,12 +81,12 @@ func (c *meminfoNumaCollector) Update(ch chan<- prometheus.Metric) error { return nil } -func getMemInfoNuma() ([]meminfoMetric, error) { +func getMemInfoNuma(config NodeCollectorConfig) ([]meminfoMetric, error) { var ( metrics []meminfoMetric ) - nodes, err := filepath.Glob(sysFilePath("devices/system/node/node[0-9]*")) + nodes, err := filepath.Glob(config.Path.sysFilePath("devices/system/node/node[0-9]*")) if err != nil { return nil, err } diff --git a/collector/memory_bsd.go b/collector/memory_bsd.go index 56fc85ff..6189a141 100644 --- a/collector/memory_bsd.go +++ b/collector/memory_bsd.go @@ -37,9 +37,7 @@ type memoryCollector struct { } func init() { - registerCollector("meminfo", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewMemoryCollector(logger) - }) + registerCollector("meminfo", defaultEnabled, NewMemoryCollector) } // NewMemoryCollector returns a new Collector exposing memory stats. diff --git a/collector/mountstats_linux.go b/collector/mountstats_linux.go index c27f86b2..c2515a34 100644 --- a/collector/mountstats_linux.go +++ b/collector/mountstats_linux.go @@ -107,14 +107,12 @@ type nfsDeviceIdentifier struct { } func init() { - registerCollector("mountstats", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewMountStatsCollector(logger) - }) + registerCollector("mountstats", defaultDisabled, NewMountStatsCollector) } // NewMountStatsCollector returns a new Collector exposing NFS statistics. -func NewMountStatsCollector(logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewMountStatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/netclass_linux.go b/collector/netclass_linux.go index 860b6e13..a5ee6cad 100644 --- a/collector/netclass_linux.go +++ b/collector/netclass_linux.go @@ -35,14 +35,11 @@ type netClassCollector struct { ignoredDevicesPattern *regexp.Regexp metricDescs map[string]*prometheus.Desc logger log.Logger - config NetClassConfig + config NodeCollectorConfig } func init() { - registerCollector("netclass", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(NetClassConfig) - return NewNetClassCollector(cfg, logger) - }) + registerCollector("netclass", defaultEnabled, NewNetClassCollector) } type NetClassConfig struct { @@ -53,12 +50,12 @@ type NetClassConfig struct { } // NewNetClassCollector returns a new Collector exposing network class stats. -func NewNetClassCollector(config NetClassConfig, logger log.Logger) (Collector, error) { - fs, err := sysfs.NewFS(*sysPath) +func NewNetClassCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := sysfs.NewFS(*config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } - pattern := regexp.MustCompile(*config.IgnoredDevices) + pattern := regexp.MustCompile(*config.NetClass.IgnoredDevices) return &netClassCollector{ fs: fs, subsystem: "network", @@ -70,7 +67,7 @@ func NewNetClassCollector(config NetClassConfig, logger log.Logger) (Collector, } func (c *netClassCollector) Update(ch chan<- prometheus.Metric) error { - if *c.config.Netlink { + if *c.config.NetClass.Netlink { return c.netClassRTNLUpdate(ch) } return c.netClassSysfsUpdate(ch) @@ -126,7 +123,7 @@ func (c *netClassCollector) netClassSysfsUpdate(ch chan<- prometheus.Metric) err if ifaceInfo.Speed != nil { // Some devices return -1 if the speed is unknown. - if *ifaceInfo.Speed >= 0 || !*c.config.InvalidSpeed { + if *ifaceInfo.Speed >= 0 || !*c.config.NetClass.InvalidSpeed { speedBytes := int64(*ifaceInfo.Speed * 1000 * 1000 / 8) pushMetric(ch, c.getFieldDesc("speed_bytes"), "speed_bytes", speedBytes, prometheus.GaugeValue, ifaceInfo.Name) } diff --git a/collector/netclass_rtnl_linux.go b/collector/netclass_rtnl_linux.go index 5b348474..0bf98cf3 100644 --- a/collector/netclass_rtnl_linux.go +++ b/collector/netclass_rtnl_linux.go @@ -140,7 +140,7 @@ func (c *netClassCollector) netClassRTNLUpdate(ch chan<- prometheus.Metric) erro pushMetric(ch, c.getFieldDesc("protocol_type"), "protocol_type", msg.Type, prometheus.GaugeValue, msg.Attributes.Name) // Skip statistics if argument collector.netclass_rtnl.with-stats is false or statistics are unavailable. - if c.config.RTNLWithStats == nil || !*c.config.RTNLWithStats || msg.Attributes.Stats64 == nil { + if c.config.NetClass.RTNLWithStats == nil || !*c.config.NetClass.RTNLWithStats || msg.Attributes.Stats64 == nil { continue } diff --git a/collector/netdev_common.go b/collector/netdev_common.go index 1e2ca293..ce061c3a 100644 --- a/collector/netdev_common.go +++ b/collector/netdev_common.go @@ -35,16 +35,13 @@ type netDevCollector struct { metricDescsMutex sync.Mutex metricDescs map[string]*prometheus.Desc logger log.Logger - config NetDevConfig + config NodeCollectorConfig } type netDevStats map[string]map[string]uint64 func init() { - registerCollector("netdev", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(NetDevConfig) - return NewNetDevCollector(cfg, logger) - }) + registerCollector("netdev", defaultEnabled, NewNetDevCollector) } type NetDevConfig struct { @@ -58,40 +55,40 @@ type NetDevConfig struct { } // NewNetDevCollector returns a new Collector exposing network device stats. -func NewNetDevCollector(config NetDevConfig, logger log.Logger) (Collector, error) { - if *config.OldDeviceInclude != "" { - if *config.DeviceInclude == "" { +func NewNetDevCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + if *config.NetDev.OldDeviceInclude != "" { + if *config.NetDev.DeviceInclude == "" { level.Warn(logger).Log("msg", "--collector.netdev.device-whitelist is DEPRECATED and will be removed in 2.0.0, use --collector.netdev.device-include") - *config.DeviceInclude = *config.OldDeviceInclude + *config.NetDev.DeviceInclude = *config.NetDev.OldDeviceInclude } else { return nil, errors.New("--collector.netdev.device-whitelist and --collector.netdev.device-include are mutually exclusive") } } - if *config.OldDeviceExclude != "" { - if *config.DeviceExclude == "" { + if *config.NetDev.OldDeviceExclude != "" { + if *config.NetDev.DeviceExclude == "" { level.Warn(logger).Log("msg", "--collector.netdev.device-blacklist is DEPRECATED and will be removed in 2.0.0, use --collector.netdev.device-exclude") - *config.DeviceExclude = *config.OldDeviceExclude + *config.NetDev.DeviceExclude = *config.NetDev.OldDeviceExclude } else { return nil, errors.New("--collector.netdev.device-blacklist and --collector.netdev.device-exclude are mutually exclusive") } } - if *config.DeviceExclude != "" && *config.DeviceInclude != "" { + if *config.NetDev.DeviceExclude != "" && *config.NetDev.DeviceInclude != "" { return nil, errors.New("device-exclude & device-include are mutually exclusive") } - if *config.DeviceExclude != "" { - level.Info(logger).Log("msg", "Parsed flag --collector.netdev.device-exclude", "flag", *netdevDeviceExclude) + if *config.NetDev.DeviceExclude != "" { + level.Info(logger).Log("msg", "Parsed flag --collector.netdev.device-exclude", "flag", *config.NetDev.DeviceExclude) } - if *config.DeviceInclude != "" { - level.Info(logger).Log("msg", "Parsed Flag --collector.netdev.device-include", "flag", *netdevDeviceInclude) + if *config.NetDev.DeviceInclude != "" { + level.Info(logger).Log("msg", "Parsed Flag --collector.netdev.device-include", "flag", *config.NetDev.DeviceInclude) } return &netDevCollector{ subsystem: "network", - deviceFilter: newDeviceFilter(*config.DeviceExclude, *config.DeviceInclude), + deviceFilter: newDeviceFilter(*config.NetDev.DeviceExclude, *config.NetDev.DeviceInclude), metricDescs: map[string]*prometheus.Desc{}, logger: logger, config: config, @@ -115,12 +112,12 @@ func (c *netDevCollector) metricDesc(key string) *prometheus.Desc { } func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error { - netDev, err := getNetDevStats(c.config.Netlink, &c.deviceFilter, c.logger) + netDev, err := getNetDevStats(c.config, c.config.NetDev.Netlink, &c.deviceFilter, c.logger) if err != nil { return fmt.Errorf("couldn't get netstats: %w", err) } for dev, devStats := range netDev { - if !*c.config.DetailedMetrics { + if !*c.config.NetDev.DetailedMetrics { legacy(devStats) } for key, value := range devStats { @@ -128,7 +125,7 @@ func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error { ch <- prometheus.MustNewConstMetric(desc, prometheus.CounterValue, float64(value), dev) } } - if *c.config.AddressInfo { + if *c.config.NetDev.AddressInfo { interfaces, err := net.Interfaces() if err != nil { return fmt.Errorf("could not get network interfaces: %w", err) diff --git a/collector/netdev_linux.go b/collector/netdev_linux.go index 0d3ce780..1b9e9166 100644 --- a/collector/netdev_linux.go +++ b/collector/netdev_linux.go @@ -25,11 +25,11 @@ import ( "github.com/prometheus/procfs" ) -func getNetDevStats(netDevNetlink *bool, filter *deviceFilter, logger log.Logger) (netDevStats, error) { +func getNetDevStats(config NodeCollectorConfig, netDevNetlink *bool, filter *deviceFilter, logger log.Logger) (netDevStats, error) { if *netDevNetlink { return netlinkStats(filter, logger) } - return procNetDevStats(filter, logger) + return procNetDevStats(config, filter, logger) } func netlinkStats(filter *deviceFilter, logger log.Logger) (netDevStats, error) { @@ -97,10 +97,10 @@ func parseNetlinkStats(links []rtnetlink.LinkMessage, filter *deviceFilter, logg return metrics } -func procNetDevStats(filter *deviceFilter, logger log.Logger) (netDevStats, error) { +func procNetDevStats(config NodeCollectorConfig, filter *deviceFilter, logger log.Logger) (netDevStats, error) { metrics := netDevStats{} - fs, err := procfs.NewFS(*procPath) + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return metrics, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/netisr_freebsd.go b/collector/netisr_freebsd.go index 8977a57e..d8e5dd35 100644 --- a/collector/netisr_freebsd.go +++ b/collector/netisr_freebsd.go @@ -33,12 +33,10 @@ const ( ) func init() { - registerCollector("netisr", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewNetisrCollector(logger) - }) + registerCollector("netisr", defaultEnabled, NewNetisrCollector) } -func NewNetisrCollector(logger log.Logger) (Collector, error) { +func NewNetisrCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &netisrCollector{ sysctls: []bsdSysctl{ { diff --git a/collector/netstat_linux.go b/collector/netstat_linux.go index a05be8af..c55ebd7d 100644 --- a/collector/netstat_linux.go +++ b/collector/netstat_linux.go @@ -37,13 +37,11 @@ const ( type netStatCollector struct { fieldPattern *regexp.Regexp logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector(netStatsSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(NetStatConfig) - return NewNetStatCollector(cfg, logger) - }) + registerCollector(netStatsSubsystem, defaultEnabled, NewNetStatCollector) } type NetStatConfig struct { @@ -52,24 +50,25 @@ type NetStatConfig struct { // NewNetStatCollector takes and returns // a new Collector exposing network stats. -func NewNetStatCollector(config NetStatConfig, logger log.Logger) (Collector, error) { - pattern := regexp.MustCompile(*config.Fields) +func NewNetStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + pattern := regexp.MustCompile(*config.NetStat.Fields) return &netStatCollector{ fieldPattern: pattern, logger: logger, + config: config, }, nil } func (c *netStatCollector) Update(ch chan<- prometheus.Metric) error { - netStats, err := getNetStats(procFilePath("net/netstat")) + netStats, err := getNetStats(c.config.Path.procFilePath("net/netstat")) if err != nil { return fmt.Errorf("couldn't get netstats: %w", err) } - snmpStats, err := getNetStats(procFilePath("net/snmp")) + snmpStats, err := getNetStats(c.config.Path.procFilePath("net/snmp")) if err != nil { return fmt.Errorf("couldn't get SNMP stats: %w", err) } - snmp6Stats, err := getSNMP6Stats(procFilePath("net/snmp6")) + snmp6Stats, err := getSNMP6Stats(c.config.Path.procFilePath("net/snmp6")) if err != nil { return fmt.Errorf("couldn't get SNMP6 stats: %w", err) } diff --git a/collector/network_route_linux.go b/collector/network_route_linux.go index 5b7f8ae2..f661e1ab 100644 --- a/collector/network_route_linux.go +++ b/collector/network_route_linux.go @@ -35,13 +35,11 @@ type networkRouteCollector struct { } func init() { - registerCollector("network_route", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewNetworkRouteCollector(logger) - }) + registerCollector("network_route", defaultDisabled, NewNetworkRouteCollector) } // NewNetworkRouteCollector returns a new Collector exposing systemd statistics. -func NewNetworkRouteCollector(logger log.Logger) (Collector, error) { +func NewNetworkRouteCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { const subsystem = "network" routeInfoDesc := prometheus.NewDesc( diff --git a/collector/nfs_linux.go b/collector/nfs_linux.go index a704d79d..21585534 100644 --- a/collector/nfs_linux.go +++ b/collector/nfs_linux.go @@ -44,14 +44,12 @@ type nfsCollector struct { } func init() { - registerCollector("nfs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewNfsCollector(logger) - }) + registerCollector("nfs", defaultEnabled, NewNfsCollector) } // NewNfsCollector returns a new Collector exposing NFS statistics. -func NewNfsCollector(logger log.Logger) (Collector, error) { - fs, err := nfs.NewFS(*procPath) +func NewNfsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := nfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/nfsd_linux.go b/collector/nfsd_linux.go index 54cd8ff9..9a0fb493 100644 --- a/collector/nfsd_linux.go +++ b/collector/nfsd_linux.go @@ -36,9 +36,7 @@ type nfsdCollector struct { } func init() { - registerCollector("nfsd", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewNFSdCollector(logger) - }) + registerCollector("nfsd", defaultEnabled, NewNFSdCollector) } const ( @@ -46,8 +44,8 @@ const ( ) // NewNFSdCollector returns a new Collector exposing /proc/net/rpc/nfsd statistics. -func NewNFSdCollector(logger log.Logger) (Collector, error) { - fs, err := nfs.NewFS(*procPath) +func NewNFSdCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := nfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/ntp.go b/collector/ntp.go index 957cb810..36b7c0c4 100644 --- a/collector/ntp.go +++ b/collector/ntp.go @@ -41,14 +41,11 @@ var ( type ntpCollector struct { stratum, leap, rtt, offset, reftime, rootDelay, rootDispersion, sanity typedDesc logger log.Logger - config NTPConfig + config NodeCollectorConfig } func init() { - registerCollector("ntp", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(NTPConfig) - return NewNtpCollector(cfg, logger) - }) + registerCollector("ntp", defaultDisabled, NewNtpCollector) } type NTPConfig struct { @@ -65,22 +62,22 @@ type NTPConfig struct { // Default definition of "local" is: // - collector.ntp.server address is a loopback address (or collector.ntp.server-is-mine flag is turned on) // - the server is reachable with outgoin IP_TTL = 1 -func NewNtpCollector(config NTPConfig, logger log.Logger) (Collector, error) { - ipaddr := net.ParseIP(*config.Server) - if !*config.ServerIsLocal && (ipaddr == nil || !ipaddr.IsLoopback()) { +func NewNtpCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + ipaddr := net.ParseIP(*config.NTP.Server) + if !*config.NTP.ServerIsLocal && (ipaddr == nil || !ipaddr.IsLoopback()) { return nil, fmt.Errorf("only IP address of local NTP server is valid for --collector.ntp.server") } - if *config.ProtocolVersion < 2 || *config.ProtocolVersion > 4 { - return nil, fmt.Errorf("invalid NTP protocol version %d; must be 2, 3, or 4", *config.ProtocolVersion) + if *config.NTP.ProtocolVersion < 2 || *config.NTP.ProtocolVersion > 4 { + return nil, fmt.Errorf("invalid NTP protocol version %d; must be 2, 3, or 4", *config.NTP.ProtocolVersion) } - if *config.OffsetTolerance < 0 { + if *config.NTP.OffsetTolerance < 0 { return nil, fmt.Errorf("offset tolerance must be non-negative") } - if *config.ServerPort < 1 || *config.ServerPort > 65535 { - return nil, fmt.Errorf("invalid NTP port number %d; must be between 1 and 65535 inclusive", *config.ServerPort) + if *config.NTP.ServerPort < 1 || *config.NTP.ServerPort > 65535 { + return nil, fmt.Errorf("invalid NTP port number %d; must be between 1 and 65535 inclusive", *config.NTP.ServerPort) } level.Warn(logger).Log("msg", "This collector is deprecated and will be removed in the next major version release.") @@ -130,11 +127,11 @@ func NewNtpCollector(config NTPConfig, logger log.Logger) (Collector, error) { } func (c *ntpCollector) Update(ch chan<- prometheus.Metric) error { - resp, err := ntp.QueryWithOptions(*c.config.Server, ntp.QueryOptions{ - Version: *c.config.ProtocolVersion, - TTL: *c.config.IPTTL, + resp, err := ntp.QueryWithOptions(*c.config.NTP.Server, ntp.QueryOptions{ + Version: *c.config.NTP.ProtocolVersion, + TTL: *c.config.NTP.IPTTL, Timeout: time.Second, // default `ntpdate` timeout - Port: *c.config.ServerPort, + Port: *c.config.NTP.ServerPort, }) if err != nil { return fmt.Errorf("couldn't get SNTP reply: %w", err) @@ -159,7 +156,7 @@ func (c *ntpCollector) Update(ch chan<- prometheus.Metric) error { // Here is SNTP packet sanity check that is exposed to move burden of // configuration from node_exporter user to the developer. - maxerr := *c.config.OffsetTolerance + maxerr := *c.config.NTP.OffsetTolerance leapMidnightMutex.Lock() if resp.Leap == ntp.LeapAddSecond || resp.Leap == ntp.LeapDelSecond { // state of leapMidnight is cached as leap flag is dropped right after midnight @@ -171,7 +168,7 @@ func (c *ntpCollector) Update(ch chan<- prometheus.Metric) error { } leapMidnightMutex.Unlock() - if resp.Validate() == nil && resp.RootDistance <= *c.config.MaxDistance && resp.MinError <= maxerr { + if resp.Validate() == nil && resp.RootDistance <= *c.config.NTP.MaxDistance && resp.MinError <= maxerr { ch <- c.sanity.mustNewConstMetric(1) } else { ch <- c.sanity.mustNewConstMetric(0) diff --git a/collector/nvme_linux.go b/collector/nvme_linux.go index fbbd3e0e..506f1d04 100644 --- a/collector/nvme_linux.go +++ b/collector/nvme_linux.go @@ -33,14 +33,12 @@ type nvmeCollector struct { } func init() { - registerCollector("nvme", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewNVMeCollector(logger) - }) + registerCollector("nvme", defaultEnabled, NewNVMeCollector) } // NewNVMeCollector returns a new Collector exposing NVMe stats. -func NewNVMeCollector(logger log.Logger) (Collector, error) { - fs, err := sysfs.NewFS(*sysPath) +func NewNVMeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := sysfs.NewFS(*config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } diff --git a/collector/os_release.go b/collector/os_release.go index 569d9b36..8d09f947 100644 --- a/collector/os_release.go +++ b/collector/os_release.go @@ -65,6 +65,7 @@ type osReleaseCollector struct { osReleaseFilenames []string // all os-release file names to check version float64 versionDesc *prometheus.Desc + config NodeCollectorConfig } type Plist struct { @@ -77,13 +78,11 @@ type Dict struct { } func init() { - registerCollector("os", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewOSCollector(logger) - }) + registerCollector("os", defaultEnabled, NewOSCollector) } // NewOSCollector returns a new Collector exposing os-release information. -func NewOSCollector(logger log.Logger) (Collector, error) { +func NewOSCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &osReleaseCollector{ logger: logger, infoDesc: prometheus.NewDesc( @@ -99,6 +98,7 @@ func NewOSCollector(logger log.Logger) (Collector, error) { "Metric containing the major.minor part of the OS version.", []string{"id", "id_like", "name"}, nil, ), + config: config, }, nil } @@ -176,7 +176,7 @@ func (c *osReleaseCollector) UpdateStruct(path string) error { func (c *osReleaseCollector) Update(ch chan<- prometheus.Metric) error { for i, path := range c.osReleaseFilenames { - err := c.UpdateStruct(*rootfsPath + path) + err := c.UpdateStruct(*c.config.Path.RootfsPath + path) if err == nil { break } diff --git a/collector/paths.go b/collector/paths.go index 82c94187..e14e0204 100644 --- a/collector/paths.go +++ b/collector/paths.go @@ -16,40 +16,36 @@ package collector import ( "path/filepath" "strings" - - "github.com/alecthomas/kingpin/v2" - "github.com/prometheus/procfs" ) -var ( - // The path of the proc filesystem. - procPath = kingpin.Flag("path.procfs", "procfs mountpoint.").Default(procfs.DefaultMountPoint).String() - sysPath = kingpin.Flag("path.sysfs", "sysfs mountpoint.").Default("/sys").String() - rootfsPath = kingpin.Flag("path.rootfs", "rootfs mountpoint.").Default("/").String() - udevDataPath = kingpin.Flag("path.udev.data", "udev data path.").Default("/run/udev/data").String() -) - -func procFilePath(name string) string { - return filepath.Join(*procPath, name) +type PathConfig struct { + ProcPath *string + SysPath *string + RootfsPath *string + UdevDataPath *string } -func sysFilePath(name string) string { - return filepath.Join(*sysPath, name) +func (p *PathConfig) procFilePath(name string) string { + return filepath.Join(*p.ProcPath, name) } -func rootfsFilePath(name string) string { - return filepath.Join(*rootfsPath, name) +func (p *PathConfig) sysFilePath(name string) string { + return filepath.Join(*p.SysPath, name) } -func udevDataFilePath(name string) string { - return filepath.Join(*udevDataPath, name) +func (p *PathConfig) rootfsFilePath(name string) string { + return filepath.Join(*p.RootfsPath, name) } -func rootfsStripPrefix(path string) string { - if *rootfsPath == "/" { +func (p *PathConfig) udevDataFilePath(name string) string { + return filepath.Join(*p.UdevDataPath, name) +} + +func (p *PathConfig) rootfsStripPrefix(path string) string { + if *p.RootfsPath == "/" { return path } - stripped := strings.TrimPrefix(path, *rootfsPath) + stripped := strings.TrimPrefix(path, *p.RootfsPath) if stripped == "" { return "/" } diff --git a/collector/paths_test.go b/collector/paths_test.go index 9426fa4b..2f060f4c 100644 --- a/collector/paths_test.go +++ b/collector/paths_test.go @@ -25,11 +25,11 @@ func TestDefaultProcPath(t *testing.T) { t.Fatal(err) } - if got, want := procFilePath("somefile"), "/proc/somefile"; got != want { + if got, want := c.config.Path.procFilePath("somefile"), "/proc/somefile"; got != want { t.Errorf("Expected: %s, Got: %s", want, got) } - if got, want := procFilePath("some/file"), "/proc/some/file"; got != want { + if got, want := c.config.Path.procFilePath("some/file"), "/proc/some/file"; got != want { t.Errorf("Expected: %s, Got: %s", want, got) } } @@ -39,39 +39,39 @@ func TestCustomProcPath(t *testing.T) { t.Fatal(err) } - if got, want := procFilePath("somefile"), "../some/place/somefile"; got != want { + if got, want := c.config.Path.procFilePath("somefile"), "../some/place/somefile"; got != want { t.Errorf("Expected: %s, Got: %s", want, got) } - if got, want := procFilePath("some/file"), "../some/place/some/file"; got != want { + if got, want := c.config.Path.procFilePath("some/file"), "../some/place/some/file"; got != want { t.Errorf("Expected: %s, Got: %s", want, got) } } -func TestDefaultSysPath(t *testing.T) { +func TestDefault*config.Path.SysPath(t *testing.T) { if _, err := kingpin.CommandLine.Parse([]string{"--path.sysfs", "/sys"}); err != nil { t.Fatal(err) } - if got, want := sysFilePath("somefile"), "/sys/somefile"; got != want { + if got, want := *config.Path.SysPath("somefile"), "/sys/somefile"; got != want { t.Errorf("Expected: %s, Got: %s", want, got) } - if got, want := sysFilePath("some/file"), "/sys/some/file"; got != want { + if got, want := *config.Path.SysPath("some/file"), "/sys/some/file"; got != want { t.Errorf("Expected: %s, Got: %s", want, got) } } -func TestCustomSysPath(t *testing.T) { +func TestCustom*config.Path.SysPath(t *testing.T) { if _, err := kingpin.CommandLine.Parse([]string{"--path.sysfs", "./../some/./place/"}); err != nil { t.Fatal(err) } - if got, want := sysFilePath("somefile"), "../some/place/somefile"; got != want { + if got, want := *config.Path.SysPath("somefile"), "../some/place/somefile"; got != want { t.Errorf("Expected: %s, Got: %s", want, got) } - if got, want := sysFilePath("some/file"), "../some/place/some/file"; got != want { + if got, want := *config.Path.SysPath("some/file"), "../some/place/some/file"; got != want { t.Errorf("Expected: %s, Got: %s", want, got) } } diff --git a/collector/perf_linux.go b/collector/perf_linux.go index b8e00b5a..c7b855ba 100644 --- a/collector/perf_linux.go +++ b/collector/perf_linux.go @@ -34,10 +34,7 @@ const ( ) func init() { - registerCollector(perfSubsystem, defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(PerfConfig) - return NewPerfCollector(cfg, logger) - }) + registerCollector(perfSubsystem, defaultDisabled, NewPerfCollector) } type PerfConfig struct { @@ -303,7 +300,7 @@ func newPerfTracepointCollector( // NewPerfCollector returns a new perf based collector, it creates a profiler // per CPU. -func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { +func NewPerfCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { collector := &perfCollector{ perfHwProfilers: map[int]*perf.HardwareProfiler{}, perfSwProfilers: map[int]*perf.SoftwareProfiler{}, @@ -318,8 +315,8 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { cpus []int err error ) - if config.CPUs != nil && *config.CPUs != "" { - cpus, err = perfCPUFlagToCPUs(*config.CPUs) + if config.Perf.CPUs != nil && *config.Perf.CPUs != "" { + cpus, err = perfCPUFlagToCPUs(*config.Perf.CPUs) if err != nil { return nil, err } @@ -331,8 +328,8 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { } // First configure any tracepoints. - if *config.Tracepoint != nil && len(*config.Tracepoint) > 0 { - tracepointCollector, err := newPerfTracepointCollector(logger, *config.Tracepoint, cpus) + if *config.Perf.Tracepoint != nil && len(*config.Perf.Tracepoint) > 0 { + tracepointCollector, err := newPerfTracepointCollector(logger, *config.Perf.Tracepoint, cpus) if err != nil { return nil, err } @@ -341,27 +338,27 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { // Configure perf profilers hardwareProfilers := perf.AllHardwareProfilers - if *config.HwProfiler != nil && len(*config.HwProfiler) > 0 { + if *config.Perf.HwProfiler != nil && len(*config.Perf.HwProfiler) > 0 { // hardwareProfilers = 0 - for _, hf := range *config.HwProfiler { + for _, hf := range *config.Perf.HwProfiler { if v, ok := perfHardwareProfilerMap[hf]; ok { hardwareProfilers |= v } } } softwareProfilers := perf.AllSoftwareProfilers - if *config.SwProfiler != nil && len(*config.SwProfiler) > 0 { + if *config.Perf.SwProfiler != nil && len(*config.Perf.SwProfiler) > 0 { // softwareProfilers = 0 - for _, sf := range *config.SwProfiler { + for _, sf := range *config.Perf.SwProfiler { if v, ok := perfSoftwareProfilerMap[sf]; ok { softwareProfilers |= v } } } cacheProfilers := perf.L1DataReadHitProfiler | perf.L1DataReadMissProfiler | perf.L1DataWriteHitProfiler | perf.L1InstrReadMissProfiler | perf.InstrTLBReadHitProfiler | perf.InstrTLBReadMissProfiler | perf.LLReadHitProfiler | perf.LLReadMissProfiler | perf.LLWriteHitProfiler | perf.LLWriteMissProfiler | perf.BPUReadHitProfiler | perf.BPUReadMissProfiler - if *config.CaProfilerFlag != nil && len(*config.CaProfilerFlag) > 0 { + if *config.Perf.CaProfilerFlag != nil && len(*config.Perf.CaProfilerFlag) > 0 { cacheProfilers = 0 - for _, cf := range *config.CaProfilerFlag { + for _, cf := range *config.Perf.CaProfilerFlag { if v, ok := perfCacheProfilerMap[cf]; ok { cacheProfilers |= v } @@ -372,7 +369,7 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { for _, cpu := range cpus { // Use -1 to profile all processes on the CPU, see: // man perf_event_open - if !*config.NoHwProfiler { + if !*config.Perf.NoHwProfiler { hwProf, err := perf.NewHardwareProfiler( -1, cpu, @@ -388,7 +385,7 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { collector.hwProfilerCPUMap[&hwProf] = cpu } - if !*config.NoSwProfiler { + if !*config.Perf.NoSwProfiler { swProf, err := perf.NewSoftwareProfiler(-1, cpu, softwareProfilers) if err != nil && !swProf.HasProfilers() { return nil, err @@ -400,7 +397,7 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { collector.swProfilerCPUMap[&swProf] = cpu } - if !*config.NoCaProfiler { + if !*config.Perf.NoCaProfiler { cacheProf, err := perf.NewCacheProfiler( -1, cpu, diff --git a/collector/powersupplyclass.go b/collector/powersupplyclass.go index f9172197..e6483246 100644 --- a/collector/powersupplyclass.go +++ b/collector/powersupplyclass.go @@ -29,21 +29,19 @@ type powerSupplyClassCollector struct { ignoredPattern *regexp.Regexp metricDescs map[string]*prometheus.Desc logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("powersupplyclass", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(PowerSupplyClassConfig) - return NewPowerSupplyClassCollector(cfg, logger) - }) + registerCollector("powersupplyclass", defaultEnabled, NewPowerSupplyClassCollector) } type PowerSupplyClassConfig struct { IgnoredPowerSupplies *string } -func NewPowerSupplyClassCollector(config PowerSupplyClassConfig, logger log.Logger) (Collector, error) { - pattern := regexp.MustCompile(*config.IgnoredPowerSupplies) +func NewPowerSupplyClassCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + pattern := regexp.MustCompile(*config.PowerSupplyClass.IgnoredPowerSupplies) return &powerSupplyClassCollector{ subsystem: "power_supply", ignoredPattern: pattern, diff --git a/collector/powersupplyclass_linux.go b/collector/powersupplyclass_linux.go index 86e81fb6..01a0be25 100644 --- a/collector/powersupplyclass_linux.go +++ b/collector/powersupplyclass_linux.go @@ -28,7 +28,7 @@ import ( ) func (c *powerSupplyClassCollector) Update(ch chan<- prometheus.Metric) error { - powerSupplyClass, err := getPowerSupplyClassInfo(c.ignoredPattern) + powerSupplyClass, err := getPowerSupplyClassInfo(c.config, c.ignoredPattern) if err != nil { if errors.Is(err, os.ErrNotExist) { return ErrNoData @@ -155,8 +155,8 @@ func pushPowerSupplyMetric(ch chan<- prometheus.Metric, subsystem string, name s ch <- prometheus.MustNewConstMetric(fieldDesc, valueType, value, powerSupplyName) } -func getPowerSupplyClassInfo(ignore *regexp.Regexp) (sysfs.PowerSupplyClass, error) { - fs, err := sysfs.NewFS(*sysPath) +func getPowerSupplyClassInfo(config NodeCollectorConfig, ignore *regexp.Regexp) (sysfs.PowerSupplyClass, error) { + fs, err := sysfs.NewFS(*config.Path.SysPath) if err != nil { return nil, err } diff --git a/collector/pressure_linux.go b/collector/pressure_linux.go index 6141fcc1..bd0b5d45 100644 --- a/collector/pressure_linux.go +++ b/collector/pressure_linux.go @@ -45,14 +45,12 @@ type pressureStatsCollector struct { } func init() { - registerCollector("pressure", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewPressureStatsCollector(logger) - }) + registerCollector("pressure", defaultEnabled, NewPressureStatsCollector) } // NewPressureStatsCollector returns a Collector exposing pressure stall information -func NewPressureStatsCollector(logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewPressureStatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/processes_linux.go b/collector/processes_linux.go index f37235e7..2778ebd3 100644 --- a/collector/processes_linux.go +++ b/collector/processes_linux.go @@ -40,17 +40,16 @@ type processCollector struct { pidUsed *prometheus.Desc pidMax *prometheus.Desc logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("processes", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewProcessStatCollector(logger) - }) + registerCollector("processes", defaultEnabled, NewProcessStatCollector) } // NewProcessStatCollector returns a new Collector exposing process data read from the proc filesystem. -func NewProcessStatCollector(logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewProcessStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } @@ -93,7 +92,7 @@ func (c *processCollector) Update(ch chan<- prometheus.Metric) error { } ch <- prometheus.MustNewConstMetric(c.threadAlloc, prometheus.GaugeValue, float64(threads)) - maxThreads, err := readUintFromFile(procFilePath("sys/kernel/threads-max")) + maxThreads, err := readUintFromFile(c.config.Path.procFilePath("sys/kernel/threads-max")) if err != nil { return fmt.Errorf("unable to retrieve limit number of threads: %w", err) } @@ -107,7 +106,7 @@ func (c *processCollector) Update(ch chan<- prometheus.Metric) error { ch <- prometheus.MustNewConstMetric(c.threadsState, prometheus.GaugeValue, float64(threadStates[state]), state) } - pidM, err := readUintFromFile(procFilePath("sys/kernel/pid_max")) + pidM, err := readUintFromFile(c.config.Path.procFilePath("sys/kernel/pid_max")) if err != nil { return fmt.Errorf("unable to retrieve limit number of maximum pids alloved: %w", err) } @@ -150,7 +149,7 @@ func (c *processCollector) getAllocatedThreads() (int, map[string]int32, int, ma } func (c *processCollector) getThreadStates(pid int, pidStat procfs.ProcStat, threadStates map[string]int32) error { - fs, err := procfs.NewFS(procFilePath(path.Join(strconv.Itoa(pid), "task"))) + fs, err := procfs.NewFS(c.config.Path.procFilePath(path.Join(strconv.Itoa(pid), "task"))) if err != nil { if c.isIgnoredError(err) { level.Debug(c.logger).Log("msg", "file not found when retrieving tasks for pid", "pid", pid, "err", err) diff --git a/collector/processes_linux_test.go b/collector/processes_linux_test.go index e2814a01..5eee41c3 100644 --- a/collector/processes_linux_test.go +++ b/collector/processes_linux_test.go @@ -20,6 +20,7 @@ import ( "testing" "github.com/alecthomas/kingpin/v2" + "github.com/docker/cli/cli/config" "github.com/go-kit/log" "github.com/prometheus/procfs" ) @@ -29,7 +30,7 @@ func TestReadProcessStatus(t *testing.T) { t.Fatal(err) } want := 1 - fs, err := procfs.NewFS(*procPath) + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { t.Errorf("failed to open procfs: %v", err) } @@ -45,7 +46,7 @@ func TestReadProcessStatus(t *testing.T) { t.Fatalf("Process states cannot be nil %v:", states) } - maxPid, err := readUintFromFile(procFilePath("sys/kernel/pid_max")) + maxPid, err := readUintFromFile(c.config.Path.procFilePath("sys/kernel/pid_max")) if err != nil { t.Fatalf("Unable to retrieve limit number of maximum pids alloved %v\n", err) } diff --git a/collector/qdisc_linux.go b/collector/qdisc_linux.go index d5cf96f3..d3f55b37 100644 --- a/collector/qdisc_linux.go +++ b/collector/qdisc_linux.go @@ -37,14 +37,11 @@ type qdiscStatCollector struct { overlimits typedDesc qlength typedDesc backlog typedDesc - config QdiscConfig + config NodeCollectorConfig } func init() { - registerCollector("qdisc", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(QdiscConfig) - return NewQdiscStatCollector(cfg, logger) - }) + registerCollector("qdisc", defaultDisabled, NewQdiscStatCollector) } type QdiscConfig struct { @@ -54,8 +51,8 @@ type QdiscConfig struct { } // NewQdiscStatCollector returns a new Collector exposing queuing discipline statistics. -func NewQdiscStatCollector(config QdiscConfig, logger log.Logger) (Collector, error) { - if *config.DeviceExclude != "" && *config.DeviceInclude != "" { +func NewQdiscStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + if *config.Qdisc.DeviceExclude != "" && *config.Qdisc.DeviceInclude != "" { return nil, fmt.Errorf("collector.qdisk.device-include and collector.qdisk.device-exclude are mutaly exclusive") } @@ -96,7 +93,7 @@ func NewQdiscStatCollector(config QdiscConfig, logger log.Logger) (Collector, er []string{"device", "kind"}, nil, ), prometheus.GaugeValue}, logger: logger, - deviceFilter: newDeviceFilter(*config.DeviceExclude, *config.DeviceExclude), + deviceFilter: newDeviceFilter(*config.Qdisc.DeviceExclude, *config.Qdisc.DeviceExclude), config: config, }, nil } @@ -117,7 +114,7 @@ func (c *qdiscStatCollector) Update(ch chan<- prometheus.Metric) error { var msgs []qdisc.QdiscInfo var err error - fixtures := *c.config.Fixtures + fixtures := *c.config.Qdisc.Fixtures if fixtures == "" { msgs, err = qdisc.Get() diff --git a/collector/rapl_linux.go b/collector/rapl_linux.go index 0158285f..bd7df219 100644 --- a/collector/rapl_linux.go +++ b/collector/rapl_linux.go @@ -35,14 +35,11 @@ type raplCollector struct { logger log.Logger joulesMetricDesc *prometheus.Desc - config RaplConfig + config NodeCollectorConfig } func init() { - registerCollector(raplCollectorSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(RaplConfig) - return NewRaplCollector(cfg, logger) - }) + registerCollector(raplCollectorSubsystem, defaultEnabled, NewRaplCollector) } type RaplConfig struct { @@ -50,8 +47,8 @@ type RaplConfig struct { } // NewRaplCollector returns a new Collector exposing RAPL metrics. -func NewRaplCollector(config RaplConfig, logger log.Logger) (Collector, error) { - fs, err := sysfs.NewFS(*sysPath) +func NewRaplCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := sysfs.NewFS(*config.Path.SysPath) if err != nil { return nil, err @@ -100,7 +97,7 @@ func (c *raplCollector) Update(ch chan<- prometheus.Metric) error { joules := float64(microJoules) / 1000000.0 - if *c.config.ZoneLabel { + if *c.config.Rapl.ZoneLabel { ch <- c.joulesMetricWithZoneLabel(rz, joules) } else { ch <- c.joulesMetric(rz, joules) diff --git a/collector/runit.go b/collector/runit.go index 483dbe11..9d3a29da 100644 --- a/collector/runit.go +++ b/collector/runit.go @@ -29,14 +29,11 @@ type runitCollector struct { stateNormal typedDesc stateTimestamp typedDesc logger log.Logger - config RunitConfig + config NodeCollectorConfig } func init() { - registerCollector("runit", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(RunitConfig) - return NewRunitCollector(cfg, logger) - }) + registerCollector("runit", defaultDisabled, NewRunitCollector) } type RunitConfig struct { @@ -44,7 +41,7 @@ type RunitConfig struct { } // NewRunitCollector returns a new Collector exposing runit statistics. -func NewRunitCollector(config RunitConfig, logger log.Logger) (Collector, error) { +func NewRunitCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { var ( subsystem = "service" constLabels = prometheus.Labels{"supervisor": "runit"} @@ -80,7 +77,7 @@ func NewRunitCollector(config RunitConfig, logger log.Logger) (Collector, error) } func (c *runitCollector) Update(ch chan<- prometheus.Metric) error { - services, err := runit.GetServices(*c.config.ServiceDir) + services, err := runit.GetServices(*c.config.Runit.ServiceDir) if err != nil { return err } diff --git a/collector/schedstat_linux.go b/collector/schedstat_linux.go index d2f566bb..cbd8c577 100644 --- a/collector/schedstat_linux.go +++ b/collector/schedstat_linux.go @@ -53,8 +53,8 @@ var ( ) // NewSchedstatCollector returns a new Collector exposing task scheduler statistics -func NewSchedstatCollector(logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewSchedstatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } @@ -68,9 +68,7 @@ type schedstatCollector struct { } func init() { - registerCollector("schedstat", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewSchedstatCollector(logger) - }) + registerCollector("schedstat", defaultEnabled, NewSchedstatCollector) } func (c *schedstatCollector) Update(ch chan<- prometheus.Metric) error { diff --git a/collector/selinux_linux.go b/collector/selinux_linux.go index 970cdb9c..fd00da56 100644 --- a/collector/selinux_linux.go +++ b/collector/selinux_linux.go @@ -30,13 +30,11 @@ type selinuxCollector struct { } func init() { - registerCollector("selinux", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewSelinuxCollector(logger) - }) + registerCollector("selinux", defaultEnabled, NewSelinuxCollector) } // NewSelinuxCollector returns a new Collector exposing SELinux statistics. -func NewSelinuxCollector(logger log.Logger) (Collector, error) { +func NewSelinuxCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { const subsystem = "selinux" return &selinuxCollector{ diff --git a/collector/slabinfo_linux.go b/collector/slabinfo_linux.go index d8f0ed8f..4e07038f 100644 --- a/collector/slabinfo_linux.go +++ b/collector/slabinfo_linux.go @@ -32,13 +32,11 @@ type slabinfoCollector struct { } func init() { - registerCollector("slabinfo", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewSlabinfoCollector(logger) - }) + registerCollector("slabinfo", defaultDisabled, NewSlabinfoCollector) } -func NewSlabinfoCollector(logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewSlabinfoCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/sockstat_linux.go b/collector/sockstat_linux.go index cf2831fa..ca6c8ff6 100644 --- a/collector/sockstat_linux.go +++ b/collector/sockstat_linux.go @@ -36,21 +36,20 @@ var pageSize = os.Getpagesize() type sockStatCollector struct { logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector(sockStatSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewSockStatCollector(logger) - }) + registerCollector(sockStatSubsystem, defaultEnabled, NewSockStatCollector) } // NewSockStatCollector returns a new Collector exposing socket stats. -func NewSockStatCollector(logger log.Logger) (Collector, error) { - return &sockStatCollector{logger}, nil +func NewSockStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + return &sockStatCollector{logger, config}, nil } func (c *sockStatCollector) Update(ch chan<- prometheus.Metric) error { - fs, err := procfs.NewFS(*procPath) + fs, err := procfs.NewFS(*c.config.Path.ProcPath) if err != nil { return fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/softirqs_common.go b/collector/softirqs_common.go index 1bfac97d..10822ddf 100644 --- a/collector/softirqs_common.go +++ b/collector/softirqs_common.go @@ -31,20 +31,18 @@ type softirqsCollector struct { } func init() { - registerCollector("softirqs", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewSoftirqsCollector(logger) - }) + registerCollector("softirqs", defaultDisabled, NewSoftirqsCollector) } // NewSoftirqsCollector returns a new Collector exposing softirq stats. -func NewSoftirqsCollector(logger log.Logger) (Collector, error) { +func NewSoftirqsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { desc := typedDesc{prometheus.NewDesc( namespace+"_softirqs_functions_total", "Softirq counts per CPU.", softirqLabelNames, nil, ), prometheus.CounterValue} - fs, err := procfs.NewFS(*procPath) + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/softnet_linux.go b/collector/softnet_linux.go index 954c4c59..3a242c71 100644 --- a/collector/softnet_linux.go +++ b/collector/softnet_linux.go @@ -42,14 +42,12 @@ const ( ) func init() { - registerCollector("softnet", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewSoftnetCollector(logger) - }) + registerCollector("softnet", defaultEnabled, NewSoftnetCollector) } // NewSoftnetCollector returns a new Collector exposing softnet metrics. -func NewSoftnetCollector(logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewSoftnetCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/stat_linux.go b/collector/stat_linux.go index cf77368b..3830f444 100644 --- a/collector/stat_linux.go +++ b/collector/stat_linux.go @@ -34,14 +34,11 @@ type statCollector struct { procsBlocked *prometheus.Desc softIRQ *prometheus.Desc logger log.Logger - config StatConfig + config NodeCollectorConfig } func init() { - registerCollector("stat", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(StatConfig) - return NewStatCollector(cfg, logger) - }) + registerCollector("stat", defaultEnabled, NewStatCollector) } type StatConfig struct { @@ -49,8 +46,8 @@ type StatConfig struct { } // NewStatCollector returns a new Collector exposing kernel/system statistics. -func NewStatCollector(config StatConfig, logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } @@ -112,7 +109,7 @@ func (c *statCollector) Update(ch chan<- prometheus.Metric) error { ch <- prometheus.MustNewConstMetric(c.procsRunning, prometheus.GaugeValue, float64(stats.ProcessesRunning)) ch <- prometheus.MustNewConstMetric(c.procsBlocked, prometheus.GaugeValue, float64(stats.ProcessesBlocked)) - if *c.config.Softirq { + if *c.config.Stat.Softirq { si := stats.SoftIRQ for _, vec := range []struct { diff --git a/collector/supervisord.go b/collector/supervisord.go index f44f95b6..87110121 100644 --- a/collector/supervisord.go +++ b/collector/supervisord.go @@ -43,10 +43,7 @@ type supervisordCollector struct { } func init() { - registerCollector("supervisord", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(SupervisordConfig) - return NewSupervisordCollector(cfg, logger) - }) + registerCollector("supervisord", defaultDisabled, NewSupervisordCollector) } type SupervisordConfig struct { @@ -54,13 +51,13 @@ type SupervisordConfig struct { } // NewSupervisordCollector returns a new Collector exposing supervisord statistics. -func NewSupervisordCollector(config SupervisordConfig, logger log.Logger) (Collector, error) { +func NewSupervisordCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { var ( subsystem = "supervisord" labelNames = []string{"name", "group"} ) - if u, err := url.Parse(*config.URL); err == nil && u.Scheme == "unix" { + if u, err := url.Parse(*config.Supervisord.URL); err == nil && u.Scheme == "unix" { // Fake the URI scheme as http, since net/http.*Transport.roundTrip will complain // about a non-http(s) transport. xrpc = xmlrpc.NewClient("http://unix/RPC2") @@ -71,7 +68,7 @@ func NewSupervisordCollector(config SupervisordConfig, logger log.Logger) (Colle }, } } else { - xrpc = xmlrpc.NewClient(*config.URL) + xrpc = xmlrpc.NewClient(*config.Supervisord.URL) } level.Warn(logger).Log("msg", "This collector is deprecated and will be removed in the next major version release.") diff --git a/collector/sysctl_linux.go b/collector/sysctl_linux.go index 9954e4aa..dec348ff 100644 --- a/collector/sysctl_linux.go +++ b/collector/sysctl_linux.go @@ -34,10 +34,7 @@ type sysctlCollector struct { } func init() { - registerCollector("sysctl", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(SysctlConfig) - return NewSysctlCollector(cfg, logger) - }) + registerCollector("sysctl", defaultDisabled, NewSysctlCollector) } type SysctlConfig struct { @@ -45,8 +42,8 @@ type SysctlConfig struct { IncludeInfo *[]string } -func NewSysctlCollector(config SysctlConfig, logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewSysctlCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } @@ -56,7 +53,7 @@ func NewSysctlCollector(config SysctlConfig, logger log.Logger) (Collector, erro sysctls: []*sysctl{}, } - for _, include := range *config.Include { + for _, include := range *config.Sysctl.Include { sysctl, err := newSysctl(include, true) if err != nil { return nil, err @@ -64,7 +61,7 @@ func NewSysctlCollector(config SysctlConfig, logger log.Logger) (Collector, erro c.sysctls = append(c.sysctls, sysctl) } - for _, include := range *config.IncludeInfo { + for _, include := range *config.Sysctl.IncludeInfo { sysctl, err := newSysctl(include, false) if err != nil { return nil, err diff --git a/collector/systemd_linux.go b/collector/systemd_linux.go index 3fe79316..9cc00cad 100644 --- a/collector/systemd_linux.go +++ b/collector/systemd_linux.go @@ -64,16 +64,13 @@ type systemdCollector struct { systemdUnitIncludePattern *regexp.Regexp systemdUnitExcludePattern *regexp.Regexp logger log.Logger - config SystemdConfig + config NodeCollectorConfig } var unitStatesName = []string{"active", "activating", "deactivating", "inactive", "failed"} func init() { - registerCollector("systemd", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(SystemdConfig) - return NewSystemdCollector(cfg, logger) - }) + registerCollector("systemd", defaultDisabled, NewSystemdCollector) } type SystemdConfig struct { @@ -88,7 +85,7 @@ type SystemdConfig struct { } // NewSystemdCollector returns a new Collector exposing systemd statistics. -func NewSystemdCollector(config SystemdConfig, logger log.Logger) (Collector, error) { +func NewSystemdCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { const subsystem = "systemd" unitDesc := prometheus.NewDesc( @@ -134,26 +131,26 @@ func NewSystemdCollector(config SystemdConfig, logger log.Logger) (Collector, er prometheus.BuildFQName(namespace, subsystem, "version"), "Detected systemd version", []string{"version"}, nil) - if *config.OldUnitExclude != "" { + if *config.Systemd.OldUnitExclude != "" { if !systemdUnitExcludeSet { level.Warn(logger).Log("msg", "--collector.systemd.unit-blacklist is DEPRECATED and will be removed in 2.0.0, use --collector.systemd.unit-exclude") - *config.UnitExclude = *config.OldUnitExclude + *config.Systemd.UnitExclude = *config.Systemd.OldUnitExclude } else { return nil, errors.New("--collector.systemd.unit-blacklist and --collector.systemd.unit-exclude are mutually exclusive") } } - if *config.OldUnitInclude != "" { + if *config.Systemd.OldUnitInclude != "" { if !systemdUnitIncludeSet { level.Warn(logger).Log("msg", "--collector.systemd.unit-whitelist is DEPRECATED and will be removed in 2.0.0, use --collector.systemd.unit-include") - *config.UnitInclude = *config.OldUnitInclude + *config.Systemd.UnitInclude = *config.Systemd.OldUnitInclude } else { return nil, errors.New("--collector.systemd.unit-whitelist and --collector.systemd.unit-include are mutually exclusive") } } - level.Info(logger).Log("msg", "Parsed flag --collector.systemd.unit-include", "flag", *config.UnitInclude) - systemdUnitIncludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *config.UnitInclude)) - level.Info(logger).Log("msg", "Parsed flag --collector.systemd.unit-exclude", "flag", *config.UnitExclude) - systemdUnitExcludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *config.UnitExclude)) + level.Info(logger).Log("msg", "Parsed flag --collector.systemd.unit-include", "flag", *config.Systemd.UnitInclude) + systemdUnitIncludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *config.Systemd.UnitInclude)) + level.Info(logger).Log("msg", "Parsed flag --collector.systemd.unit-exclude", "flag", *config.Systemd.UnitExclude) + systemdUnitExcludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *config.Systemd.UnitExclude)) return &systemdCollector{ unitDesc: unitDesc, @@ -178,7 +175,7 @@ func NewSystemdCollector(config SystemdConfig, logger log.Logger) (Collector, er // to reduce wait time for responses. func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error { begin := time.Now() - conn, err := newSystemdDbusConn(c.config.Private) + conn, err := newSystemdDbusConn(c.config.Systemd.Private) if err != nil { return fmt.Errorf("couldn't get dbus connection: %w", err) } @@ -221,7 +218,7 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error { level.Debug(c.logger).Log("msg", "collectUnitStatusMetrics took", "duration_seconds", time.Since(begin).Seconds()) }() - if *c.config.EnableStartTimeMetrics { + if *c.config.Systemd.EnableStartTimeMetrics { wg.Add(1) go func() { defer wg.Done() @@ -231,7 +228,7 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error { }() } - if *c.config.EnableTaskMetrics { + if *c.config.Systemd.EnableTaskMetrics { wg.Add(1) go func() { defer wg.Done() @@ -295,7 +292,7 @@ func (c *systemdCollector) collectUnitStatusMetrics(conn *dbus.Conn, ch chan<- p c.unitDesc, prometheus.GaugeValue, isActive, unit.Name, stateName, serviceType) } - if *c.config.EnableRestartsMetrics && strings.HasSuffix(unit.Name, ".service") { + if *c.config.Systemd.EnableRestartsMetrics && strings.HasSuffix(unit.Name, ".service") { // NRestarts wasn't added until systemd 235. restartsCount, err := conn.GetUnitTypePropertyContext(context.TODO(), unit.Name, "Service", "NRestarts") if err != nil { diff --git a/collector/tapestats_linux.go b/collector/tapestats_linux.go index 42af04c6..f16653d7 100644 --- a/collector/tapestats_linux.go +++ b/collector/tapestats_linux.go @@ -44,10 +44,7 @@ type tapestatsCollector struct { } func init() { - registerCollector("tapestats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(TapestatsConfig) - return NewTapestatsCollector(cfg, logger) - }) + registerCollector("tapestats", defaultEnabled, NewTapestatsCollector) } type TapestatsConfig struct { @@ -56,10 +53,10 @@ type TapestatsConfig struct { // NewTapestatsCollector returns a new Collector exposing tape device stats. // Docs from https://www.kernel.org/doc/html/latest/scsi/st.html#sysfs-and-statistics-for-tape-devices -func NewTapestatsCollector(config TapestatsConfig, logger log.Logger) (Collector, error) { +func NewTapestatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { var tapeLabelNames = []string{"device"} - fs, err := sysfs.NewFS(*sysPath) + fs, err := sysfs.NewFS(*config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } @@ -67,7 +64,7 @@ func NewTapestatsCollector(config TapestatsConfig, logger log.Logger) (Collector tapeSubsystem := "tape" return &tapestatsCollector{ - ignoredDevicesPattern: regexp.MustCompile(*config.IgnoredDevices), + ignoredDevicesPattern: regexp.MustCompile(*config.Tapestats.IgnoredDevices), ioNow: prometheus.NewDesc( prometheus.BuildFQName(namespace, tapeSubsystem, "io_now"), diff --git a/collector/tcpstat_linux.go b/collector/tcpstat_linux.go index 120face8..4165d558 100644 --- a/collector/tcpstat_linux.go +++ b/collector/tcpstat_linux.go @@ -61,16 +61,15 @@ const ( type tcpStatCollector struct { desc typedDesc logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("tcpstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewTCPStatCollector(logger) - }) + registerCollector("tcpstat", defaultDisabled, NewTCPStatCollector) } // NewTCPStatCollector returns a new Collector exposing network stats. -func NewTCPStatCollector(logger log.Logger) (Collector, error) { +func NewTCPStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &tcpStatCollector{ desc: typedDesc{prometheus.NewDesc( prometheus.BuildFQName(namespace, "tcp", "connection_states"), @@ -78,6 +77,7 @@ func NewTCPStatCollector(logger log.Logger) (Collector, error) { []string{"state"}, nil, ), prometheus.GaugeValue}, logger: logger, + config: config, }, nil } @@ -137,7 +137,7 @@ func (c *tcpStatCollector) Update(ch chan<- prometheus.Metric) error { } // if enabled ipv6 system - if _, hasIPv6 := os.Stat(procFilePath("net/tcp6")); hasIPv6 == nil { + if _, hasIPv6 := os.Stat(c.config.Path.procFilePath("net/tcp6")); hasIPv6 == nil { tcp6Stats, err := getTCPStats(syscall.AF_INET6) if err != nil { return fmt.Errorf("couldn't get tcp6stats: %w", err) diff --git a/collector/textfile.go b/collector/textfile.go index e9f26981..def07914 100644 --- a/collector/textfile.go +++ b/collector/textfile.go @@ -48,10 +48,7 @@ type textFileCollector struct { } func init() { - registerCollector("textfile", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(TextFileConfig) - return NewTextFileCollector(cfg, logger) - }) + registerCollector("textfile", defaultEnabled, NewTextFileCollector) } type TextFileConfig struct { @@ -60,9 +57,9 @@ type TextFileConfig struct { // NewTextFileCollector returns a new Collector exposing metrics read from files // in the given textfile directory. -func NewTextFileCollector(config TextFileConfig, logger log.Logger) (Collector, error) { +func NewTextFileCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { c := &textFileCollector{ - path: *config.Directory, + path: *config.TextFile.Directory, logger: logger, } return c, nil diff --git a/collector/thermal_darwin.go b/collector/thermal_darwin.go index 6bb4d0f9..d7330970 100644 --- a/collector/thermal_darwin.go +++ b/collector/thermal_darwin.go @@ -63,9 +63,7 @@ type thermCollector struct { const thermal = "thermal" func init() { - registerCollector(thermal, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewThermCollector(logger) - }) + registerCollector(thermal, defaultEnabled, NewThermCollector) } // NewThermCollector returns a new Collector exposing current CPU power levels. diff --git a/collector/thermal_zone_linux.go b/collector/thermal_zone_linux.go index 7f1acbb9..e68ac882 100644 --- a/collector/thermal_zone_linux.go +++ b/collector/thermal_zone_linux.go @@ -39,14 +39,12 @@ type thermalZoneCollector struct { } func init() { - registerCollector("thermal_zone", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewThermalZoneCollector(logger) - }) + registerCollector("thermal_zone", defaultEnabled, NewThermalZoneCollector) } // NewThermalZoneCollector returns a new Collector exposing kernel/system statistics. -func NewThermalZoneCollector(logger log.Logger) (Collector, error) { - fs, err := sysfs.NewFS(*sysPath) +func NewThermalZoneCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := sysfs.NewFS(*config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } diff --git a/collector/time.go b/collector/time.go index be510c30..1d34cbb0 100644 --- a/collector/time.go +++ b/collector/time.go @@ -30,17 +30,16 @@ type timeCollector struct { clocksourcesAvailable typedDesc clocksourceCurrent typedDesc logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector("time", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewTimeCollector(logger) - }) + registerCollector("time", defaultEnabled, NewTimeCollector) } // NewTimeCollector returns a new Collector exposing the current system time in // seconds since epoch. -func NewTimeCollector(logger log.Logger) (Collector, error) { +func NewTimeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { const subsystem = "time" return &timeCollector{ now: typedDesc{prometheus.NewDesc( @@ -64,6 +63,7 @@ func NewTimeCollector(logger log.Logger) (Collector, error) { []string{"device", "clocksource"}, nil, ), prometheus.GaugeValue}, logger: logger, + config: config, }, nil } diff --git a/collector/time_linux.go b/collector/time_linux.go index a67f5a8f..f3c502c1 100644 --- a/collector/time_linux.go +++ b/collector/time_linux.go @@ -26,7 +26,7 @@ import ( ) func (c *timeCollector) update(ch chan<- prometheus.Metric) error { - fs, err := sysfs.NewFS(*sysPath) + fs, err := sysfs.NewFS(*c.config.Path.SysPath) if err != nil { return fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/timex.go b/collector/timex.go index 93d1d01a..5fa6014e 100644 --- a/collector/timex.go +++ b/collector/timex.go @@ -62,13 +62,11 @@ type timexCollector struct { } func init() { - registerCollector("timex", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewTimexCollector(logger) - }) + registerCollector("timex", defaultEnabled, NewTimexCollector) } // NewTimexCollector returns a new Collector exposing adjtime(3) stats. -func NewTimexCollector(logger log.Logger) (Collector, error) { +func NewTimexCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { const subsystem = "timex" return &timexCollector{ diff --git a/collector/udp_queues_linux.go b/collector/udp_queues_linux.go index 3e30e39f..05f1b4ff 100644 --- a/collector/udp_queues_linux.go +++ b/collector/udp_queues_linux.go @@ -36,14 +36,12 @@ type ( ) func init() { - registerCollector("udp_queues", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewUDPqueuesCollector(logger) - }) + registerCollector("udp_queues", defaultEnabled, NewUDPqueuesCollector) } // NewUDPqueuesCollector returns a new Collector exposing network udp queued bytes. -func NewUDPqueuesCollector(logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewUDPqueuesCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/collector/uname.go b/collector/uname.go index 46b1cb51..e03101db 100644 --- a/collector/uname.go +++ b/collector/uname.go @@ -49,13 +49,11 @@ type uname struct { } func init() { - registerCollector("uname", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return newUnameCollector(logger) - }) + registerCollector("uname", defaultEnabled, newUnameCollector) } // NewUnameCollector returns new unameCollector. -func newUnameCollector(logger log.Logger) (Collector, error) { +func newUnameCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &unameCollector{logger}, nil } diff --git a/collector/vmstat_linux.go b/collector/vmstat_linux.go index c9d7ed41..5241425c 100644 --- a/collector/vmstat_linux.go +++ b/collector/vmstat_linux.go @@ -35,13 +35,11 @@ const ( type vmStatCollector struct { fieldPattern *regexp.Regexp logger log.Logger + config NodeCollectorConfig } func init() { - registerCollector(vmStatSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(VmStatConfig) - return NewvmStatCollector(cfg, logger) - }) + registerCollector(vmStatSubsystem, defaultEnabled, NewvmStatCollector) } type VmStatConfig struct { @@ -49,16 +47,17 @@ type VmStatConfig struct { } // NewvmStatCollector returns a new Collector exposing vmstat stats. -func NewvmStatCollector(config VmStatConfig, logger log.Logger) (Collector, error) { - pattern := regexp.MustCompile(*config.Fields) +func NewvmStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + pattern := regexp.MustCompile(*config.VmStat.Fields) return &vmStatCollector{ fieldPattern: pattern, logger: logger, + config: config, }, nil } func (c *vmStatCollector) Update(ch chan<- prometheus.Metric) error { - file, err := os.Open(procFilePath("vmstat")) + file, err := os.Open(c.config.Path.procFilePath("vmstat")) if err != nil { return err } diff --git a/collector/wifi_linux.go b/collector/wifi_linux.go index 5c056618..39ef3df5 100644 --- a/collector/wifi_linux.go +++ b/collector/wifi_linux.go @@ -45,14 +45,11 @@ type wifiCollector struct { stationBeaconLossTotal *prometheus.Desc logger log.Logger - config WifiConfig + config NodeCollectorConfig } func init() { - registerCollector("wifi", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - cfg := config.(WifiConfig) - return NewWifiCollector(cfg, logger) - }) + registerCollector("wifi", defaultDisabled, NewWifiCollector) } type WifiConfig struct { @@ -70,7 +67,7 @@ type wifiStater interface { } // NewWifiCollector returns a new Collector exposing Wifi statistics. -func NewWifiCollector(config WifiConfig, logger log.Logger) (Collector, error) { +func NewWifiCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { const ( subsystem = "wifi" ) @@ -169,7 +166,7 @@ func NewWifiCollector(config WifiConfig, logger log.Logger) (Collector, error) { } func (c *wifiCollector) Update(ch chan<- prometheus.Metric) error { - stat, err := newWifiStater(*c.config.Fixtures) + stat, err := newWifiStater(*c.config.Wifi.Fixtures) if err != nil { // Cannot access wifi metrics, report no error. if errors.Is(err, os.ErrNotExist) { diff --git a/collector/xfs_linux.go b/collector/xfs_linux.go index ed3dea98..819d1598 100644 --- a/collector/xfs_linux.go +++ b/collector/xfs_linux.go @@ -31,14 +31,12 @@ type xfsCollector struct { } func init() { - registerCollector("xfs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewXFSCollector(logger) - }) + registerCollector("xfs", defaultEnabled, NewXFSCollector) } // NewXFSCollector returns a new Collector exposing XFS statistics. -func NewXFSCollector(logger log.Logger) (Collector, error) { - fs, err := xfs.NewFS(*procPath, *sysPath) +func NewXFSCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := xfs.NewFS(*config.Path.ProcPath, *config.Path.SysPath) if err != nil { return nil, fmt.Errorf("failed to open sysfs: %w", err) } diff --git a/collector/zfs.go b/collector/zfs.go index 03bffd11..032a9b63 100644 --- a/collector/zfs.go +++ b/collector/zfs.go @@ -30,9 +30,7 @@ var errZFSNotAvailable = errors.New("ZFS / ZFS statistics are not available") type zfsSysctl string func init() { - registerCollector("zfs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewZFSCollector(logger) - }) + registerCollector("zfs", defaultEnabled, NewZFSCollector) } type zfsCollector struct { @@ -42,10 +40,11 @@ type zfsCollector struct { linuxZpoolStatePath string linuxPathMap map[string]string logger log.Logger + config NodeCollectorConfig } // NewZFSCollector returns a new Collector exposing ZFS statistics. -func NewZFSCollector(logger log.Logger) (Collector, error) { +func NewZFSCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &zfsCollector{ linuxProcpathBase: "spl/kstat/zfs", linuxZpoolIoPath: "/*/io", @@ -65,6 +64,7 @@ func NewZFSCollector(logger log.Logger) (Collector, error) { "zfs_zil": "zil", }, logger: logger, + config: config, }, nil } diff --git a/collector/zfs_freebsd.go b/collector/zfs_freebsd.go index 77760027..3b070225 100644 --- a/collector/zfs_freebsd.go +++ b/collector/zfs_freebsd.go @@ -33,12 +33,10 @@ const ( ) func init() { - registerCollector(zfsCollectorSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewZfsCollector(logger) - }) + registerCollector(zfsCollectorSubsystem, defaultEnabled, NewZfsCollector) } -func NewZfsCollector(logger log.Logger) (Collector, error) { +func NewZfsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { return &zfsCollector{ sysctls: []bsdSysctl{ { diff --git a/collector/zfs_linux.go b/collector/zfs_linux.go index ec195b3d..a7348a56 100644 --- a/collector/zfs_linux.go +++ b/collector/zfs_linux.go @@ -45,12 +45,12 @@ const ( var zfsPoolStatesName = []string{"online", "degraded", "faulted", "offline", "removed", "unavail", "suspended"} func (c *zfsCollector) openProcFile(path string) (*os.File, error) { - file, err := os.Open(procFilePath(path)) + file, err := os.Open(c.config.Path.procFilePath(path)) if err != nil { // file not found error can occur if: // 1. zfs module is not loaded // 2. zfs version does not have the feature with metrics -- ok to ignore - level.Debug(c.logger).Log("msg", "Cannot open file for reading", "path", procFilePath(path)) + level.Debug(c.logger).Log("msg", "Cannot open file for reading", "path", c.config.Path.procFilePath(path)) return nil, errZFSNotAvailable } return file, nil @@ -69,7 +69,7 @@ func (c *zfsCollector) updateZfsStats(subsystem string, ch chan<- prometheus.Met } func (c *zfsCollector) updatePoolStats(ch chan<- prometheus.Metric) error { - zpoolPaths, err := filepath.Glob(procFilePath(filepath.Join(c.linuxProcpathBase, c.linuxZpoolIoPath))) + zpoolPaths, err := filepath.Glob(c.config.Path.procFilePath(filepath.Join(c.linuxProcpathBase, c.linuxZpoolIoPath))) if err != nil { return err } @@ -91,7 +91,7 @@ func (c *zfsCollector) updatePoolStats(ch chan<- prometheus.Metric) error { } } - zpoolObjsetPaths, err := filepath.Glob(procFilePath(filepath.Join(c.linuxProcpathBase, c.linuxZpoolObjsetPath))) + zpoolObjsetPaths, err := filepath.Glob(c.config.Path.procFilePath(filepath.Join(c.linuxProcpathBase, c.linuxZpoolObjsetPath))) if err != nil { return err } @@ -113,7 +113,7 @@ func (c *zfsCollector) updatePoolStats(ch chan<- prometheus.Metric) error { } } - zpoolStatePaths, err := filepath.Glob(procFilePath(filepath.Join(c.linuxProcpathBase, c.linuxZpoolStatePath))) + zpoolStatePaths, err := filepath.Glob(c.config.Path.procFilePath(filepath.Join(c.linuxProcpathBase, c.linuxZpoolStatePath))) if err != nil { return err } diff --git a/collector/zfs_solaris.go b/collector/zfs_solaris.go index d7c2e640..b94f04dc 100644 --- a/collector/zfs_solaris.go +++ b/collector/zfs_solaris.go @@ -62,9 +62,7 @@ const ( ) func init() { - registerCollector(zfsCollectorSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { - return NewZfsCollector(logger) - }) + registerCollector(zfsCollectorSubsystem, defaultEnabled, NewZfsCollector) } func NewZfsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { diff --git a/collector/zoneinfo_linux.go b/collector/zoneinfo_linux.go index 4e9045aa..eefc1095 100644 --- a/collector/zoneinfo_linux.go +++ b/collector/zoneinfo_linux.go @@ -33,14 +33,12 @@ type zoneinfoCollector struct { } func init() { - registerCollector(zoneinfoSubsystem, defaultDisabled, func(config any, logger log.Logger) (Collector, error) { - return NewZoneinfoCollector(logger) - }) + registerCollector(zoneinfoSubsystem, defaultDisabled, NewZoneinfoCollector) } // NewZoneinfoCollector returns a new Collector exposing zone stats. -func NewZoneinfoCollector(logger log.Logger) (Collector, error) { - fs, err := procfs.NewFS(*procPath) +func NewZoneinfoCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { + fs, err := procfs.NewFS(*config.Path.ProcPath) if err != nil { return nil, fmt.Errorf("failed to open procfs: %w", err) } diff --git a/kingpinconfig/flags.go b/kingpinconfig/flags.go index 3585c893..3971ad78 100644 --- a/kingpinconfig/flags.go +++ b/kingpinconfig/flags.go @@ -16,6 +16,7 @@ package kingpinconfig import ( "github.com/alecthomas/kingpin/v2" "github.com/prometheus/node_exporter/collector" + "github.com/prometheus/procfs" ) func AddFlags(a *kingpin.Application) collector.NodeCollectorConfig { @@ -108,6 +109,11 @@ func AddFlags(a *kingpin.Application) collector.NodeCollectorConfig { config.NTP.MaxDistance = a.Flag("collector.ntp.max-distance", "Max accumulated distance to the root").Default("3.46608s").Duration() config.NTP.OffsetTolerance = a.Flag("collector.ntp.local-offset-tolerance", "Offset between local clock and local ntpd time to tolerate").Default("1ms").Duration() + *config.Path.ProcPath = kingpin.Flag("path.procfs", "procfs mountpoint.").Default(procfs.DefaultMountPoint).String() + config.Path.*config.Path.SysPath = kingpin.Flag("path.sysfs", "sysfs mountpoint.").Default("/sys").String() + config.Path.RootfsPath = kingpin.Flag("path.rootfs", "rootfs mountpoint.").Default("/").String() + config.Path.UdevDataPath = kingpin.Flag("path.udev.data", "udev data path.").Default("/run/udev/data").String() + config.Perf.CPUs = a.Flag("collector.perf.cpus", "List of CPUs from which perf metrics should be collected").Default("").String() config.Perf.Tracepoint = a.Flag("collector.perf.tracepoint", "perf tracepoint that should be collected").Strings() config.Perf.NoHwProfiler = a.Flag("collector.perf.disable-hardware-profilers", "disable perf hardware profilers").Default("false").Bool()