Refactor collectors - part 3

pull/2813/head
Marc Tuduri 2023-09-26 16:41:39 +02:00
parent ed7a10dde2
commit 96f13a2e27
No known key found for this signature in database
GPG Key ID: 761973D5AE312AF4
107 changed files with 495 additions and 655 deletions

View File

@ -32,10 +32,7 @@ type arpCollector struct {
} }
func init() { func init() {
registerCollector("arp", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("arp", defaultEnabled, NewARPCollector)
arpConfig := config.(ArpConfig)
return NewARPCollector(arpConfig, logger)
})
} }
type ArpConfig struct { type ArpConfig struct {
@ -44,15 +41,15 @@ type ArpConfig struct {
} }
// NewARPCollector returns a new Collector exposing ARP stats. // NewARPCollector returns a new Collector exposing ARP stats.
func NewARPCollector(config ArpConfig, logger log.Logger) (Collector, error) { func NewARPCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }
return &arpCollector{ return &arpCollector{
fs: fs, fs: fs,
deviceFilter: newDeviceFilter(*config.DeviceExclude, *config.DeviceInclude), deviceFilter: newDeviceFilter(*config.Arp.DeviceExclude, *config.Arp.DeviceInclude),
entries: prometheus.NewDesc( entries: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "arp", "entries"), prometheus.BuildFQName(namespace, "arp", "entries"),
"ARP entries by device", "ARP entries by device",

View File

@ -25,17 +25,15 @@ import (
) )
func init() { func init() {
registerCollector("bcache", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("bcache", defaultEnabled, NewBcacheCollector)
bcacheConfig := config.(BcacheConfig)
return NewBcacheCollector(bcacheConfig, logger)
})
} }
// A bcacheCollector is a Collector which gathers metrics from Linux bcache. // A bcacheCollector is a Collector which gathers metrics from Linux bcache.
type bcacheCollector struct { type bcacheCollector struct {
fs bcache.FS fs bcache.FS
logger log.Logger logger log.Logger
config BcacheConfig config NodeCollectorConfig
} }
type BcacheConfig struct { type BcacheConfig struct {
@ -44,8 +42,8 @@ type BcacheConfig struct {
// NewBcacheCollector returns a newly allocated bcacheCollector. // NewBcacheCollector returns a newly allocated bcacheCollector.
// It exposes a number of Linux bcache statistics. // It exposes a number of Linux bcache statistics.
func NewBcacheCollector(config BcacheConfig, logger log.Logger) (Collector, error) { func NewBcacheCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := bcache.NewFS(*sysPath) fs, err := bcache.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) 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 { func (c *bcacheCollector) Update(ch chan<- prometheus.Metric) error {
var stats []*bcache.Stats var stats []*bcache.Stats
var err error var err error
if *c.config.PriorityStats { if *c.config.Bcache.PriorityStats {
stats, err = c.fs.Stats() stats, err = c.fs.Stats()
} else { } else {
stats, err = c.fs.StatsWithoutPriority() stats, err = c.fs.StatsWithoutPriority()
@ -321,7 +319,7 @@ func (c *bcacheCollector) updateBcacheStats(ch chan<- prometheus.Metric, s *bcac
extraLabelValue: cache.Name, extraLabelValue: cache.Name,
}, },
} }
if *c.config.PriorityStats { if *c.config.Bcache.PriorityStats {
// metrics in /sys/fs/bcache/<uuid>/<cache>/priority_stats // metrics in /sys/fs/bcache/<uuid>/<cache>/priority_stats
priorityStatsMetrics := []bcacheMetric{ priorityStatsMetrics := []bcacheMetric{
{ {

View File

@ -31,17 +31,16 @@ import (
type bondingCollector struct { type bondingCollector struct {
slaves, active typedDesc slaves, active typedDesc
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("bonding", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("bonding", defaultEnabled, NewBondingCollector)
return NewBondingCollector(logger)
})
} }
// NewBondingCollector returns a newly allocated bondingCollector. // NewBondingCollector returns a newly allocated bondingCollector.
// It exposes the number of configured and active slave of linux bonding interfaces. // 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{ return &bondingCollector{
slaves: typedDesc{prometheus.NewDesc( slaves: typedDesc{prometheus.NewDesc(
prometheus.BuildFQName(namespace, "bonding", "slaves"), prometheus.BuildFQName(namespace, "bonding", "slaves"),
@ -54,12 +53,13 @@ func NewBondingCollector(logger log.Logger) (Collector, error) {
[]string{"master"}, nil, []string{"master"}, nil,
), prometheus.GaugeValue}, ), prometheus.GaugeValue},
logger: logger, logger: logger,
config: config,
}, nil }, nil
} }
// Update reads and exposes bonding states, implements Collector interface. Caution: This works only on linux. // Update reads and exposes bonding states, implements Collector interface. Caution: This works only on linux.
func (c *bondingCollector) Update(ch chan<- prometheus.Metric) error { func (c *bondingCollector) Update(ch chan<- prometheus.Metric) error {
statusfile := sysFilePath("class/net") statusfile := c.config.Path.sysFilePath("class/net")
bondingStats, err := readBondingStats(statusfile) bondingStats, err := readBondingStats(statusfile)
if err != nil { if err != nil {
if errors.Is(err, os.ErrNotExist) { if errors.Is(err, os.ErrNotExist) {

View File

@ -28,13 +28,11 @@ type bootTimeCollector struct {
} }
func init() { func init() {
registerCollector("boottime", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("boottime", defaultEnabled, newBootTimeCollector(logger))
return newBootTimeCollector(logger)
})
} }
// newBootTimeCollector returns a new Collector exposing system boot time on BSD systems. // 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{ return &bootTimeCollector{
logger: logger, logger: logger,
}, nil }, nil

View File

@ -28,12 +28,10 @@ type bootTimeCollector struct {
} }
func init() { func init() {
registerCollector("boottime", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("boottime", defaultEnabled, newBootTimeCollector)
return newBootTimeCollector(logger)
})
} }
func newBootTimeCollector(logger log.Logger) (Collector, error) { func newBootTimeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &bootTimeCollector{ return &bootTimeCollector{
boottime: typedDesc{ boottime: typedDesc{
prometheus.NewDesc( prometheus.NewDesc(

View File

@ -33,17 +33,16 @@ import (
type btrfsCollector struct { type btrfsCollector struct {
fs btrfs.FS fs btrfs.FS
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("btrfs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("btrfs", defaultEnabled, NewBtrfsCollector)
return NewBtrfsCollector(logger)
})
} }
// NewBtrfsCollector returns a new Collector exposing Btrfs statistics. // NewBtrfsCollector returns a new Collector exposing Btrfs statistics.
func NewBtrfsCollector(logger log.Logger) (Collector, error) { func NewBtrfsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := btrfs.NewFS(*sysPath) fs, err := btrfs.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) return nil, fmt.Errorf("failed to open sysfs: %w", err)
} }
@ -51,6 +50,7 @@ func NewBtrfsCollector(logger log.Logger) (Collector, error) {
return &btrfsCollector{ return &btrfsCollector{
fs: fs, fs: fs,
logger: logger, logger: logger,
config: config,
}, nil }, nil
} }
@ -105,7 +105,7 @@ type btrfsIoctlFsStats struct {
func (c *btrfsCollector) getIoctlStats() (map[string]*btrfsIoctlFsStats, error) { func (c *btrfsCollector) getIoctlStats() (map[string]*btrfsIoctlFsStats, error) {
// Instead of introducing more ioctl calls to scan for all btrfs // Instead of introducing more ioctl calls to scan for all btrfs
// filesystems re-use our mount point utils to find known mounts // 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 { if err != nil {
return nil, err return nil, err
} }
@ -125,7 +125,7 @@ func (c *btrfsCollector) getIoctlStats() (map[string]*btrfsIoctlFsStats, error)
continue continue
} }
mountPath := rootfsFilePath(mount.mountPoint) mountPath := c.config.Path.rootfsFilePath(mount.mountPoint)
fs, err := dennwc.Open(mountPath, true) fs, err := dennwc.Open(mountPath, true)
if err != nil { if err != nil {

View File

@ -37,19 +37,17 @@ type buddyinfoCollector struct {
} }
func init() { func init() {
registerCollector("buddyinfo", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("buddyinfo", defaultDisabled, NewBuddyinfoCollector)
return NewBuddyinfoCollector(logger)
})
} }
// NewBuddyinfoCollector returns a new Collector exposing buddyinfo stats. // 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( desc := prometheus.NewDesc(
prometheus.BuildFQName(namespace, buddyInfoSubsystem, "blocks"), prometheus.BuildFQName(namespace, buddyInfoSubsystem, "blocks"),
"Count of free blocks according to size.", "Count of free blocks according to size.",
[]string{"node", "zone", "size"}, nil, []string{"node", "zone", "size"}, nil,
) )
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -34,14 +34,12 @@ type cgroupSummaryCollector struct {
} }
func init() { func init() {
registerCollector(cgroupsCollectorSubsystem, defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector(cgroupsCollectorSubsystem, defaultDisabled, NewCgroupSummaryCollector)
return NewCgroupSummaryCollector(logger)
})
} }
// NewCgroupSummaryCollector returns a new Collector exposing a summary of cgroups. // NewCgroupSummaryCollector returns a new Collector exposing a summary of cgroups.
func NewCgroupSummaryCollector(logger log.Logger) (Collector, error) { func NewCgroupSummaryCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -50,14 +50,14 @@ const (
) )
var ( 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{} initiatedCollectorsMtx = sync.Mutex{}
initiatedCollectors = make(map[string]Collector) initiatedCollectors = make(map[string]Collector)
collectorState = make(map[string]*bool) collectorState = make(map[string]*bool)
forcedCollectors = map[string]bool{} // collectors which have been explicitly enabled or disabled 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 var helpDefaultState string
if isDefaultEnabled { if isDefaultEnabled {
helpDefaultState = "enabled" helpDefaultState = "enabled"

View File

@ -29,6 +29,7 @@ type NodeCollectorConfig struct {
NetDev NetDevConfig NetDev NetDevConfig
NetStat NetStatConfig NetStat NetStatConfig
NTP NTPConfig NTP NTPConfig
Path PathConfig
Perf PerfConfig Perf PerfConfig
PowerSupplyClass PowerSupplyClassConfig PowerSupplyClass PowerSupplyClassConfig
Qdisc QdiscConfig Qdisc QdiscConfig

View File

@ -39,6 +39,7 @@ type conntrackCollector struct {
earlyDrop *prometheus.Desc earlyDrop *prometheus.Desc
searchRestart *prometheus.Desc searchRestart *prometheus.Desc
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
type conntrackStatistics struct { type conntrackStatistics struct {
@ -53,13 +54,11 @@ type conntrackStatistics struct {
} }
func init() { func init() {
registerCollector("conntrack", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("conntrack", defaultEnabled, NewConntrackCollector)
return NewConntrackCollector(logger)
})
} }
// NewConntrackCollector returns a new Collector exposing conntrack stats. // 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{ return &conntrackCollector{
current: prometheus.NewDesc( current: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "", "nf_conntrack_entries"), prometheus.BuildFQName(namespace, "", "nf_conntrack_entries"),
@ -112,25 +111,26 @@ func NewConntrackCollector(logger log.Logger) (Collector, error) {
nil, nil, nil, nil,
), ),
logger: logger, logger: logger,
config: config,
}, nil }, nil
} }
func (c *conntrackCollector) Update(ch chan<- prometheus.Metric) error { 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 { if err != nil {
return c.handleErr(err) return c.handleErr(err)
} }
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.current, prometheus.GaugeValue, float64(value)) 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 { if err != nil {
return c.handleErr(err) return c.handleErr(err)
} }
ch <- prometheus.MustNewConstMetric( ch <- prometheus.MustNewConstMetric(
c.limit, prometheus.GaugeValue, float64(value)) c.limit, prometheus.GaugeValue, float64(value))
conntrackStats, err := getConntrackStatistics() conntrackStats, err := getConntrackStatistics(c.config)
if err != nil { if err != nil {
return c.handleErr(err) 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) return fmt.Errorf("failed to retrieve conntrack stats: %w", err)
} }
func getConntrackStatistics() (*conntrackStatistics, error) { func getConntrackStatistics(config NodeCollectorConfig) (*conntrackStatistics, error) {
c := conntrackStatistics{} c := conntrackStatistics{}
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -57,13 +57,11 @@ type statCollector struct {
} }
func init() { func init() {
registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("cpu", defaultEnabled, NewCPUCollector)
return NewCPUCollector(logger)
})
} }
// NewCPUCollector returns a new Collector exposing CPU stats. // 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{ return &statCollector{
cpu: nodeCPUSecondsDesc, cpu: nodeCPUSecondsDesc,
logger: logger, logger: logger,

View File

@ -82,13 +82,11 @@ type statCollector struct {
} }
func init() { func init() {
registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("cpu", defaultEnabled, NewStatCollector)
return NewStatCollector(logger)
})
} }
// NewStatCollector returns a new Collector exposing CPU stats. // 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{ return &statCollector{
cpu: nodeCPUSecondsDesc, cpu: nodeCPUSecondsDesc,
logger: logger, logger: logger,

View File

@ -89,13 +89,11 @@ type statCollector struct {
} }
func init() { func init() {
registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("cpu", defaultEnabled, NewStatCollector)
return NewStatCollector(logger)
})
} }
// NewStatCollector returns a new Collector exposing CPU stats. // 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{ return &statCollector{
cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue},
temp: typedDesc{prometheus.NewDesc( temp: typedDesc{prometheus.NewDesc(

View File

@ -51,7 +51,7 @@ type cpuCollector struct {
cpuFlagsIncludeRegexp *regexp.Regexp cpuFlagsIncludeRegexp *regexp.Regexp
cpuBugsIncludeRegexp *regexp.Regexp cpuBugsIncludeRegexp *regexp.Regexp
config CPUConfig config NodeCollectorConfig
} }
// Idle jump back limit in seconds. // Idle jump back limit in seconds.
@ -69,20 +69,17 @@ type CPUConfig struct {
} }
func init() { func init() {
registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("cpu", defaultEnabled, NewCPUCollector)
cpuConfig := config.(CPUConfig)
return NewCPUCollector(cpuConfig, logger)
})
} }
// NewCPUCollector returns a new Collector exposing kernel/system statistics. // NewCPUCollector returns a new Collector exposing kernel/system statistics.
func NewCPUCollector(config CPUConfig, logger log.Logger) (Collector, error) { func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) 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 { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) 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), cpuStats: make(map[int64]procfs.CPUStat),
config: config, 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 { 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) 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 { func (c *cpuCollector) compileIncludeFlags(flagsIncludeFlag, bugsIncludeFlag *string) error {
if (*flagsIncludeFlag != "" || *bugsIncludeFlag != "") && !*c.config.EnableCPUInfo { if (*flagsIncludeFlag != "" || *bugsIncludeFlag != "") && !*c.config.CPU.EnableCPUInfo {
*c.config.EnableCPUInfo = true *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") 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/. // Update implements Collector and exposes cpu related metrics from /proc/stat and /sys/.../cpu/.
func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error { 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 { if err := c.updateInfo(ch); err != nil {
return err return err
} }
@ -180,7 +177,7 @@ func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error {
if c.isolatedCpus != nil { if c.isolatedCpus != nil {
c.updateIsolated(ch) c.updateIsolated(ch)
} }
return c.updateThermalThrottle(ch) return c.updateThermalThrottle(c.config, ch)
} }
// updateInfo reads /proc/cpuinfo // 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. // updateThermalThrottle reads /sys/devices/system/cpu/cpu* and expose thermal throttle statistics.
func (c *cpuCollector) updateThermalThrottle(ch chan<- prometheus.Metric) error { func (c *cpuCollector) updateThermalThrottle(config NodeCollectorConfig, ch chan<- prometheus.Metric) error {
cpus, err := filepath.Glob(sysFilePath("devices/system/cpu/cpu[0-9]*")) cpus, err := filepath.Glob(config.Path.sysFilePath("devices/system/cpu/cpu[0-9]*"))
if err != nil { if err != nil {
return err 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.SoftIRQ, cpuNum, "softirq")
ch <- prometheus.MustNewConstMetric(c.cpu, prometheus.CounterValue, cpuStat.Steal, cpuNum, "steal") 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. // 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.Guest, cpuNum, "user")
ch <- prometheus.MustNewConstMetric(c.cpuGuest, prometheus.CounterValue, cpuStat.GuestNice, cpuNum, "nice") ch <- prometheus.MustNewConstMetric(c.cpuGuest, prometheus.CounterValue, cpuStat.GuestNice, cpuNum, "nice")

View File

@ -218,13 +218,11 @@ type statCollector struct {
} }
func init() { func init() {
registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("cpu", defaultEnabled, NewStatCollector)
return NewStatCollector(logger)
})
} }
// NewStatCollector returns a new Collector exposing CPU stats. // 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{ return &statCollector{
cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue},
temp: typedDesc{prometheus.NewDesc( temp: typedDesc{prometheus.NewDesc(

View File

@ -49,9 +49,7 @@ type cpuCollector struct {
} }
func init() { func init() {
registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("cpu", defaultEnabled, NewCPUCollector)
return NewCPUCollector(logger)
})
} }
func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {

View File

@ -33,12 +33,10 @@ type cpuCollector struct {
} }
func init() { func init() {
registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("cpu", defaultEnabled, NewCpuCollector)
return NewCPUCollector(logger)
})
} }
func NewCpuCollector(logger log.Logger) (Collector, error) { func NewCpuCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &cpuCollector{ return &cpuCollector{
cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue},
logger: logger, logger: logger,

View File

@ -34,20 +34,20 @@ var (
) )
) )
type cpuVulnerabilitiesCollector struct{} type cpuVulnerabilitiesCollector struct {
config NodeCollectorConfig
func init() {
registerCollector(cpuVulerabilitiesCollector, defaultDisabled, func(config any, logger log.Logger) (Collector, error) {
return NewVulnerabilitySysfsCollector(logger)
})
} }
func NewVulnerabilitySysfsCollector(logger log.Logger) (Collector, error) { func init() {
return &cpuVulnerabilitiesCollector{}, nil 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 { 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 { if err != nil {
return fmt.Errorf("failed to open sysfs: %w", err) return fmt.Errorf("failed to open sysfs: %w", err)
} }

View File

@ -31,14 +31,12 @@ type cpuFreqCollector struct {
} }
func init() { func init() {
registerCollector("cpufreq", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("cpufreq", defaultEnabled, NewCPUFreqCollector)
return NewCPUFreqCollector(logger)
})
} }
// NewCPUFreqCollector returns a new Collector exposing kernel/system statistics. // NewCPUFreqCollector returns a new Collector exposing kernel/system statistics.
func NewCPUFreqCollector(logger log.Logger) (Collector, error) { func NewCPUFreqCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := sysfs.NewFS(*sysPath) fs, err := sysfs.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) return nil, fmt.Errorf("failed to open sysfs: %w", err)
} }

View File

@ -33,12 +33,10 @@ type cpuFreqCollector struct {
} }
func init() { func init() {
registerCollector("cpufreq", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("cpufreq", defaultEnabled, NewCPUFreqCollector)
return NewCPUFreqCollector(logger)
})
} }
func NewCpuFreqCollector(logger log.Logger) (Collector, error) { func NewCpuFreqCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &cpuFreqCollector{ return &cpuFreqCollector{
logger: logger, logger: logger,
}, nil }, nil

View File

@ -102,13 +102,11 @@ type devstatCollector struct {
} }
func init() { func init() {
registerCollector("devstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("devstat", defaultDisabled,NewDevstatCollector)
return NewDevstatCollector(logger)
})
} }
// NewDevstatCollector returns a new Collector exposing Device stats. // 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{ return &devstatCollector{
bytesDesc: prometheus.NewDesc( bytesDesc: prometheus.NewDesc(
prometheus.BuildFQName(namespace, devstatSubsystem, "bytes_total"), prometheus.BuildFQName(namespace, devstatSubsystem, "bytes_total"),

View File

@ -47,9 +47,7 @@ type devstatCollector struct {
} }
func init() { func init() {
registerCollector("devstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("devstat", defaultDisabled, NewDevstatCollector)
return NewDevstatCollector(logger)
})
} }
// NewDevstatCollector returns a new Collector exposing Device stats. // NewDevstatCollector returns a new Collector exposing Device stats.

View File

@ -39,17 +39,14 @@ type diskstatsCollector struct {
} }
func init() { func init() {
registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector)
cfg := config.(DiskstatsDeviceFilterConfig)
return NewDiskstatsCollector(cfg, logger)
})
} }
// NewDiskstatsCollector returns a new Collector exposing disk device stats. // 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"} var diskLabelNames = []string{"device"}
deviceFilter, err := newDiskstatsDeviceFilter(config, logger) deviceFilter, err := newDiskstatsDeviceFilter(config.DiskstatsDeviceFilter, logger)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse device filter flags: %w", err) return nil, fmt.Errorf("failed to parse device filter flags: %w", err)
} }

View File

@ -86,26 +86,24 @@ type diskstatsCollector struct {
deviceMapperInfoDesc typedFactorDesc deviceMapperInfoDesc typedFactorDesc
ataDescs map[string]typedFactorDesc ataDescs map[string]typedFactorDesc
logger log.Logger logger log.Logger
getUdevDeviceProperties func(uint32, uint32) (udevInfo, error) getUdevDeviceProperties func(NodeCollectorConfig, uint32, uint32) (udevInfo, error)
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector)
cfg := config.(DiskstatsDeviceFilterConfig)
return NewDiskstatsCollector(cfg, logger)
})
} }
// NewDiskstatsCollector returns a new Collector exposing disk device stats. // NewDiskstatsCollector returns a new Collector exposing disk device stats.
// Docs from https://www.kernel.org/doc/Documentation/iostats.txt // 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"} var diskLabelNames = []string{"device"}
fs, err := blockdevice.NewFS(*procPath, *sysPath) fs, err := blockdevice.NewFS(*config.Path.ProcPath, *config.Path.SysPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) return nil, fmt.Errorf("failed to open sysfs: %w", err)
} }
deviceFilter, err := newDiskstatsDeviceFilter(config, logger) deviceFilter, err := newDiskstatsDeviceFilter(config.DiskstatsDeviceFilter, logger)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse device filter flags: %w", err) 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, logger: logger,
config: config,
} }
// Only enable getting device properties from udev if the directory is readable. // Only enable getting device properties from udev if the directory is readable.
if stat, err := os.Stat(*udevDataPath); err != nil || !stat.IsDir() { 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", *udevDataPath) level.Error(logger).Log("msg", "Failed to open directory, disabling udev device properties", "path", *config.Path.UdevDataPath)
} else { } else {
collector.getUdevDeviceProperties = getUdevDeviceProperties collector.getUdevDeviceProperties = getUdevDeviceProperties
} }
@ -285,7 +284,7 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error {
continue continue
} }
info, err := getUdevDeviceProperties(stats.MajorNumber, stats.MinorNumber) info, err := getUdevDeviceProperties(c.config, stats.MajorNumber, stats.MinorNumber)
if err != nil { if err != nil {
level.Debug(c.logger).Log("msg", "Failed to parse udev info", "err", err) 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 return nil
} }
func getUdevDeviceProperties(major, minor uint32) (udevInfo, error) { func getUdevDeviceProperties(config NodeCollectorConfig, major, minor uint32) (udevInfo, error) {
filename := udevDataFilePath(fmt.Sprintf("b%d:%d", major, minor)) filename := config.Path.udevDataFilePath(fmt.Sprintf("b%d:%d", major, minor))
data, err := os.Open(filename) data, err := os.Open(filename)
if err != nil { if err != nil {

View File

@ -45,15 +45,12 @@ type diskstatsCollector struct {
} }
func init() { func init() {
registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector)
cfg := config.(DiskstatsDeviceFilterConfig)
return NewDiskstatsCollector(cfg, logger)
})
} }
// NewDiskstatsCollector returns a new Collector exposing disk device stats. // 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) {
deviceFilter, err := newDiskstatsDeviceFilter(config, logger) deviceFilter, err := newDiskstatsDeviceFilter(config.DiskstatsDeviceFilter, logger)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse device filter flags: %w", err) return nil, fmt.Errorf("failed to parse device filter flags: %w", err)
} }

View File

@ -56,15 +56,12 @@ type diskstatsCollector struct {
} }
func init() { func init() {
registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector)
cfg := config.(DiskstatsDeviceFilterConfig)
return NewDiskstatsCollector(cfg, logger)
})
} }
// NewDiskstatsCollector returns a new Collector exposing disk device stats. // 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) {
deviceFilter, err := newDiskstatsDeviceFilter(config, logger) deviceFilter, err := newDiskstatsDeviceFilter(config.DiskstatsDeviceFilter, logger)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to parse device filter flags: %w", err) return nil, fmt.Errorf("failed to parse device filter flags: %w", err)
} }

View File

@ -34,14 +34,12 @@ type dmiCollector struct {
} }
func init() { func init() {
registerCollector("dmi", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("dmi", defaultEnabled, NewDMICollector)
return NewDMICollector(logger)
})
} }
// NewDMICollector returns a new Collector exposing DMI information. // NewDMICollector returns a new Collector exposing DMI information.
func NewDMICollector(logger log.Logger) (Collector, error) { func NewDMICollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := sysfs.NewFS(*sysPath) fs, err := sysfs.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) return nil, fmt.Errorf("failed to open sysfs: %w", err)
} }

View File

@ -80,15 +80,14 @@ type drbdCollector struct {
stringPair map[string]drbdStringPairMetric stringPair map[string]drbdStringPairMetric
connected *prometheus.Desc connected *prometheus.Desc
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("drbd", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("drbd", defaultDisabled, newDRBDCollector)
return newDRBDCollector(logger)
})
} }
func newDRBDCollector(logger log.Logger) (Collector, error) { func newDRBDCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &drbdCollector{ return &drbdCollector{
numerical: map[string]drbdNumericalMetric{ numerical: map[string]drbdNumericalMetric{
"ns": newDRBDNumericalMetric( "ns": newDRBDNumericalMetric(
@ -185,11 +184,12 @@ func newDRBDCollector(logger log.Logger) (Collector, error) {
nil, nil,
), ),
logger: logger, logger: logger,
config: config,
}, nil }, nil
} }
func (c *drbdCollector) Update(ch chan<- prometheus.Metric) error { func (c *drbdCollector) Update(ch chan<- prometheus.Metric) error {
statsFile := procFilePath("drbd") statsFile := c.config.Path.procFilePath("drbd")
file, err := os.Open(statsFile) file, err := os.Open(statsFile)
if err != nil { if err != nil {
if errors.Is(err, os.ErrNotExist) { if errors.Is(err, os.ErrNotExist) {

View File

@ -42,14 +42,12 @@ type drmCollector struct {
} }
func init() { func init() {
registerCollector("drm", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("drm", defaultDisabled, NewDrmCollector)
return NewDrmCollector(logger)
})
} }
// NewDrmCollector returns a new Collector exposing /sys/class/drm/card?/device stats. // NewDrmCollector returns a new Collector exposing /sys/class/drm/card?/device stats.
func NewDrmCollector(logger log.Logger) (Collector, error) { func NewDrmCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := sysfs.NewFS(*sysPath) fs, err := sysfs.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) return nil, fmt.Errorf("failed to open sysfs: %w", err)
} }

View File

@ -40,16 +40,15 @@ type edacCollector struct {
csRowCECount *prometheus.Desc csRowCECount *prometheus.Desc
csRowUECount *prometheus.Desc csRowUECount *prometheus.Desc
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("edac", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("edac", defaultEnabled, NewEdacCollector)
return NewEdacCollector(logger)
})
} }
// NewEdacCollector returns a new Collector exposing edac stats. // 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{ return &edacCollector{
ceCount: prometheus.NewDesc( ceCount: prometheus.NewDesc(
prometheus.BuildFQName(namespace, edacSubsystem, "correctable_errors_total"), prometheus.BuildFQName(namespace, edacSubsystem, "correctable_errors_total"),
@ -72,11 +71,12 @@ func NewEdacCollector(logger log.Logger) (Collector, error) {
[]string{"controller", "csrow"}, nil, []string{"controller", "csrow"}, nil,
), ),
logger: logger, logger: logger,
config: config,
}, nil }, nil
} }
func (c *edacCollector) Update(ch chan<- prometheus.Metric) error { 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 { if err != nil {
return err return err
} }

View File

@ -32,14 +32,12 @@ type entropyCollector struct {
} }
func init() { func init() {
registerCollector("entropy", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("entropy", defaultEnabled, NewEntropyCollector)
return NewEntropyCollector(logger)
})
} }
// NewEntropyCollector returns a new Collector exposing entropy stats. // NewEntropyCollector returns a new Collector exposing entropy stats.
func NewEntropyCollector(logger log.Logger) (Collector, error) { func NewEntropyCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -87,8 +87,8 @@ type EthtoolConfig struct {
// makeEthtoolCollector is the internal constructor for EthtoolCollector. // makeEthtoolCollector is the internal constructor for EthtoolCollector.
// This allows NewEthtoolTestCollector to override its .ethtool interface // This allows NewEthtoolTestCollector to override its .ethtool interface
// for testing. // for testing.
func makeEthtoolCollector(config EthtoolConfig, logger log.Logger) (*ethtoolCollector, error) { func makeEthtoolCollector(config NodeCollectorConfig, logger log.Logger) (*ethtoolCollector, error) {
fs, err := sysfs.NewFS(*sysPath) fs, err := sysfs.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) return nil, fmt.Errorf("failed to open sysfs: %w", err)
} }
@ -102,8 +102,8 @@ func makeEthtoolCollector(config EthtoolConfig, logger log.Logger) (*ethtoolColl
return &ethtoolCollector{ return &ethtoolCollector{
fs: fs, fs: fs,
ethtool: &ethtoolLibrary{e}, ethtool: &ethtoolLibrary{e},
deviceFilter: newDeviceFilter(*config.DeviceExclude, *config.DeviceInclude), deviceFilter: newDeviceFilter(*config.Ethtool.DeviceExclude, *config.Ethtool.DeviceInclude),
metricsPattern: regexp.MustCompile(*config.IncludedMetrics), metricsPattern: regexp.MustCompile(*config.Ethtool.IncludedMetrics),
logger: logger, logger: logger,
entries: map[string]*prometheus.Desc{ entries: map[string]*prometheus.Desc{
"rx_bytes": prometheus.NewDesc( "rx_bytes": prometheus.NewDesc(
@ -203,10 +203,7 @@ func makeEthtoolCollector(config EthtoolConfig, logger log.Logger) (*ethtoolColl
} }
func init() { func init() {
registerCollector("ethtool", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("ethtool", defaultDisabled, NewEthtoolCollector)
cfg := config.(EthtoolConfig)
return NewEthtoolCollector(cfg, logger)
})
} }
// Generate the fully-qualified metric name for the ethool metric. // 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. // 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) return makeEthtoolCollector(config, logger)
} }

View File

@ -23,6 +23,7 @@ import (
"syscall" "syscall"
"testing" "testing"
"github.com/docker/cli/cli/config"
"github.com/go-kit/log" "github.com/go-kit/log"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/testutil" "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="100baseT"} 1.25e+07
node_network_supported_speed_bytes{device="eth0",duplex="half",mode="10baseT"} 1.25e+06 node_network_supported_speed_bytes{device="eth0",duplex="half",mode="10baseT"} 1.25e+06
` `
*sysPath = "fixtures/sys" *config.Path.SysPath = "fixtures/sys"
config := NodeCollectorConfig{} config := NodeCollectorConfig{}
logger := log.NewLogfmtLogger(os.Stderr) logger := log.NewLogfmtLogger(os.Stderr)

View File

@ -28,13 +28,11 @@ type execCollector struct {
} }
func init() { func init() {
registerCollector("exec", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("exec", defaultEnabled, NewExecCollector)
return NewExecCollector(logger)
})
} }
// NewExecCollector returns a new Collector exposing system execution statistics. // 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: // From sys/vm/vm_meter.c:
// All are of type CTLTYPE_UINT. // All are of type CTLTYPE_UINT.
// //

View File

@ -36,17 +36,15 @@ type fibrechannelCollector struct {
} }
func init() { func init() {
registerCollector("fibrechannel", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("fibrechannel", defaultEnabled, NewFibreChannelCollector)
return NewFibreChannelCollector(logger)
})
} }
// NewFibreChannelCollector returns a new Collector exposing FibreChannel stats. // 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 i fibrechannelCollector
var err error var err error
i.fs, err = sysfs.NewFS(*sysPath) i.fs, err = sysfs.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) return nil, fmt.Errorf("failed to open sysfs: %w", err)
} }

View File

@ -33,21 +33,20 @@ const (
type fileFDStatCollector struct { type fileFDStatCollector struct {
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector(fileFDStatSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector(fileFDStatSubsystem, defaultEnabled, NewFileFDStatCollector)
return NewFileFDStatCollector(logger)
})
} }
// NewFileFDStatCollector returns a new Collector exposing file-nr stats. // NewFileFDStatCollector returns a new Collector exposing file-nr stats.
func NewFileFDStatCollector(logger log.Logger) (Collector, error) { func NewFileFDStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &fileFDStatCollector{logger}, nil return &fileFDStatCollector{logger, config}, nil
} }
func (c *fileFDStatCollector) Update(ch chan<- prometheus.Metric) error { func (c *fileFDStatCollector) Update(ch chan<- prometheus.Metric) error {
fileFDStat, err := parseFileFDStats(procFilePath("sys/fs/file-nr")) fileFDStat, err := parseFileFDStats(c.config.Path.procFilePath("sys/fs/file-nr"))
if err != nil { if err != nil {
return fmt.Errorf("couldn't get file-nr: %w", err) return fmt.Errorf("couldn't get file-nr: %w", err)
} }

View File

@ -47,7 +47,7 @@ type filesystemCollector struct {
filesDesc, filesFreeDesc *prometheus.Desc filesDesc, filesFreeDesc *prometheus.Desc
roDesc, deviceErrorDesc *prometheus.Desc roDesc, deviceErrorDesc *prometheus.Desc
logger log.Logger logger log.Logger
config FilesystemConfig config NodeCollectorConfig
} }
type filesystemLabels struct { type filesystemLabels struct {
@ -70,46 +70,43 @@ type FilesystemConfig struct {
} }
func init() { func init() {
registerCollector("filesystem", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("filesystem", defaultEnabled, NewFilesystemCollector)
cfg := config.(FilesystemConfig)
return NewFilesystemCollector(cfg, logger)
})
} }
// NewFilesystemCollector returns a new Collector exposing filesystems stats. // NewFilesystemCollector returns a new Collector exposing filesystems stats.
func NewFilesystemCollector(config FilesystemConfig, logger log.Logger) (Collector, error) { func NewFilesystemCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
if *config.OldMountPointsExcluded != "" { if *config.Filesystem.OldMountPointsExcluded != "" {
if !mountPointsExcludeSet { 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") 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 { } else {
return nil, errors.New("--collector.filesystem.ignored-mount-points and --collector.filesystem.mount-points-exclude are mutually exclusive") return nil, errors.New("--collector.filesystem.ignored-mount-points and --collector.filesystem.mount-points-exclude are mutually exclusive")
} }
} }
if *config.MountPointsExclude != "" { if *config.Filesystem.MountPointsExclude != "" {
level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.mount-points-exclude", "flag", *config.MountPointsExclude) level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.mount-points-exclude", "flag", *config.Filesystem.MountPointsExclude)
} else { } else {
*config.MountPointsExclude = defMountPointsExcluded *config.Filesystem.MountPointsExclude = defMountPointsExcluded
} }
if *config.OldFSTypesExcluded != "" { if *config.Filesystem.OldFSTypesExcluded != "" {
if !fsTypesExcludeSet { 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") 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 { } else {
return nil, errors.New("--collector.filesystem.ignored-fs-types and --collector.filesystem.fs-types-exclude are mutually exclusive") return nil, errors.New("--collector.filesystem.ignored-fs-types and --collector.filesystem.fs-types-exclude are mutually exclusive")
} }
} }
if *config.FSTypesExclude != "" { if *config.Filesystem.FSTypesExclude != "" {
level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.fs-types-exclude", "flag", *config.FSTypesExclude) level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.fs-types-exclude", "flag", *config.Filesystem.FSTypesExclude)
} else { } else {
*config.FSTypesExclude = defFSTypesExcluded *config.Filesystem.FSTypesExclude = defFSTypesExcluded
} }
subsystem := "filesystem" subsystem := "filesystem"
mountPointPattern := regexp.MustCompile(*config.MountPointsExclude) mountPointPattern := regexp.MustCompile(*config.Filesystem.MountPointsExclude)
filesystemsTypesPattern := regexp.MustCompile(*config.FSTypesExclude) filesystemsTypesPattern := regexp.MustCompile(*config.Filesystem.FSTypesExclude)
sizeDesc := prometheus.NewDesc( sizeDesc := prometheus.NewDesc(
prometheus.BuildFQName(namespace, subsystem, "size_bytes"), prometheus.BuildFQName(namespace, subsystem, "size_bytes"),

View File

@ -41,7 +41,7 @@ var stuckMountsMtx = &sync.Mutex{}
// GetStats returns filesystem stats. // GetStats returns filesystem stats.
func (c *filesystemCollector) GetStats() ([]filesystemStats, error) { func (c *filesystemCollector) GetStats() ([]filesystemStats, error) {
mps, err := mountPointDetails(c.logger) mps, err := mountPointDetails(c.config, c.logger)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -50,7 +50,7 @@ func (c *filesystemCollector) GetStats() ([]filesystemStats, error) {
statChan := make(chan filesystemStats) statChan := make(chan filesystemStats)
wg := sync.WaitGroup{} wg := sync.WaitGroup{}
workerCount := *c.config.StatWorkerCount workerCount := *c.config.Filesystem.StatWorkerCount
if workerCount < 1 { if workerCount < 1 {
workerCount = 1 workerCount = 1
} }
@ -103,10 +103,10 @@ func (c *filesystemCollector) GetStats() ([]filesystemStats, error) {
func (c *filesystemCollector) processStat(labels filesystemLabels) filesystemStats { func (c *filesystemCollector) processStat(labels filesystemLabels) filesystemStats {
success := make(chan struct{}) 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) buf := new(unix.Statfs_t)
err := unix.Statfs(rootfsFilePath(labels.mountPoint), buf) err := unix.Statfs(c.config.Path.rootfsFilePath(labels.mountPoint), buf)
stuckMountsMtx.Lock() stuckMountsMtx.Lock()
close(success) close(success)
@ -118,7 +118,7 @@ func (c *filesystemCollector) processStat(labels filesystemLabels) filesystemSta
stuckMountsMtx.Unlock() stuckMountsMtx.Unlock()
if err != nil { 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{ return filesystemStats{
labels: labels, labels: labels,
deviceError: 1, deviceError: 1,
@ -166,22 +166,22 @@ func stuckMountWatcher(mountTimeout *time.Duration, mountPoint string, success c
} }
} }
func mountPointDetails(logger log.Logger) ([]filesystemLabels, error) { func mountPointDetails(config NodeCollectorConfig, logger log.Logger) ([]filesystemLabels, error) {
file, err := os.Open(procFilePath("1/mounts")) file, err := os.Open(config.Path.procFilePath("1/mounts"))
if errors.Is(err, os.ErrNotExist) { if errors.Is(err, os.ErrNotExist) {
// Fallback to `/proc/mounts` if `/proc/1/mounts` is missing due hidepid. // Fallback to `/proc/mounts` if `/proc/1/mounts` is missing due hidepid.
level.Debug(logger).Log("msg", "Reading root mounts failed, falling back to system mounts", "err", err) level.Debug(logger).Log("msg", "Reading root mounts failed, falling back to system mounts", "err", err)
file, err = os.Open(procFilePath("mounts")) file, err = os.Open(config.Path.procFilePath("mounts"))
} }
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer file.Close() 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 var filesystems []filesystemLabels
scanner := bufio.NewScanner(r) scanner := bufio.NewScanner(r)
@ -199,7 +199,7 @@ func parseFilesystemLabels(r io.Reader) ([]filesystemLabels, error) {
filesystems = append(filesystems, filesystemLabels{ filesystems = append(filesystems, filesystemLabels{
device: parts[0], device: parts[0],
mountPoint: rootfsStripPrefix(parts[1]), mountPoint: config.Path.rootfsStripPrefix(parts[1]),
fsType: parts[2], fsType: parts[2],
options: parts[3], options: parts[3],
}) })

View File

@ -43,15 +43,13 @@ var (
) )
func init() { func init() {
registerCollector("hwmon", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("hwmon", defaultEnabled, NewHwMonCollector)
cfg := config.(HwMonConfig)
return NewHwMonCollector(cfg, logger)
})
} }
type hwMonCollector struct { type hwMonCollector struct {
deviceFilter deviceFilter deviceFilter deviceFilter
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
type HwMonConfig struct { type HwMonConfig struct {
@ -61,11 +59,12 @@ type HwMonConfig struct {
// NewHwMonCollector returns a new Collector exposing /sys/class/hwmon stats // NewHwMonCollector returns a new Collector exposing /sys/class/hwmon stats
// (similar to lm-sensors). // (similar to lm-sensors).
func NewHwMonCollector(config HwMonConfig, logger log.Logger) (Collector, error) { func NewHwMonCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &hwMonCollector{ return &hwMonCollector{
logger: logger, logger: logger,
deviceFilter: newDeviceFilter(*config.ChipExclude, *config.ChipInclude), deviceFilter: newDeviceFilter(*config.HwMon.ChipExclude, *config.HwMon.ChipInclude),
config: config,
}, nil }, 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 // Step 1: scan /sys/class/hwmon, resolve all symlinks and call
// updatesHwmon for each folder // updatesHwmon for each folder
hwmonPathName := filepath.Join(sysFilePath("class"), "hwmon") hwmonPathName := filepath.Join(c.config.Path.sysFilePath("class"), "hwmon")
hwmonFiles, err := os.ReadDir(hwmonPathName) hwmonFiles, err := os.ReadDir(hwmonPathName)
if err != nil { if err != nil {

View File

@ -36,17 +36,15 @@ type infinibandCollector struct {
} }
func init() { func init() {
registerCollector("infiniband", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("infiniband", defaultEnabled, NewInfiniBandCollector)
return NewInfiniBandCollector(logger)
})
} }
// NewInfiniBandCollector returns a new Collector exposing InfiniBand stats. // 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 i infinibandCollector
var err error var err error
i.fs, err = sysfs.NewFS(*sysPath) i.fs, err = sysfs.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) return nil, fmt.Errorf("failed to open sysfs: %w", err)
} }

View File

@ -25,16 +25,15 @@ import (
type interruptsCollector struct { type interruptsCollector struct {
desc typedDesc desc typedDesc
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("interrupts", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("interrupts", defaultDisabled, NewInterruptsCollector)
return NewInterruptsCollector(logger)
})
} }
// NewInterruptsCollector returns a new Collector exposing interrupts stats. // 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{ return &interruptsCollector{
desc: typedDesc{prometheus.NewDesc( desc: typedDesc{prometheus.NewDesc(
namespace+"_interrupts_total", namespace+"_interrupts_total",
@ -42,5 +41,6 @@ func NewInterruptsCollector(logger log.Logger) (Collector, error) {
interruptLabelNames, nil, interruptLabelNames, nil,
), prometheus.CounterValue}, ), prometheus.CounterValue},
logger: logger, logger: logger,
config: config,
}, nil }, nil
} }

View File

@ -33,7 +33,7 @@ var (
) )
func (c *interruptsCollector) Update(ch chan<- prometheus.Metric) (err error) { func (c *interruptsCollector) Update(ch chan<- prometheus.Metric) (err error) {
interrupts, err := getInterrupts() interrupts, err := getInterrupts(c.config)
if err != nil { if err != nil {
return fmt.Errorf("couldn't get interrupts: %w", err) return fmt.Errorf("couldn't get interrupts: %w", err)
} }
@ -55,8 +55,8 @@ type interrupt struct {
values []string values []string
} }
func getInterrupts() (map[string]interrupt, error) { func getInterrupts(config NodeCollectorConfig) (map[string]interrupt, error) {
file, err := os.Open(procFilePath("interrupts")) file, err := os.Open(config.Path.procFilePath("interrupts"))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -66,10 +66,7 @@ var (
) )
func init() { func init() {
registerCollector("ipvs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("ipvs", defaultEnabled, NewIPVSCollector)
cfg := config.(IPVSConfig)
return NewIPVSCollector(cfg, logger)
})
} }
type IPVSConfig struct { type IPVSConfig struct {
@ -78,27 +75,27 @@ type IPVSConfig struct {
// NewIPVSCollector sets up a new collector for IPVS metrics. It accepts the // NewIPVSCollector sets up a new collector for IPVS metrics. It accepts the
// "procfs" config parameter to override the default proc location (/proc). // "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) return newIPVSCollector(config, logger)
} }
func newIPVSCollector(config IPVSConfig, logger log.Logger) (*ipvsCollector, error) { func newIPVSCollector(config NodeCollectorConfig, logger log.Logger) (*ipvsCollector, error) {
var ( var (
c ipvsCollector c ipvsCollector
err error err error
subsystem = "ipvs" subsystem = "ipvs"
) )
if *config.Labels == "" { if *config.IPVS.Labels == "" {
*config.Labels = strings.Join(fullIpvsBackendLabels, ",") *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 return nil, err
} }
c.logger = logger c.logger = logger
c.fs, err = procfs.NewFS(*procPath) c.fs, err = procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -32,12 +32,11 @@ var (
type ksmdCollector struct { type ksmdCollector struct {
metricDescs map[string]*prometheus.Desc metricDescs map[string]*prometheus.Desc
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("ksmd", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("ksmd", defaultDisabled, NewKsmdCollector)
return NewKsmdCollector(logger)
})
} }
func getCanonicalMetricName(filename string) string { func getCanonicalMetricName(filename string) string {
@ -52,7 +51,7 @@ func getCanonicalMetricName(filename string) string {
} }
// NewKsmdCollector returns a new Collector exposing kernel/system statistics. // 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" subsystem := "ksmd"
descs := make(map[string]*prometheus.Desc) descs := make(map[string]*prometheus.Desc)
@ -61,13 +60,13 @@ func NewKsmdCollector(logger log.Logger) (Collector, error) {
prometheus.BuildFQName(namespace, subsystem, getCanonicalMetricName(n)), prometheus.BuildFQName(namespace, subsystem, getCanonicalMetricName(n)),
fmt.Sprintf("ksmd '%s' file.", n), nil, nil) 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. // Update implements Collector and exposes kernel and system statistics.
func (c *ksmdCollector) Update(ch chan<- prometheus.Metric) error { func (c *ksmdCollector) Update(ch chan<- prometheus.Metric) error {
for _, n := range ksmdFiles { 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 { if err != nil {
return err return err
} }

View File

@ -27,16 +27,15 @@ import (
type lnstatCollector struct { type lnstatCollector struct {
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("lnstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("lnstat", defaultDisabled, NewLnstatCollector)
return NewLnstatCollector(logger)
})
} }
func NewLnstatCollector(logger log.Logger) (Collector, error) { func NewLnstatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &lnstatCollector{logger}, nil return &lnstatCollector{logger, config}, nil
} }
func (c *lnstatCollector) Update(ch chan<- prometheus.Metric) error { func (c *lnstatCollector) Update(ch chan<- prometheus.Metric) error {
@ -44,7 +43,7 @@ func (c *lnstatCollector) Update(ch chan<- prometheus.Metric) error {
subsystem = "lnstat" subsystem = "lnstat"
) )
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*c.config.Path.ProcPath)
if err != nil { if err != nil {
return fmt.Errorf("failed to open procfs: %w", err) return fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -28,16 +28,15 @@ import (
type loadavgCollector struct { type loadavgCollector struct {
metric []typedDesc metric []typedDesc
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("loadavg", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("loadavg", defaultEnabled, NewLoadavgCollector)
return NewLoadavgCollector(logger)
})
} }
// NewLoadavgCollector returns a new Collector exposing load average stats. // 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{ return &loadavgCollector{
metric: []typedDesc{ metric: []typedDesc{
{prometheus.NewDesc(namespace+"_load1", "1m load average.", nil, nil), prometheus.GaugeValue}, {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}, {prometheus.NewDesc(namespace+"_load15", "15m load average.", nil, nil), prometheus.GaugeValue},
}, },
logger: logger, logger: logger,
config: config,
}, nil }, nil
} }
func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) error { func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) error {
loads, err := getLoad() loads, err := getLoad(c.config)
if err != nil { if err != nil {
return fmt.Errorf("couldn't get load: %w", err) return fmt.Errorf("couldn't get load: %w", err)
} }

View File

@ -24,12 +24,12 @@ import (
) )
// Read loadavg from /proc. // Read loadavg from /proc.
func getLoad() (loads []float64, err error) { func getLoad(config NodeCollectorConfig) (loads []float64, err error) {
data, err := os.ReadFile(procFilePath("loadavg")) data, err := os.ReadFile(config.Path.procFilePath("loadavg"))
if err != nil { if err != nil {
return nil, err return nil, err
} }
loads, err = parseLoad(string(data)) loads, err = parseLoad(config, string(data))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -37,11 +37,11 @@ func getLoad() (loads []float64, err error) {
} }
// Parse /proc loadavg and return 1m, 5m and 15m. // 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) loads = make([]float64, 3)
parts := strings.Fields(data) parts := strings.Fields(data)
if len(parts) < 3 { 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] { for i, load := range parts[0:3] {
loads[i], err = strconv.ParseFloat(load, 64) loads[i], err = strconv.ParseFloat(load, 64)

View File

@ -82,13 +82,11 @@ type logindSeatEntry struct {
} }
func init() { func init() {
registerCollector("logind", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("logind", defaultDisabled, NewLogindCollector)
return NewLogindCollector(logger)
})
} }
// NewLogindCollector returns a new Collector exposing logind statistics. // 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 return &logindCollector{logger}, nil
} }

View File

@ -29,17 +29,16 @@ import (
type mdadmCollector struct { type mdadmCollector struct {
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("mdadm", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("mdadm", defaultEnabled, NewMdadmCollector)
return NewMdadmCollector(logger)
})
} }
// NewMdadmCollector returns a new Collector exposing raid statistics. // NewMdadmCollector returns a new Collector exposing raid statistics.
func NewMdadmCollector(logger log.Logger) (Collector, error) { func NewMdadmCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &mdadmCollector{logger}, nil return &mdadmCollector{logger, config}, nil
} }
var ( var (
@ -104,7 +103,7 @@ var (
) )
func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) error { 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 { if err != nil {
return fmt.Errorf("failed to open procfs: %w", err) 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 err != nil {
if errors.Is(err, os.ErrNotExist) { 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 return ErrNoData
} }

View File

@ -32,17 +32,16 @@ const (
type meminfoCollector struct { type meminfoCollector struct {
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("meminfo", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("meminfo", defaultEnabled, NewMeminfoCollector)
return NewMeminfoCollector(logger)
})
} }
// NewMeminfoCollector returns a new Collector exposing memory stats. // NewMeminfoCollector returns a new Collector exposing memory stats.
func NewMeminfoCollector(logger log.Logger) (Collector, error) { func NewMeminfoCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &meminfoCollector{logger}, nil return &meminfoCollector{logger, config}, nil
} }
// Update calls (*meminfoCollector).getMemInfo to get the platform specific // Update calls (*meminfoCollector).getMemInfo to get the platform specific

View File

@ -31,7 +31,7 @@ var (
) )
func (c *meminfoCollector) getMemInfo() (map[string]float64, error) { 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 { if err != nil {
return nil, err return nil, err
} }

View File

@ -46,6 +46,7 @@ type meminfoMetric struct {
type meminfoNumaCollector struct { type meminfoNumaCollector struct {
metricDescs map[string]*prometheus.Desc metricDescs map[string]*prometheus.Desc
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
@ -57,11 +58,12 @@ func NewMeminfoNumaCollector(config NodeCollectorConfig, logger log.Logger) (Col
return &meminfoNumaCollector{ return &meminfoNumaCollector{
metricDescs: map[string]*prometheus.Desc{}, metricDescs: map[string]*prometheus.Desc{},
logger: logger, logger: logger,
config: config,
}, nil }, nil
} }
func (c *meminfoNumaCollector) Update(ch chan<- prometheus.Metric) error { func (c *meminfoNumaCollector) Update(ch chan<- prometheus.Metric) error {
metrics, err := getMemInfoNuma() metrics, err := getMemInfoNuma(c.config)
if err != nil { if err != nil {
return fmt.Errorf("couldn't get NUMA meminfo: %w", err) 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 return nil
} }
func getMemInfoNuma() ([]meminfoMetric, error) { func getMemInfoNuma(config NodeCollectorConfig) ([]meminfoMetric, error) {
var ( var (
metrics []meminfoMetric 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 { if err != nil {
return nil, err return nil, err
} }

View File

@ -37,9 +37,7 @@ type memoryCollector struct {
} }
func init() { func init() {
registerCollector("meminfo", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("meminfo", defaultEnabled, NewMemoryCollector)
return NewMemoryCollector(logger)
})
} }
// NewMemoryCollector returns a new Collector exposing memory stats. // NewMemoryCollector returns a new Collector exposing memory stats.

View File

@ -107,14 +107,12 @@ type nfsDeviceIdentifier struct {
} }
func init() { func init() {
registerCollector("mountstats", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("mountstats", defaultDisabled, NewMountStatsCollector)
return NewMountStatsCollector(logger)
})
} }
// NewMountStatsCollector returns a new Collector exposing NFS statistics. // NewMountStatsCollector returns a new Collector exposing NFS statistics.
func NewMountStatsCollector(logger log.Logger) (Collector, error) { func NewMountStatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -35,14 +35,11 @@ type netClassCollector struct {
ignoredDevicesPattern *regexp.Regexp ignoredDevicesPattern *regexp.Regexp
metricDescs map[string]*prometheus.Desc metricDescs map[string]*prometheus.Desc
logger log.Logger logger log.Logger
config NetClassConfig config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("netclass", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("netclass", defaultEnabled, NewNetClassCollector)
cfg := config.(NetClassConfig)
return NewNetClassCollector(cfg, logger)
})
} }
type NetClassConfig struct { type NetClassConfig struct {
@ -53,12 +50,12 @@ type NetClassConfig struct {
} }
// NewNetClassCollector returns a new Collector exposing network class stats. // NewNetClassCollector returns a new Collector exposing network class stats.
func NewNetClassCollector(config NetClassConfig, logger log.Logger) (Collector, error) { func NewNetClassCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := sysfs.NewFS(*sysPath) fs, err := sysfs.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) return nil, fmt.Errorf("failed to open sysfs: %w", err)
} }
pattern := regexp.MustCompile(*config.IgnoredDevices) pattern := regexp.MustCompile(*config.NetClass.IgnoredDevices)
return &netClassCollector{ return &netClassCollector{
fs: fs, fs: fs,
subsystem: "network", subsystem: "network",
@ -70,7 +67,7 @@ func NewNetClassCollector(config NetClassConfig, logger log.Logger) (Collector,
} }
func (c *netClassCollector) Update(ch chan<- prometheus.Metric) error { func (c *netClassCollector) Update(ch chan<- prometheus.Metric) error {
if *c.config.Netlink { if *c.config.NetClass.Netlink {
return c.netClassRTNLUpdate(ch) return c.netClassRTNLUpdate(ch)
} }
return c.netClassSysfsUpdate(ch) return c.netClassSysfsUpdate(ch)
@ -126,7 +123,7 @@ func (c *netClassCollector) netClassSysfsUpdate(ch chan<- prometheus.Metric) err
if ifaceInfo.Speed != nil { if ifaceInfo.Speed != nil {
// Some devices return -1 if the speed is unknown. // 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) speedBytes := int64(*ifaceInfo.Speed * 1000 * 1000 / 8)
pushMetric(ch, c.getFieldDesc("speed_bytes"), "speed_bytes", speedBytes, prometheus.GaugeValue, ifaceInfo.Name) pushMetric(ch, c.getFieldDesc("speed_bytes"), "speed_bytes", speedBytes, prometheus.GaugeValue, ifaceInfo.Name)
} }

View File

@ -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) 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. // 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 continue
} }

View File

@ -35,16 +35,13 @@ type netDevCollector struct {
metricDescsMutex sync.Mutex metricDescsMutex sync.Mutex
metricDescs map[string]*prometheus.Desc metricDescs map[string]*prometheus.Desc
logger log.Logger logger log.Logger
config NetDevConfig config NodeCollectorConfig
} }
type netDevStats map[string]map[string]uint64 type netDevStats map[string]map[string]uint64
func init() { func init() {
registerCollector("netdev", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("netdev", defaultEnabled, NewNetDevCollector)
cfg := config.(NetDevConfig)
return NewNetDevCollector(cfg, logger)
})
} }
type NetDevConfig struct { type NetDevConfig struct {
@ -58,40 +55,40 @@ type NetDevConfig struct {
} }
// NewNetDevCollector returns a new Collector exposing network device stats. // NewNetDevCollector returns a new Collector exposing network device stats.
func NewNetDevCollector(config NetDevConfig, logger log.Logger) (Collector, error) { func NewNetDevCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
if *config.OldDeviceInclude != "" { if *config.NetDev.OldDeviceInclude != "" {
if *config.DeviceInclude == "" { 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") 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 { } else {
return nil, errors.New("--collector.netdev.device-whitelist and --collector.netdev.device-include are mutually exclusive") return nil, errors.New("--collector.netdev.device-whitelist and --collector.netdev.device-include are mutually exclusive")
} }
} }
if *config.OldDeviceExclude != "" { if *config.NetDev.OldDeviceExclude != "" {
if *config.DeviceExclude == "" { 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") 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 { } else {
return nil, errors.New("--collector.netdev.device-blacklist and --collector.netdev.device-exclude are mutually exclusive") 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") return nil, errors.New("device-exclude & device-include are mutually exclusive")
} }
if *config.DeviceExclude != "" { if *config.NetDev.DeviceExclude != "" {
level.Info(logger).Log("msg", "Parsed flag --collector.netdev.device-exclude", "flag", *netdevDeviceExclude) level.Info(logger).Log("msg", "Parsed flag --collector.netdev.device-exclude", "flag", *config.NetDev.DeviceExclude)
} }
if *config.DeviceInclude != "" { if *config.NetDev.DeviceInclude != "" {
level.Info(logger).Log("msg", "Parsed Flag --collector.netdev.device-include", "flag", *netdevDeviceInclude) level.Info(logger).Log("msg", "Parsed Flag --collector.netdev.device-include", "flag", *config.NetDev.DeviceInclude)
} }
return &netDevCollector{ return &netDevCollector{
subsystem: "network", subsystem: "network",
deviceFilter: newDeviceFilter(*config.DeviceExclude, *config.DeviceInclude), deviceFilter: newDeviceFilter(*config.NetDev.DeviceExclude, *config.NetDev.DeviceInclude),
metricDescs: map[string]*prometheus.Desc{}, metricDescs: map[string]*prometheus.Desc{},
logger: logger, logger: logger,
config: config, config: config,
@ -115,12 +112,12 @@ func (c *netDevCollector) metricDesc(key string) *prometheus.Desc {
} }
func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error { 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 { if err != nil {
return fmt.Errorf("couldn't get netstats: %w", err) return fmt.Errorf("couldn't get netstats: %w", err)
} }
for dev, devStats := range netDev { for dev, devStats := range netDev {
if !*c.config.DetailedMetrics { if !*c.config.NetDev.DetailedMetrics {
legacy(devStats) legacy(devStats)
} }
for key, value := range 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) ch <- prometheus.MustNewConstMetric(desc, prometheus.CounterValue, float64(value), dev)
} }
} }
if *c.config.AddressInfo { if *c.config.NetDev.AddressInfo {
interfaces, err := net.Interfaces() interfaces, err := net.Interfaces()
if err != nil { if err != nil {
return fmt.Errorf("could not get network interfaces: %w", err) return fmt.Errorf("could not get network interfaces: %w", err)

View File

@ -25,11 +25,11 @@ import (
"github.com/prometheus/procfs" "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 { if *netDevNetlink {
return netlinkStats(filter, logger) return netlinkStats(filter, logger)
} }
return procNetDevStats(filter, logger) return procNetDevStats(config, filter, logger)
} }
func netlinkStats(filter *deviceFilter, logger log.Logger) (netDevStats, error) { func netlinkStats(filter *deviceFilter, logger log.Logger) (netDevStats, error) {
@ -97,10 +97,10 @@ func parseNetlinkStats(links []rtnetlink.LinkMessage, filter *deviceFilter, logg
return metrics return metrics
} }
func procNetDevStats(filter *deviceFilter, logger log.Logger) (netDevStats, error) { func procNetDevStats(config NodeCollectorConfig, filter *deviceFilter, logger log.Logger) (netDevStats, error) {
metrics := netDevStats{} metrics := netDevStats{}
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return metrics, fmt.Errorf("failed to open procfs: %w", err) return metrics, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -33,12 +33,10 @@ const (
) )
func init() { func init() {
registerCollector("netisr", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("netisr", defaultEnabled, NewNetisrCollector)
return NewNetisrCollector(logger)
})
} }
func NewNetisrCollector(logger log.Logger) (Collector, error) { func NewNetisrCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &netisrCollector{ return &netisrCollector{
sysctls: []bsdSysctl{ sysctls: []bsdSysctl{
{ {

View File

@ -37,13 +37,11 @@ const (
type netStatCollector struct { type netStatCollector struct {
fieldPattern *regexp.Regexp fieldPattern *regexp.Regexp
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector(netStatsSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector(netStatsSubsystem, defaultEnabled, NewNetStatCollector)
cfg := config.(NetStatConfig)
return NewNetStatCollector(cfg, logger)
})
} }
type NetStatConfig struct { type NetStatConfig struct {
@ -52,24 +50,25 @@ type NetStatConfig struct {
// NewNetStatCollector takes and returns // NewNetStatCollector takes and returns
// a new Collector exposing network stats. // a new Collector exposing network stats.
func NewNetStatCollector(config NetStatConfig, logger log.Logger) (Collector, error) { func NewNetStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
pattern := regexp.MustCompile(*config.Fields) pattern := regexp.MustCompile(*config.NetStat.Fields)
return &netStatCollector{ return &netStatCollector{
fieldPattern: pattern, fieldPattern: pattern,
logger: logger, logger: logger,
config: config,
}, nil }, nil
} }
func (c *netStatCollector) Update(ch chan<- prometheus.Metric) error { func (c *netStatCollector) Update(ch chan<- prometheus.Metric) error {
netStats, err := getNetStats(procFilePath("net/netstat")) netStats, err := getNetStats(c.config.Path.procFilePath("net/netstat"))
if err != nil { if err != nil {
return fmt.Errorf("couldn't get netstats: %w", err) 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 { if err != nil {
return fmt.Errorf("couldn't get SNMP stats: %w", err) 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 { if err != nil {
return fmt.Errorf("couldn't get SNMP6 stats: %w", err) return fmt.Errorf("couldn't get SNMP6 stats: %w", err)
} }

View File

@ -35,13 +35,11 @@ type networkRouteCollector struct {
} }
func init() { func init() {
registerCollector("network_route", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("network_route", defaultDisabled, NewNetworkRouteCollector)
return NewNetworkRouteCollector(logger)
})
} }
// NewNetworkRouteCollector returns a new Collector exposing systemd statistics. // 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" const subsystem = "network"
routeInfoDesc := prometheus.NewDesc( routeInfoDesc := prometheus.NewDesc(

View File

@ -44,14 +44,12 @@ type nfsCollector struct {
} }
func init() { func init() {
registerCollector("nfs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("nfs", defaultEnabled, NewNfsCollector)
return NewNfsCollector(logger)
})
} }
// NewNfsCollector returns a new Collector exposing NFS statistics. // NewNfsCollector returns a new Collector exposing NFS statistics.
func NewNfsCollector(logger log.Logger) (Collector, error) { func NewNfsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := nfs.NewFS(*procPath) fs, err := nfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -36,9 +36,7 @@ type nfsdCollector struct {
} }
func init() { func init() {
registerCollector("nfsd", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("nfsd", defaultEnabled, NewNFSdCollector)
return NewNFSdCollector(logger)
})
} }
const ( const (
@ -46,8 +44,8 @@ const (
) )
// NewNFSdCollector returns a new Collector exposing /proc/net/rpc/nfsd statistics. // NewNFSdCollector returns a new Collector exposing /proc/net/rpc/nfsd statistics.
func NewNFSdCollector(logger log.Logger) (Collector, error) { func NewNFSdCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := nfs.NewFS(*procPath) fs, err := nfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -41,14 +41,11 @@ var (
type ntpCollector struct { type ntpCollector struct {
stratum, leap, rtt, offset, reftime, rootDelay, rootDispersion, sanity typedDesc stratum, leap, rtt, offset, reftime, rootDelay, rootDispersion, sanity typedDesc
logger log.Logger logger log.Logger
config NTPConfig config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("ntp", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("ntp", defaultDisabled, NewNtpCollector)
cfg := config.(NTPConfig)
return NewNtpCollector(cfg, logger)
})
} }
type NTPConfig struct { type NTPConfig struct {
@ -65,22 +62,22 @@ type NTPConfig struct {
// Default definition of "local" is: // Default definition of "local" is:
// - collector.ntp.server address is a loopback address (or collector.ntp.server-is-mine flag is turned on) // - 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 // - the server is reachable with outgoin IP_TTL = 1
func NewNtpCollector(config NTPConfig, logger log.Logger) (Collector, error) { func NewNtpCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
ipaddr := net.ParseIP(*config.Server) ipaddr := net.ParseIP(*config.NTP.Server)
if !*config.ServerIsLocal && (ipaddr == nil || !ipaddr.IsLoopback()) { 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") return nil, fmt.Errorf("only IP address of local NTP server is valid for --collector.ntp.server")
} }
if *config.ProtocolVersion < 2 || *config.ProtocolVersion > 4 { 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.ProtocolVersion) 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") return nil, fmt.Errorf("offset tolerance must be non-negative")
} }
if *config.ServerPort < 1 || *config.ServerPort > 65535 { 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.ServerPort) 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.") 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 { func (c *ntpCollector) Update(ch chan<- prometheus.Metric) error {
resp, err := ntp.QueryWithOptions(*c.config.Server, ntp.QueryOptions{ resp, err := ntp.QueryWithOptions(*c.config.NTP.Server, ntp.QueryOptions{
Version: *c.config.ProtocolVersion, Version: *c.config.NTP.ProtocolVersion,
TTL: *c.config.IPTTL, TTL: *c.config.NTP.IPTTL,
Timeout: time.Second, // default `ntpdate` timeout Timeout: time.Second, // default `ntpdate` timeout
Port: *c.config.ServerPort, Port: *c.config.NTP.ServerPort,
}) })
if err != nil { if err != nil {
return fmt.Errorf("couldn't get SNTP reply: %w", err) 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 // Here is SNTP packet sanity check that is exposed to move burden of
// configuration from node_exporter user to the developer. // configuration from node_exporter user to the developer.
maxerr := *c.config.OffsetTolerance maxerr := *c.config.NTP.OffsetTolerance
leapMidnightMutex.Lock() leapMidnightMutex.Lock()
if resp.Leap == ntp.LeapAddSecond || resp.Leap == ntp.LeapDelSecond { if resp.Leap == ntp.LeapAddSecond || resp.Leap == ntp.LeapDelSecond {
// state of leapMidnight is cached as leap flag is dropped right after midnight // 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() 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) ch <- c.sanity.mustNewConstMetric(1)
} else { } else {
ch <- c.sanity.mustNewConstMetric(0) ch <- c.sanity.mustNewConstMetric(0)

View File

@ -33,14 +33,12 @@ type nvmeCollector struct {
} }
func init() { func init() {
registerCollector("nvme", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("nvme", defaultEnabled, NewNVMeCollector)
return NewNVMeCollector(logger)
})
} }
// NewNVMeCollector returns a new Collector exposing NVMe stats. // NewNVMeCollector returns a new Collector exposing NVMe stats.
func NewNVMeCollector(logger log.Logger) (Collector, error) { func NewNVMeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := sysfs.NewFS(*sysPath) fs, err := sysfs.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) return nil, fmt.Errorf("failed to open sysfs: %w", err)
} }

View File

@ -65,6 +65,7 @@ type osReleaseCollector struct {
osReleaseFilenames []string // all os-release file names to check osReleaseFilenames []string // all os-release file names to check
version float64 version float64
versionDesc *prometheus.Desc versionDesc *prometheus.Desc
config NodeCollectorConfig
} }
type Plist struct { type Plist struct {
@ -77,13 +78,11 @@ type Dict struct {
} }
func init() { func init() {
registerCollector("os", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("os", defaultEnabled, NewOSCollector)
return NewOSCollector(logger)
})
} }
// NewOSCollector returns a new Collector exposing os-release information. // 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{ return &osReleaseCollector{
logger: logger, logger: logger,
infoDesc: prometheus.NewDesc( infoDesc: prometheus.NewDesc(
@ -99,6 +98,7 @@ func NewOSCollector(logger log.Logger) (Collector, error) {
"Metric containing the major.minor part of the OS version.", "Metric containing the major.minor part of the OS version.",
[]string{"id", "id_like", "name"}, nil, []string{"id", "id_like", "name"}, nil,
), ),
config: config,
}, nil }, nil
} }
@ -176,7 +176,7 @@ func (c *osReleaseCollector) UpdateStruct(path string) error {
func (c *osReleaseCollector) Update(ch chan<- prometheus.Metric) error { func (c *osReleaseCollector) Update(ch chan<- prometheus.Metric) error {
for i, path := range c.osReleaseFilenames { for i, path := range c.osReleaseFilenames {
err := c.UpdateStruct(*rootfsPath + path) err := c.UpdateStruct(*c.config.Path.RootfsPath + path)
if err == nil { if err == nil {
break break
} }

View File

@ -16,40 +16,36 @@ package collector
import ( import (
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/alecthomas/kingpin/v2"
"github.com/prometheus/procfs"
) )
var ( type PathConfig struct {
// The path of the proc filesystem. ProcPath *string
procPath = kingpin.Flag("path.procfs", "procfs mountpoint.").Default(procfs.DefaultMountPoint).String() SysPath *string
sysPath = kingpin.Flag("path.sysfs", "sysfs mountpoint.").Default("/sys").String() RootfsPath *string
rootfsPath = kingpin.Flag("path.rootfs", "rootfs mountpoint.").Default("/").String() UdevDataPath *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)
} }
func sysFilePath(name string) string { func (p *PathConfig) procFilePath(name string) string {
return filepath.Join(*sysPath, name) return filepath.Join(*p.ProcPath, name)
} }
func rootfsFilePath(name string) string { func (p *PathConfig) sysFilePath(name string) string {
return filepath.Join(*rootfsPath, name) return filepath.Join(*p.SysPath, name)
} }
func udevDataFilePath(name string) string { func (p *PathConfig) rootfsFilePath(name string) string {
return filepath.Join(*udevDataPath, name) return filepath.Join(*p.RootfsPath, name)
} }
func rootfsStripPrefix(path string) string { func (p *PathConfig) udevDataFilePath(name string) string {
if *rootfsPath == "/" { return filepath.Join(*p.UdevDataPath, name)
}
func (p *PathConfig) rootfsStripPrefix(path string) string {
if *p.RootfsPath == "/" {
return path return path
} }
stripped := strings.TrimPrefix(path, *rootfsPath) stripped := strings.TrimPrefix(path, *p.RootfsPath)
if stripped == "" { if stripped == "" {
return "/" return "/"
} }

View File

@ -25,11 +25,11 @@ func TestDefaultProcPath(t *testing.T) {
t.Fatal(err) 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) 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) t.Errorf("Expected: %s, Got: %s", want, got)
} }
} }
@ -39,39 +39,39 @@ func TestCustomProcPath(t *testing.T) {
t.Fatal(err) 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) 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) 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 { if _, err := kingpin.CommandLine.Parse([]string{"--path.sysfs", "/sys"}); err != nil {
t.Fatal(err) 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) 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) 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 { if _, err := kingpin.CommandLine.Parse([]string{"--path.sysfs", "./../some/./place/"}); err != nil {
t.Fatal(err) 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) 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) t.Errorf("Expected: %s, Got: %s", want, got)
} }
} }

View File

@ -34,10 +34,7 @@ const (
) )
func init() { func init() {
registerCollector(perfSubsystem, defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector(perfSubsystem, defaultDisabled, NewPerfCollector)
cfg := config.(PerfConfig)
return NewPerfCollector(cfg, logger)
})
} }
type PerfConfig struct { type PerfConfig struct {
@ -303,7 +300,7 @@ func newPerfTracepointCollector(
// NewPerfCollector returns a new perf based collector, it creates a profiler // NewPerfCollector returns a new perf based collector, it creates a profiler
// per CPU. // per CPU.
func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { func NewPerfCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
collector := &perfCollector{ collector := &perfCollector{
perfHwProfilers: map[int]*perf.HardwareProfiler{}, perfHwProfilers: map[int]*perf.HardwareProfiler{},
perfSwProfilers: map[int]*perf.SoftwareProfiler{}, perfSwProfilers: map[int]*perf.SoftwareProfiler{},
@ -318,8 +315,8 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) {
cpus []int cpus []int
err error err error
) )
if config.CPUs != nil && *config.CPUs != "" { if config.Perf.CPUs != nil && *config.Perf.CPUs != "" {
cpus, err = perfCPUFlagToCPUs(*config.CPUs) cpus, err = perfCPUFlagToCPUs(*config.Perf.CPUs)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -331,8 +328,8 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) {
} }
// First configure any tracepoints. // First configure any tracepoints.
if *config.Tracepoint != nil && len(*config.Tracepoint) > 0 { if *config.Perf.Tracepoint != nil && len(*config.Perf.Tracepoint) > 0 {
tracepointCollector, err := newPerfTracepointCollector(logger, *config.Tracepoint, cpus) tracepointCollector, err := newPerfTracepointCollector(logger, *config.Perf.Tracepoint, cpus)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -341,27 +338,27 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) {
// Configure perf profilers // Configure perf profilers
hardwareProfilers := perf.AllHardwareProfilers hardwareProfilers := perf.AllHardwareProfilers
if *config.HwProfiler != nil && len(*config.HwProfiler) > 0 { if *config.Perf.HwProfiler != nil && len(*config.Perf.HwProfiler) > 0 {
// hardwareProfilers = 0 // hardwareProfilers = 0
for _, hf := range *config.HwProfiler { for _, hf := range *config.Perf.HwProfiler {
if v, ok := perfHardwareProfilerMap[hf]; ok { if v, ok := perfHardwareProfilerMap[hf]; ok {
hardwareProfilers |= v hardwareProfilers |= v
} }
} }
} }
softwareProfilers := perf.AllSoftwareProfilers softwareProfilers := perf.AllSoftwareProfilers
if *config.SwProfiler != nil && len(*config.SwProfiler) > 0 { if *config.Perf.SwProfiler != nil && len(*config.Perf.SwProfiler) > 0 {
// softwareProfilers = 0 // softwareProfilers = 0
for _, sf := range *config.SwProfiler { for _, sf := range *config.Perf.SwProfiler {
if v, ok := perfSoftwareProfilerMap[sf]; ok { if v, ok := perfSoftwareProfilerMap[sf]; ok {
softwareProfilers |= v 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 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 cacheProfilers = 0
for _, cf := range *config.CaProfilerFlag { for _, cf := range *config.Perf.CaProfilerFlag {
if v, ok := perfCacheProfilerMap[cf]; ok { if v, ok := perfCacheProfilerMap[cf]; ok {
cacheProfilers |= v cacheProfilers |= v
} }
@ -372,7 +369,7 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) {
for _, cpu := range cpus { for _, cpu := range cpus {
// Use -1 to profile all processes on the CPU, see: // Use -1 to profile all processes on the CPU, see:
// man perf_event_open // man perf_event_open
if !*config.NoHwProfiler { if !*config.Perf.NoHwProfiler {
hwProf, err := perf.NewHardwareProfiler( hwProf, err := perf.NewHardwareProfiler(
-1, -1,
cpu, cpu,
@ -388,7 +385,7 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) {
collector.hwProfilerCPUMap[&hwProf] = cpu collector.hwProfilerCPUMap[&hwProf] = cpu
} }
if !*config.NoSwProfiler { if !*config.Perf.NoSwProfiler {
swProf, err := perf.NewSoftwareProfiler(-1, cpu, softwareProfilers) swProf, err := perf.NewSoftwareProfiler(-1, cpu, softwareProfilers)
if err != nil && !swProf.HasProfilers() { if err != nil && !swProf.HasProfilers() {
return nil, err return nil, err
@ -400,7 +397,7 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) {
collector.swProfilerCPUMap[&swProf] = cpu collector.swProfilerCPUMap[&swProf] = cpu
} }
if !*config.NoCaProfiler { if !*config.Perf.NoCaProfiler {
cacheProf, err := perf.NewCacheProfiler( cacheProf, err := perf.NewCacheProfiler(
-1, -1,
cpu, cpu,

View File

@ -29,21 +29,19 @@ type powerSupplyClassCollector struct {
ignoredPattern *regexp.Regexp ignoredPattern *regexp.Regexp
metricDescs map[string]*prometheus.Desc metricDescs map[string]*prometheus.Desc
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("powersupplyclass", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("powersupplyclass", defaultEnabled, NewPowerSupplyClassCollector)
cfg := config.(PowerSupplyClassConfig)
return NewPowerSupplyClassCollector(cfg, logger)
})
} }
type PowerSupplyClassConfig struct { type PowerSupplyClassConfig struct {
IgnoredPowerSupplies *string IgnoredPowerSupplies *string
} }
func NewPowerSupplyClassCollector(config PowerSupplyClassConfig, logger log.Logger) (Collector, error) { func NewPowerSupplyClassCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
pattern := regexp.MustCompile(*config.IgnoredPowerSupplies) pattern := regexp.MustCompile(*config.PowerSupplyClass.IgnoredPowerSupplies)
return &powerSupplyClassCollector{ return &powerSupplyClassCollector{
subsystem: "power_supply", subsystem: "power_supply",
ignoredPattern: pattern, ignoredPattern: pattern,

View File

@ -28,7 +28,7 @@ import (
) )
func (c *powerSupplyClassCollector) Update(ch chan<- prometheus.Metric) error { 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 err != nil {
if errors.Is(err, os.ErrNotExist) { if errors.Is(err, os.ErrNotExist) {
return ErrNoData return ErrNoData
@ -155,8 +155,8 @@ func pushPowerSupplyMetric(ch chan<- prometheus.Metric, subsystem string, name s
ch <- prometheus.MustNewConstMetric(fieldDesc, valueType, value, powerSupplyName) ch <- prometheus.MustNewConstMetric(fieldDesc, valueType, value, powerSupplyName)
} }
func getPowerSupplyClassInfo(ignore *regexp.Regexp) (sysfs.PowerSupplyClass, error) { func getPowerSupplyClassInfo(config NodeCollectorConfig, ignore *regexp.Regexp) (sysfs.PowerSupplyClass, error) {
fs, err := sysfs.NewFS(*sysPath) fs, err := sysfs.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -45,14 +45,12 @@ type pressureStatsCollector struct {
} }
func init() { func init() {
registerCollector("pressure", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("pressure", defaultEnabled, NewPressureStatsCollector)
return NewPressureStatsCollector(logger)
})
} }
// NewPressureStatsCollector returns a Collector exposing pressure stall information // NewPressureStatsCollector returns a Collector exposing pressure stall information
func NewPressureStatsCollector(logger log.Logger) (Collector, error) { func NewPressureStatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -40,17 +40,16 @@ type processCollector struct {
pidUsed *prometheus.Desc pidUsed *prometheus.Desc
pidMax *prometheus.Desc pidMax *prometheus.Desc
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("processes", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("processes", defaultEnabled, NewProcessStatCollector)
return NewProcessStatCollector(logger)
})
} }
// NewProcessStatCollector returns a new Collector exposing process data read from the proc filesystem. // NewProcessStatCollector returns a new Collector exposing process data read from the proc filesystem.
func NewProcessStatCollector(logger log.Logger) (Collector, error) { func NewProcessStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) 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)) 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 { if err != nil {
return fmt.Errorf("unable to retrieve limit number of threads: %w", err) 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) 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 { if err != nil {
return fmt.Errorf("unable to retrieve limit number of maximum pids alloved: %w", err) 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 { 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 err != nil {
if c.isIgnoredError(err) { if c.isIgnoredError(err) {
level.Debug(c.logger).Log("msg", "file not found when retrieving tasks for pid", "pid", pid, "err", err) level.Debug(c.logger).Log("msg", "file not found when retrieving tasks for pid", "pid", pid, "err", err)

View File

@ -20,6 +20,7 @@ import (
"testing" "testing"
"github.com/alecthomas/kingpin/v2" "github.com/alecthomas/kingpin/v2"
"github.com/docker/cli/cli/config"
"github.com/go-kit/log" "github.com/go-kit/log"
"github.com/prometheus/procfs" "github.com/prometheus/procfs"
) )
@ -29,7 +30,7 @@ func TestReadProcessStatus(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
want := 1 want := 1
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
t.Errorf("failed to open procfs: %v", err) 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) 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 { if err != nil {
t.Fatalf("Unable to retrieve limit number of maximum pids alloved %v\n", err) t.Fatalf("Unable to retrieve limit number of maximum pids alloved %v\n", err)
} }

View File

@ -37,14 +37,11 @@ type qdiscStatCollector struct {
overlimits typedDesc overlimits typedDesc
qlength typedDesc qlength typedDesc
backlog typedDesc backlog typedDesc
config QdiscConfig config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("qdisc", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("qdisc", defaultDisabled, NewQdiscStatCollector)
cfg := config.(QdiscConfig)
return NewQdiscStatCollector(cfg, logger)
})
} }
type QdiscConfig struct { type QdiscConfig struct {
@ -54,8 +51,8 @@ type QdiscConfig struct {
} }
// NewQdiscStatCollector returns a new Collector exposing queuing discipline statistics. // NewQdiscStatCollector returns a new Collector exposing queuing discipline statistics.
func NewQdiscStatCollector(config QdiscConfig, logger log.Logger) (Collector, error) { func NewQdiscStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
if *config.DeviceExclude != "" && *config.DeviceInclude != "" { if *config.Qdisc.DeviceExclude != "" && *config.Qdisc.DeviceInclude != "" {
return nil, fmt.Errorf("collector.qdisk.device-include and collector.qdisk.device-exclude are mutaly exclusive") 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, []string{"device", "kind"}, nil,
), prometheus.GaugeValue}, ), prometheus.GaugeValue},
logger: logger, logger: logger,
deviceFilter: newDeviceFilter(*config.DeviceExclude, *config.DeviceExclude), deviceFilter: newDeviceFilter(*config.Qdisc.DeviceExclude, *config.Qdisc.DeviceExclude),
config: config, config: config,
}, nil }, nil
} }
@ -117,7 +114,7 @@ func (c *qdiscStatCollector) Update(ch chan<- prometheus.Metric) error {
var msgs []qdisc.QdiscInfo var msgs []qdisc.QdiscInfo
var err error var err error
fixtures := *c.config.Fixtures fixtures := *c.config.Qdisc.Fixtures
if fixtures == "" { if fixtures == "" {
msgs, err = qdisc.Get() msgs, err = qdisc.Get()

View File

@ -35,14 +35,11 @@ type raplCollector struct {
logger log.Logger logger log.Logger
joulesMetricDesc *prometheus.Desc joulesMetricDesc *prometheus.Desc
config RaplConfig config NodeCollectorConfig
} }
func init() { func init() {
registerCollector(raplCollectorSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector(raplCollectorSubsystem, defaultEnabled, NewRaplCollector)
cfg := config.(RaplConfig)
return NewRaplCollector(cfg, logger)
})
} }
type RaplConfig struct { type RaplConfig struct {
@ -50,8 +47,8 @@ type RaplConfig struct {
} }
// NewRaplCollector returns a new Collector exposing RAPL metrics. // NewRaplCollector returns a new Collector exposing RAPL metrics.
func NewRaplCollector(config RaplConfig, logger log.Logger) (Collector, error) { func NewRaplCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := sysfs.NewFS(*sysPath) fs, err := sysfs.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, err return nil, err
@ -100,7 +97,7 @@ func (c *raplCollector) Update(ch chan<- prometheus.Metric) error {
joules := float64(microJoules) / 1000000.0 joules := float64(microJoules) / 1000000.0
if *c.config.ZoneLabel { if *c.config.Rapl.ZoneLabel {
ch <- c.joulesMetricWithZoneLabel(rz, joules) ch <- c.joulesMetricWithZoneLabel(rz, joules)
} else { } else {
ch <- c.joulesMetric(rz, joules) ch <- c.joulesMetric(rz, joules)

View File

@ -29,14 +29,11 @@ type runitCollector struct {
stateNormal typedDesc stateNormal typedDesc
stateTimestamp typedDesc stateTimestamp typedDesc
logger log.Logger logger log.Logger
config RunitConfig config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("runit", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("runit", defaultDisabled, NewRunitCollector)
cfg := config.(RunitConfig)
return NewRunitCollector(cfg, logger)
})
} }
type RunitConfig struct { type RunitConfig struct {
@ -44,7 +41,7 @@ type RunitConfig struct {
} }
// NewRunitCollector returns a new Collector exposing runit statistics. // 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 ( var (
subsystem = "service" subsystem = "service"
constLabels = prometheus.Labels{"supervisor": "runit"} 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 { 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 { if err != nil {
return err return err
} }

View File

@ -53,8 +53,8 @@ var (
) )
// NewSchedstatCollector returns a new Collector exposing task scheduler statistics // NewSchedstatCollector returns a new Collector exposing task scheduler statistics
func NewSchedstatCollector(logger log.Logger) (Collector, error) { func NewSchedstatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }
@ -68,9 +68,7 @@ type schedstatCollector struct {
} }
func init() { func init() {
registerCollector("schedstat", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("schedstat", defaultEnabled, NewSchedstatCollector)
return NewSchedstatCollector(logger)
})
} }
func (c *schedstatCollector) Update(ch chan<- prometheus.Metric) error { func (c *schedstatCollector) Update(ch chan<- prometheus.Metric) error {

View File

@ -30,13 +30,11 @@ type selinuxCollector struct {
} }
func init() { func init() {
registerCollector("selinux", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("selinux", defaultEnabled, NewSelinuxCollector)
return NewSelinuxCollector(logger)
})
} }
// NewSelinuxCollector returns a new Collector exposing SELinux statistics. // 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" const subsystem = "selinux"
return &selinuxCollector{ return &selinuxCollector{

View File

@ -32,13 +32,11 @@ type slabinfoCollector struct {
} }
func init() { func init() {
registerCollector("slabinfo", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("slabinfo", defaultDisabled, NewSlabinfoCollector)
return NewSlabinfoCollector(logger)
})
} }
func NewSlabinfoCollector(logger log.Logger) (Collector, error) { func NewSlabinfoCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -36,21 +36,20 @@ var pageSize = os.Getpagesize()
type sockStatCollector struct { type sockStatCollector struct {
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector(sockStatSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector(sockStatSubsystem, defaultEnabled, NewSockStatCollector)
return NewSockStatCollector(logger)
})
} }
// NewSockStatCollector returns a new Collector exposing socket stats. // NewSockStatCollector returns a new Collector exposing socket stats.
func NewSockStatCollector(logger log.Logger) (Collector, error) { func NewSockStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &sockStatCollector{logger}, nil return &sockStatCollector{logger, config}, nil
} }
func (c *sockStatCollector) Update(ch chan<- prometheus.Metric) error { 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 { if err != nil {
return fmt.Errorf("failed to open procfs: %w", err) return fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -31,20 +31,18 @@ type softirqsCollector struct {
} }
func init() { func init() {
registerCollector("softirqs", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("softirqs", defaultDisabled, NewSoftirqsCollector)
return NewSoftirqsCollector(logger)
})
} }
// NewSoftirqsCollector returns a new Collector exposing softirq stats. // 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( desc := typedDesc{prometheus.NewDesc(
namespace+"_softirqs_functions_total", namespace+"_softirqs_functions_total",
"Softirq counts per CPU.", "Softirq counts per CPU.",
softirqLabelNames, nil, softirqLabelNames, nil,
), prometheus.CounterValue} ), prometheus.CounterValue}
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -42,14 +42,12 @@ const (
) )
func init() { func init() {
registerCollector("softnet", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("softnet", defaultEnabled, NewSoftnetCollector)
return NewSoftnetCollector(logger)
})
} }
// NewSoftnetCollector returns a new Collector exposing softnet metrics. // NewSoftnetCollector returns a new Collector exposing softnet metrics.
func NewSoftnetCollector(logger log.Logger) (Collector, error) { func NewSoftnetCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -34,14 +34,11 @@ type statCollector struct {
procsBlocked *prometheus.Desc procsBlocked *prometheus.Desc
softIRQ *prometheus.Desc softIRQ *prometheus.Desc
logger log.Logger logger log.Logger
config StatConfig config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("stat", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("stat", defaultEnabled, NewStatCollector)
cfg := config.(StatConfig)
return NewStatCollector(cfg, logger)
})
} }
type StatConfig struct { type StatConfig struct {
@ -49,8 +46,8 @@ type StatConfig struct {
} }
// NewStatCollector returns a new Collector exposing kernel/system statistics. // NewStatCollector returns a new Collector exposing kernel/system statistics.
func NewStatCollector(config StatConfig, logger log.Logger) (Collector, error) { func NewStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) 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.procsRunning, prometheus.GaugeValue, float64(stats.ProcessesRunning))
ch <- prometheus.MustNewConstMetric(c.procsBlocked, prometheus.GaugeValue, float64(stats.ProcessesBlocked)) ch <- prometheus.MustNewConstMetric(c.procsBlocked, prometheus.GaugeValue, float64(stats.ProcessesBlocked))
if *c.config.Softirq { if *c.config.Stat.Softirq {
si := stats.SoftIRQ si := stats.SoftIRQ
for _, vec := range []struct { for _, vec := range []struct {

View File

@ -43,10 +43,7 @@ type supervisordCollector struct {
} }
func init() { func init() {
registerCollector("supervisord", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("supervisord", defaultDisabled, NewSupervisordCollector)
cfg := config.(SupervisordConfig)
return NewSupervisordCollector(cfg, logger)
})
} }
type SupervisordConfig struct { type SupervisordConfig struct {
@ -54,13 +51,13 @@ type SupervisordConfig struct {
} }
// NewSupervisordCollector returns a new Collector exposing supervisord statistics. // 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 ( var (
subsystem = "supervisord" subsystem = "supervisord"
labelNames = []string{"name", "group"} 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 // Fake the URI scheme as http, since net/http.*Transport.roundTrip will complain
// about a non-http(s) transport. // about a non-http(s) transport.
xrpc = xmlrpc.NewClient("http://unix/RPC2") xrpc = xmlrpc.NewClient("http://unix/RPC2")
@ -71,7 +68,7 @@ func NewSupervisordCollector(config SupervisordConfig, logger log.Logger) (Colle
}, },
} }
} else { } 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.") level.Warn(logger).Log("msg", "This collector is deprecated and will be removed in the next major version release.")

View File

@ -34,10 +34,7 @@ type sysctlCollector struct {
} }
func init() { func init() {
registerCollector("sysctl", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("sysctl", defaultDisabled, NewSysctlCollector)
cfg := config.(SysctlConfig)
return NewSysctlCollector(cfg, logger)
})
} }
type SysctlConfig struct { type SysctlConfig struct {
@ -45,8 +42,8 @@ type SysctlConfig struct {
IncludeInfo *[]string IncludeInfo *[]string
} }
func NewSysctlCollector(config SysctlConfig, logger log.Logger) (Collector, error) { func NewSysctlCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) 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{}, sysctls: []*sysctl{},
} }
for _, include := range *config.Include { for _, include := range *config.Sysctl.Include {
sysctl, err := newSysctl(include, true) sysctl, err := newSysctl(include, true)
if err != nil { if err != nil {
return nil, err return nil, err
@ -64,7 +61,7 @@ func NewSysctlCollector(config SysctlConfig, logger log.Logger) (Collector, erro
c.sysctls = append(c.sysctls, sysctl) c.sysctls = append(c.sysctls, sysctl)
} }
for _, include := range *config.IncludeInfo { for _, include := range *config.Sysctl.IncludeInfo {
sysctl, err := newSysctl(include, false) sysctl, err := newSysctl(include, false)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -64,16 +64,13 @@ type systemdCollector struct {
systemdUnitIncludePattern *regexp.Regexp systemdUnitIncludePattern *regexp.Regexp
systemdUnitExcludePattern *regexp.Regexp systemdUnitExcludePattern *regexp.Regexp
logger log.Logger logger log.Logger
config SystemdConfig config NodeCollectorConfig
} }
var unitStatesName = []string{"active", "activating", "deactivating", "inactive", "failed"} var unitStatesName = []string{"active", "activating", "deactivating", "inactive", "failed"}
func init() { func init() {
registerCollector("systemd", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("systemd", defaultDisabled, NewSystemdCollector)
cfg := config.(SystemdConfig)
return NewSystemdCollector(cfg, logger)
})
} }
type SystemdConfig struct { type SystemdConfig struct {
@ -88,7 +85,7 @@ type SystemdConfig struct {
} }
// NewSystemdCollector returns a new Collector exposing systemd statistics. // 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" const subsystem = "systemd"
unitDesc := prometheus.NewDesc( unitDesc := prometheus.NewDesc(
@ -134,26 +131,26 @@ func NewSystemdCollector(config SystemdConfig, logger log.Logger) (Collector, er
prometheus.BuildFQName(namespace, subsystem, "version"), prometheus.BuildFQName(namespace, subsystem, "version"),
"Detected systemd version", []string{"version"}, nil) "Detected systemd version", []string{"version"}, nil)
if *config.OldUnitExclude != "" { if *config.Systemd.OldUnitExclude != "" {
if !systemdUnitExcludeSet { 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") 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 { } else {
return nil, errors.New("--collector.systemd.unit-blacklist and --collector.systemd.unit-exclude are mutually exclusive") 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 { 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") 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 { } else {
return nil, errors.New("--collector.systemd.unit-whitelist and --collector.systemd.unit-include are mutually exclusive") 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) level.Info(logger).Log("msg", "Parsed flag --collector.systemd.unit-include", "flag", *config.Systemd.UnitInclude)
systemdUnitIncludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *config.UnitInclude)) systemdUnitIncludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *config.Systemd.UnitInclude))
level.Info(logger).Log("msg", "Parsed flag --collector.systemd.unit-exclude", "flag", *config.UnitExclude) level.Info(logger).Log("msg", "Parsed flag --collector.systemd.unit-exclude", "flag", *config.Systemd.UnitExclude)
systemdUnitExcludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *config.UnitExclude)) systemdUnitExcludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *config.Systemd.UnitExclude))
return &systemdCollector{ return &systemdCollector{
unitDesc: unitDesc, unitDesc: unitDesc,
@ -178,7 +175,7 @@ func NewSystemdCollector(config SystemdConfig, logger log.Logger) (Collector, er
// to reduce wait time for responses. // to reduce wait time for responses.
func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error { func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error {
begin := time.Now() begin := time.Now()
conn, err := newSystemdDbusConn(c.config.Private) conn, err := newSystemdDbusConn(c.config.Systemd.Private)
if err != nil { if err != nil {
return fmt.Errorf("couldn't get dbus connection: %w", err) 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()) 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) wg.Add(1)
go func() { go func() {
defer wg.Done() 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) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
@ -295,7 +292,7 @@ func (c *systemdCollector) collectUnitStatusMetrics(conn *dbus.Conn, ch chan<- p
c.unitDesc, prometheus.GaugeValue, isActive, c.unitDesc, prometheus.GaugeValue, isActive,
unit.Name, stateName, serviceType) 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. // NRestarts wasn't added until systemd 235.
restartsCount, err := conn.GetUnitTypePropertyContext(context.TODO(), unit.Name, "Service", "NRestarts") restartsCount, err := conn.GetUnitTypePropertyContext(context.TODO(), unit.Name, "Service", "NRestarts")
if err != nil { if err != nil {

View File

@ -44,10 +44,7 @@ type tapestatsCollector struct {
} }
func init() { func init() {
registerCollector("tapestats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("tapestats", defaultEnabled, NewTapestatsCollector)
cfg := config.(TapestatsConfig)
return NewTapestatsCollector(cfg, logger)
})
} }
type TapestatsConfig struct { type TapestatsConfig struct {
@ -56,10 +53,10 @@ type TapestatsConfig struct {
// NewTapestatsCollector returns a new Collector exposing tape device stats. // 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 // 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"} var tapeLabelNames = []string{"device"}
fs, err := sysfs.NewFS(*sysPath) fs, err := sysfs.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) return nil, fmt.Errorf("failed to open sysfs: %w", err)
} }
@ -67,7 +64,7 @@ func NewTapestatsCollector(config TapestatsConfig, logger log.Logger) (Collector
tapeSubsystem := "tape" tapeSubsystem := "tape"
return &tapestatsCollector{ return &tapestatsCollector{
ignoredDevicesPattern: regexp.MustCompile(*config.IgnoredDevices), ignoredDevicesPattern: regexp.MustCompile(*config.Tapestats.IgnoredDevices),
ioNow: prometheus.NewDesc( ioNow: prometheus.NewDesc(
prometheus.BuildFQName(namespace, tapeSubsystem, "io_now"), prometheus.BuildFQName(namespace, tapeSubsystem, "io_now"),

View File

@ -61,16 +61,15 @@ const (
type tcpStatCollector struct { type tcpStatCollector struct {
desc typedDesc desc typedDesc
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("tcpstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("tcpstat", defaultDisabled, NewTCPStatCollector)
return NewTCPStatCollector(logger)
})
} }
// NewTCPStatCollector returns a new Collector exposing network stats. // 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{ return &tcpStatCollector{
desc: typedDesc{prometheus.NewDesc( desc: typedDesc{prometheus.NewDesc(
prometheus.BuildFQName(namespace, "tcp", "connection_states"), prometheus.BuildFQName(namespace, "tcp", "connection_states"),
@ -78,6 +77,7 @@ func NewTCPStatCollector(logger log.Logger) (Collector, error) {
[]string{"state"}, nil, []string{"state"}, nil,
), prometheus.GaugeValue}, ), prometheus.GaugeValue},
logger: logger, logger: logger,
config: config,
}, nil }, nil
} }
@ -137,7 +137,7 @@ func (c *tcpStatCollector) Update(ch chan<- prometheus.Metric) error {
} }
// if enabled ipv6 system // 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) tcp6Stats, err := getTCPStats(syscall.AF_INET6)
if err != nil { if err != nil {
return fmt.Errorf("couldn't get tcp6stats: %w", err) return fmt.Errorf("couldn't get tcp6stats: %w", err)

View File

@ -48,10 +48,7 @@ type textFileCollector struct {
} }
func init() { func init() {
registerCollector("textfile", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("textfile", defaultEnabled, NewTextFileCollector)
cfg := config.(TextFileConfig)
return NewTextFileCollector(cfg, logger)
})
} }
type TextFileConfig struct { type TextFileConfig struct {
@ -60,9 +57,9 @@ type TextFileConfig struct {
// NewTextFileCollector returns a new Collector exposing metrics read from files // NewTextFileCollector returns a new Collector exposing metrics read from files
// in the given textfile directory. // 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{ c := &textFileCollector{
path: *config.Directory, path: *config.TextFile.Directory,
logger: logger, logger: logger,
} }
return c, nil return c, nil

View File

@ -63,9 +63,7 @@ type thermCollector struct {
const thermal = "thermal" const thermal = "thermal"
func init() { func init() {
registerCollector(thermal, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector(thermal, defaultEnabled, NewThermCollector)
return NewThermCollector(logger)
})
} }
// NewThermCollector returns a new Collector exposing current CPU power levels. // NewThermCollector returns a new Collector exposing current CPU power levels.

View File

@ -39,14 +39,12 @@ type thermalZoneCollector struct {
} }
func init() { func init() {
registerCollector("thermal_zone", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("thermal_zone", defaultEnabled, NewThermalZoneCollector)
return NewThermalZoneCollector(logger)
})
} }
// NewThermalZoneCollector returns a new Collector exposing kernel/system statistics. // NewThermalZoneCollector returns a new Collector exposing kernel/system statistics.
func NewThermalZoneCollector(logger log.Logger) (Collector, error) { func NewThermalZoneCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := sysfs.NewFS(*sysPath) fs, err := sysfs.NewFS(*config.Path.SysPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err) return nil, fmt.Errorf("failed to open sysfs: %w", err)
} }

View File

@ -30,17 +30,16 @@ type timeCollector struct {
clocksourcesAvailable typedDesc clocksourcesAvailable typedDesc
clocksourceCurrent typedDesc clocksourceCurrent typedDesc
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("time", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("time", defaultEnabled, NewTimeCollector)
return NewTimeCollector(logger)
})
} }
// NewTimeCollector returns a new Collector exposing the current system time in // NewTimeCollector returns a new Collector exposing the current system time in
// seconds since epoch. // seconds since epoch.
func NewTimeCollector(logger log.Logger) (Collector, error) { func NewTimeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
const subsystem = "time" const subsystem = "time"
return &timeCollector{ return &timeCollector{
now: typedDesc{prometheus.NewDesc( now: typedDesc{prometheus.NewDesc(
@ -64,6 +63,7 @@ func NewTimeCollector(logger log.Logger) (Collector, error) {
[]string{"device", "clocksource"}, nil, []string{"device", "clocksource"}, nil,
), prometheus.GaugeValue}, ), prometheus.GaugeValue},
logger: logger, logger: logger,
config: config,
}, nil }, nil
} }

View File

@ -26,7 +26,7 @@ import (
) )
func (c *timeCollector) update(ch chan<- prometheus.Metric) error { 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 { if err != nil {
return fmt.Errorf("failed to open procfs: %w", err) return fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -62,13 +62,11 @@ type timexCollector struct {
} }
func init() { func init() {
registerCollector("timex", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("timex", defaultEnabled, NewTimexCollector)
return NewTimexCollector(logger)
})
} }
// NewTimexCollector returns a new Collector exposing adjtime(3) stats. // 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" const subsystem = "timex"
return &timexCollector{ return &timexCollector{

View File

@ -36,14 +36,12 @@ type (
) )
func init() { func init() {
registerCollector("udp_queues", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("udp_queues", defaultEnabled, NewUDPqueuesCollector)
return NewUDPqueuesCollector(logger)
})
} }
// NewUDPqueuesCollector returns a new Collector exposing network udp queued bytes. // NewUDPqueuesCollector returns a new Collector exposing network udp queued bytes.
func NewUDPqueuesCollector(logger log.Logger) (Collector, error) { func NewUDPqueuesCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath) fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err) return nil, fmt.Errorf("failed to open procfs: %w", err)
} }

View File

@ -49,13 +49,11 @@ type uname struct {
} }
func init() { func init() {
registerCollector("uname", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("uname", defaultEnabled, newUnameCollector)
return newUnameCollector(logger)
})
} }
// NewUnameCollector returns new unameCollector. // NewUnameCollector returns new unameCollector.
func newUnameCollector(logger log.Logger) (Collector, error) { func newUnameCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &unameCollector{logger}, nil return &unameCollector{logger}, nil
} }

View File

@ -35,13 +35,11 @@ const (
type vmStatCollector struct { type vmStatCollector struct {
fieldPattern *regexp.Regexp fieldPattern *regexp.Regexp
logger log.Logger logger log.Logger
config NodeCollectorConfig
} }
func init() { func init() {
registerCollector(vmStatSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { registerCollector(vmStatSubsystem, defaultEnabled, NewvmStatCollector)
cfg := config.(VmStatConfig)
return NewvmStatCollector(cfg, logger)
})
} }
type VmStatConfig struct { type VmStatConfig struct {
@ -49,16 +47,17 @@ type VmStatConfig struct {
} }
// NewvmStatCollector returns a new Collector exposing vmstat stats. // NewvmStatCollector returns a new Collector exposing vmstat stats.
func NewvmStatCollector(config VmStatConfig, logger log.Logger) (Collector, error) { func NewvmStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) {
pattern := regexp.MustCompile(*config.Fields) pattern := regexp.MustCompile(*config.VmStat.Fields)
return &vmStatCollector{ return &vmStatCollector{
fieldPattern: pattern, fieldPattern: pattern,
logger: logger, logger: logger,
config: config,
}, nil }, nil
} }
func (c *vmStatCollector) Update(ch chan<- prometheus.Metric) error { 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 { if err != nil {
return err return err
} }

View File

@ -45,14 +45,11 @@ type wifiCollector struct {
stationBeaconLossTotal *prometheus.Desc stationBeaconLossTotal *prometheus.Desc
logger log.Logger logger log.Logger
config WifiConfig config NodeCollectorConfig
} }
func init() { func init() {
registerCollector("wifi", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { registerCollector("wifi", defaultDisabled, NewWifiCollector)
cfg := config.(WifiConfig)
return NewWifiCollector(cfg, logger)
})
} }
type WifiConfig struct { type WifiConfig struct {
@ -70,7 +67,7 @@ type wifiStater interface {
} }
// NewWifiCollector returns a new Collector exposing Wifi statistics. // 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 ( const (
subsystem = "wifi" subsystem = "wifi"
) )
@ -169,7 +166,7 @@ func NewWifiCollector(config WifiConfig, logger log.Logger) (Collector, error) {
} }
func (c *wifiCollector) Update(ch chan<- prometheus.Metric) 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 { if err != nil {
// Cannot access wifi metrics, report no error. // Cannot access wifi metrics, report no error.
if errors.Is(err, os.ErrNotExist) { if errors.Is(err, os.ErrNotExist) {

Some files were not shown because too many files have changed in this diff Show More