mirror of
				https://github.com/prometheus/node_exporter.git
				synced 2025-08-20 18:33:52 -07:00 
			
		
		
		
	Refactor collectors - part 3
This commit is contained in:
		
							parent
							
								
									ed7a10dde2
								
							
						
					
					
						commit
						96f13a2e27
					
				|  | @ -32,10 +32,7 @@ type arpCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("arp", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		arpConfig := config.(ArpConfig) | ||||
| 		return NewARPCollector(arpConfig, logger) | ||||
| 	}) | ||||
| 	registerCollector("arp", defaultEnabled, NewARPCollector) | ||||
| } | ||||
| 
 | ||||
| type ArpConfig struct { | ||||
|  | @ -44,15 +41,15 @@ type ArpConfig struct { | |||
| } | ||||
| 
 | ||||
| // NewARPCollector returns a new Collector exposing ARP stats.
 | ||||
| func NewARPCollector(config ArpConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| func NewARPCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	return &arpCollector{ | ||||
| 		fs:           fs, | ||||
| 		deviceFilter: newDeviceFilter(*config.DeviceExclude, *config.DeviceInclude), | ||||
| 		deviceFilter: newDeviceFilter(*config.Arp.DeviceExclude, *config.Arp.DeviceInclude), | ||||
| 		entries: prometheus.NewDesc( | ||||
| 			prometheus.BuildFQName(namespace, "arp", "entries"), | ||||
| 			"ARP entries by device", | ||||
|  |  | |||
|  | @ -25,17 +25,15 @@ import ( | |||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("bcache", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		bcacheConfig := config.(BcacheConfig) | ||||
| 		return NewBcacheCollector(bcacheConfig, logger) | ||||
| 	}) | ||||
| 	registerCollector("bcache", defaultEnabled, NewBcacheCollector) | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| // A bcacheCollector is a Collector which gathers metrics from Linux bcache.
 | ||||
| type bcacheCollector struct { | ||||
| 	fs     bcache.FS | ||||
| 	logger log.Logger | ||||
| 	config BcacheConfig | ||||
| 	config NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| type BcacheConfig struct { | ||||
|  | @ -44,8 +42,8 @@ type BcacheConfig struct { | |||
| 
 | ||||
| // NewBcacheCollector returns a newly allocated bcacheCollector.
 | ||||
| // It exposes a number of Linux bcache statistics.
 | ||||
| func NewBcacheCollector(config BcacheConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := bcache.NewFS(*sysPath) | ||||
| func NewBcacheCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := bcache.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  | @ -62,7 +60,7 @@ func NewBcacheCollector(config BcacheConfig, logger log.Logger) (Collector, erro | |||
| func (c *bcacheCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	var stats []*bcache.Stats | ||||
| 	var err error | ||||
| 	if *c.config.PriorityStats { | ||||
| 	if *c.config.Bcache.PriorityStats { | ||||
| 		stats, err = c.fs.Stats() | ||||
| 	} else { | ||||
| 		stats, err = c.fs.StatsWithoutPriority() | ||||
|  | @ -321,7 +319,7 @@ func (c *bcacheCollector) updateBcacheStats(ch chan<- prometheus.Metric, s *bcac | |||
| 				extraLabelValue: cache.Name, | ||||
| 			}, | ||||
| 		} | ||||
| 		if *c.config.PriorityStats { | ||||
| 		if *c.config.Bcache.PriorityStats { | ||||
| 			// metrics in /sys/fs/bcache/<uuid>/<cache>/priority_stats
 | ||||
| 			priorityStatsMetrics := []bcacheMetric{ | ||||
| 				{ | ||||
|  |  | |||
|  | @ -31,17 +31,16 @@ import ( | |||
| type bondingCollector struct { | ||||
| 	slaves, active typedDesc | ||||
| 	logger         log.Logger | ||||
| 	config         NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("bonding", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewBondingCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("bonding", defaultEnabled, NewBondingCollector) | ||||
| } | ||||
| 
 | ||||
| // NewBondingCollector returns a newly allocated bondingCollector.
 | ||||
| // It exposes the number of configured and active slave of linux bonding interfaces.
 | ||||
| func NewBondingCollector(logger log.Logger) (Collector, error) { | ||||
| func NewBondingCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &bondingCollector{ | ||||
| 		slaves: typedDesc{prometheus.NewDesc( | ||||
| 			prometheus.BuildFQName(namespace, "bonding", "slaves"), | ||||
|  | @ -54,12 +53,13 @@ func NewBondingCollector(logger log.Logger) (Collector, error) { | |||
| 			[]string{"master"}, nil, | ||||
| 		), prometheus.GaugeValue}, | ||||
| 		logger: logger, | ||||
| 		config: config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| // Update reads and exposes bonding states, implements Collector interface. Caution: This works only on linux.
 | ||||
| func (c *bondingCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	statusfile := sysFilePath("class/net") | ||||
| 	statusfile := c.config.Path.sysFilePath("class/net") | ||||
| 	bondingStats, err := readBondingStats(statusfile) | ||||
| 	if err != nil { | ||||
| 		if errors.Is(err, os.ErrNotExist) { | ||||
|  |  | |||
|  | @ -28,13 +28,11 @@ type bootTimeCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("boottime", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return newBootTimeCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("boottime", defaultEnabled, newBootTimeCollector(logger)) | ||||
| } | ||||
| 
 | ||||
| // newBootTimeCollector returns a new Collector exposing system boot time on BSD systems.
 | ||||
| func newBootTimeCollector(logger log.Logger) (Collector, error) { | ||||
| func newBootTimeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &bootTimeCollector{ | ||||
| 		logger: logger, | ||||
| 	}, nil | ||||
|  |  | |||
|  | @ -28,12 +28,10 @@ type bootTimeCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("boottime", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return newBootTimeCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("boottime", defaultEnabled, newBootTimeCollector) | ||||
| } | ||||
| 
 | ||||
| func newBootTimeCollector(logger log.Logger) (Collector, error) { | ||||
| func newBootTimeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &bootTimeCollector{ | ||||
| 		boottime: typedDesc{ | ||||
| 			prometheus.NewDesc( | ||||
|  |  | |||
|  | @ -33,17 +33,16 @@ import ( | |||
| type btrfsCollector struct { | ||||
| 	fs     btrfs.FS | ||||
| 	logger log.Logger | ||||
| 	config NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("btrfs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewBtrfsCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("btrfs", defaultEnabled, NewBtrfsCollector) | ||||
| } | ||||
| 
 | ||||
| // NewBtrfsCollector returns a new Collector exposing Btrfs statistics.
 | ||||
| func NewBtrfsCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := btrfs.NewFS(*sysPath) | ||||
| func NewBtrfsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := btrfs.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  | @ -51,6 +50,7 @@ func NewBtrfsCollector(logger log.Logger) (Collector, error) { | |||
| 	return &btrfsCollector{ | ||||
| 		fs:     fs, | ||||
| 		logger: logger, | ||||
| 		config: config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
|  | @ -105,7 +105,7 @@ type btrfsIoctlFsStats struct { | |||
| func (c *btrfsCollector) getIoctlStats() (map[string]*btrfsIoctlFsStats, error) { | ||||
| 	// Instead of introducing more ioctl calls to scan for all btrfs
 | ||||
| 	// filesystems re-use our mount point utils to find known mounts
 | ||||
| 	mountsList, err := mountPointDetails(c.logger) | ||||
| 	mountsList, err := mountPointDetails(c.config, c.logger) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | @ -125,7 +125,7 @@ func (c *btrfsCollector) getIoctlStats() (map[string]*btrfsIoctlFsStats, error) | |||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		mountPath := rootfsFilePath(mount.mountPoint) | ||||
| 		mountPath := c.config.Path.rootfsFilePath(mount.mountPoint) | ||||
| 
 | ||||
| 		fs, err := dennwc.Open(mountPath, true) | ||||
| 		if err != nil { | ||||
|  |  | |||
|  | @ -37,19 +37,17 @@ type buddyinfoCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("buddyinfo", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewBuddyinfoCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("buddyinfo", defaultDisabled, NewBuddyinfoCollector) | ||||
| } | ||||
| 
 | ||||
| // NewBuddyinfoCollector returns a new Collector exposing buddyinfo stats.
 | ||||
| func NewBuddyinfoCollector(logger log.Logger) (Collector, error) { | ||||
| func NewBuddyinfoCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	desc := prometheus.NewDesc( | ||||
| 		prometheus.BuildFQName(namespace, buddyInfoSubsystem, "blocks"), | ||||
| 		"Count of free blocks according to size.", | ||||
| 		[]string{"node", "zone", "size"}, nil, | ||||
| 	) | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -34,14 +34,12 @@ type cgroupSummaryCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector(cgroupsCollectorSubsystem, defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewCgroupSummaryCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector(cgroupsCollectorSubsystem, defaultDisabled, NewCgroupSummaryCollector) | ||||
| } | ||||
| 
 | ||||
| // NewCgroupSummaryCollector returns a new Collector exposing a summary of cgroups.
 | ||||
| func NewCgroupSummaryCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| func NewCgroupSummaryCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -50,14 +50,14 @@ const ( | |||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	factories              = make(map[string]func(config any, logger log.Logger) (Collector, error)) | ||||
| 	factories              = make(map[string]func(config NodeCollectorConfig, logger log.Logger) (Collector, error)) | ||||
| 	initiatedCollectorsMtx = sync.Mutex{} | ||||
| 	initiatedCollectors    = make(map[string]Collector) | ||||
| 	collectorState         = make(map[string]*bool) | ||||
| 	forcedCollectors       = map[string]bool{} // collectors which have been explicitly enabled or disabled
 | ||||
| ) | ||||
| 
 | ||||
| func registerCollector(collector string, isDefaultEnabled bool, factory func(config any, logger log.Logger) (Collector, error)) { | ||||
| func registerCollector(collector string, isDefaultEnabled bool, factory func(config NodeCollectorConfig, logger log.Logger) (Collector, error)) { | ||||
| 	var helpDefaultState string | ||||
| 	if isDefaultEnabled { | ||||
| 		helpDefaultState = "enabled" | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ type NodeCollectorConfig struct { | |||
| 	NetDev                NetDevConfig | ||||
| 	NetStat               NetStatConfig | ||||
| 	NTP                   NTPConfig | ||||
| 	Path                  PathConfig | ||||
| 	Perf                  PerfConfig | ||||
| 	PowerSupplyClass      PowerSupplyClassConfig | ||||
| 	Qdisc                 QdiscConfig | ||||
|  |  | |||
|  | @ -39,6 +39,7 @@ type conntrackCollector struct { | |||
| 	earlyDrop     *prometheus.Desc | ||||
| 	searchRestart *prometheus.Desc | ||||
| 	logger        log.Logger | ||||
| 	config        NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| type conntrackStatistics struct { | ||||
|  | @ -53,13 +54,11 @@ type conntrackStatistics struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("conntrack", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewConntrackCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("conntrack", defaultEnabled, NewConntrackCollector) | ||||
| } | ||||
| 
 | ||||
| // NewConntrackCollector returns a new Collector exposing conntrack stats.
 | ||||
| func NewConntrackCollector(logger log.Logger) (Collector, error) { | ||||
| func NewConntrackCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &conntrackCollector{ | ||||
| 		current: prometheus.NewDesc( | ||||
| 			prometheus.BuildFQName(namespace, "", "nf_conntrack_entries"), | ||||
|  | @ -112,25 +111,26 @@ func NewConntrackCollector(logger log.Logger) (Collector, error) { | |||
| 			nil, nil, | ||||
| 		), | ||||
| 		logger: logger, | ||||
| 		config: config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func (c *conntrackCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	value, err := readUintFromFile(procFilePath("sys/net/netfilter/nf_conntrack_count")) | ||||
| 	value, err := readUintFromFile(c.config.Path.procFilePath("sys/net/netfilter/nf_conntrack_count")) | ||||
| 	if err != nil { | ||||
| 		return c.handleErr(err) | ||||
| 	} | ||||
| 	ch <- prometheus.MustNewConstMetric( | ||||
| 		c.current, prometheus.GaugeValue, float64(value)) | ||||
| 
 | ||||
| 	value, err = readUintFromFile(procFilePath("sys/net/netfilter/nf_conntrack_max")) | ||||
| 	value, err = readUintFromFile(c.config.Path.procFilePath("sys/net/netfilter/nf_conntrack_max")) | ||||
| 	if err != nil { | ||||
| 		return c.handleErr(err) | ||||
| 	} | ||||
| 	ch <- prometheus.MustNewConstMetric( | ||||
| 		c.limit, prometheus.GaugeValue, float64(value)) | ||||
| 
 | ||||
| 	conntrackStats, err := getConntrackStatistics() | ||||
| 	conntrackStats, err := getConntrackStatistics(c.config) | ||||
| 	if err != nil { | ||||
| 		return c.handleErr(err) | ||||
| 	} | ||||
|  | @ -162,10 +162,10 @@ func (c *conntrackCollector) handleErr(err error) error { | |||
| 	return fmt.Errorf("failed to retrieve conntrack stats: %w", err) | ||||
| } | ||||
| 
 | ||||
| func getConntrackStatistics() (*conntrackStatistics, error) { | ||||
| func getConntrackStatistics(config NodeCollectorConfig) (*conntrackStatistics, error) { | ||||
| 	c := conntrackStatistics{} | ||||
| 
 | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -57,13 +57,11 @@ type statCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewCPUCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("cpu", defaultEnabled, NewCPUCollector) | ||||
| } | ||||
| 
 | ||||
| // NewCPUCollector returns a new Collector exposing CPU stats.
 | ||||
| func NewCPUCollector(logger log.Logger) (Collector, error) { | ||||
| func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &statCollector{ | ||||
| 		cpu:    nodeCPUSecondsDesc, | ||||
| 		logger: logger, | ||||
|  |  | |||
|  | @ -82,13 +82,11 @@ type statCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewStatCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("cpu", defaultEnabled, NewStatCollector) | ||||
| } | ||||
| 
 | ||||
| // NewStatCollector returns a new Collector exposing CPU stats.
 | ||||
| func NewStatCollector(logger log.Logger) (Collector, error) { | ||||
| func NewStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &statCollector{ | ||||
| 		cpu:    nodeCPUSecondsDesc, | ||||
| 		logger: logger, | ||||
|  |  | |||
|  | @ -89,13 +89,11 @@ type statCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewStatCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("cpu", defaultEnabled, NewStatCollector) | ||||
| } | ||||
| 
 | ||||
| // NewStatCollector returns a new Collector exposing CPU stats.
 | ||||
| func NewStatCollector(logger log.Logger) (Collector, error) { | ||||
| func NewStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &statCollector{ | ||||
| 		cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, | ||||
| 		temp: typedDesc{prometheus.NewDesc( | ||||
|  |  | |||
|  | @ -51,7 +51,7 @@ type cpuCollector struct { | |||
| 	cpuFlagsIncludeRegexp *regexp.Regexp | ||||
| 	cpuBugsIncludeRegexp  *regexp.Regexp | ||||
| 
 | ||||
| 	config CPUConfig | ||||
| 	config NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| // Idle jump back limit in seconds.
 | ||||
|  | @ -69,20 +69,17 @@ type CPUConfig struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cpuConfig := config.(CPUConfig) | ||||
| 		return NewCPUCollector(cpuConfig, logger) | ||||
| 	}) | ||||
| 	registerCollector("cpu", defaultEnabled, NewCPUCollector) | ||||
| } | ||||
| 
 | ||||
| // NewCPUCollector returns a new Collector exposing kernel/system statistics.
 | ||||
| func NewCPUCollector(config CPUConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	sysfs, err := sysfs.NewFS(*sysPath) | ||||
| 	sysfs, err := sysfs.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  | @ -138,7 +135,7 @@ func NewCPUCollector(config CPUConfig, logger log.Logger) (Collector, error) { | |||
| 		cpuStats:     make(map[int64]procfs.CPUStat), | ||||
| 		config:       config, | ||||
| 	} | ||||
| 	err = c.compileIncludeFlags(c.config.FlagsInclude, c.config.BugsInclude) | ||||
| 	err = c.compileIncludeFlags(c.config.CPU.FlagsInclude, c.config.CPU.BugsInclude) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("fail to compile --collector.cpu.info.flags-include and --collector.cpu.info.bugs-include, the values of them must be regular expressions: %w", err) | ||||
| 	} | ||||
|  | @ -146,8 +143,8 @@ func NewCPUCollector(config CPUConfig, logger log.Logger) (Collector, error) { | |||
| } | ||||
| 
 | ||||
| func (c *cpuCollector) compileIncludeFlags(flagsIncludeFlag, bugsIncludeFlag *string) error { | ||||
| 	if (*flagsIncludeFlag != "" || *bugsIncludeFlag != "") && !*c.config.EnableCPUInfo { | ||||
| 		*c.config.EnableCPUInfo = true | ||||
| 	if (*flagsIncludeFlag != "" || *bugsIncludeFlag != "") && !*c.config.CPU.EnableCPUInfo { | ||||
| 		*c.config.CPU.EnableCPUInfo = true | ||||
| 		level.Info(c.logger).Log("msg", "--collector.cpu.info has been set to `true` because you set the following flags, like --collector.cpu.info.flags-include and --collector.cpu.info.bugs-include") | ||||
| 	} | ||||
| 
 | ||||
|  | @ -169,7 +166,7 @@ func (c *cpuCollector) compileIncludeFlags(flagsIncludeFlag, bugsIncludeFlag *st | |||
| 
 | ||||
| // Update implements Collector and exposes cpu related metrics from /proc/stat and /sys/.../cpu/.
 | ||||
| func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	if *c.config.EnableCPUInfo { | ||||
| 	if *c.config.CPU.EnableCPUInfo { | ||||
| 		if err := c.updateInfo(ch); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | @ -180,7 +177,7 @@ func (c *cpuCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 	if c.isolatedCpus != nil { | ||||
| 		c.updateIsolated(ch) | ||||
| 	} | ||||
| 	return c.updateThermalThrottle(ch) | ||||
| 	return c.updateThermalThrottle(c.config, ch) | ||||
| } | ||||
| 
 | ||||
| // updateInfo reads /proc/cpuinfo
 | ||||
|  | @ -237,8 +234,8 @@ func updateFieldInfo(valueList []string, filter *regexp.Regexp, desc *prometheus | |||
| } | ||||
| 
 | ||||
| // updateThermalThrottle reads /sys/devices/system/cpu/cpu* and expose thermal throttle statistics.
 | ||||
| func (c *cpuCollector) updateThermalThrottle(ch chan<- prometheus.Metric) error { | ||||
| 	cpus, err := filepath.Glob(sysFilePath("devices/system/cpu/cpu[0-9]*")) | ||||
| func (c *cpuCollector) updateThermalThrottle(config NodeCollectorConfig, ch chan<- prometheus.Metric) error { | ||||
| 	cpus, err := filepath.Glob(config.Path.sysFilePath("devices/system/cpu/cpu[0-9]*")) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | @ -345,7 +342,7 @@ func (c *cpuCollector) updateStat(ch chan<- prometheus.Metric) error { | |||
| 		ch <- prometheus.MustNewConstMetric(c.cpu, prometheus.CounterValue, cpuStat.SoftIRQ, cpuNum, "softirq") | ||||
| 		ch <- prometheus.MustNewConstMetric(c.cpu, prometheus.CounterValue, cpuStat.Steal, cpuNum, "steal") | ||||
| 
 | ||||
| 		if *c.config.EnableCPUGuest { | ||||
| 		if *c.config.CPU.EnableCPUGuest { | ||||
| 			// Guest CPU is also accounted for in cpuStat.User and cpuStat.Nice, expose these as separate metrics.
 | ||||
| 			ch <- prometheus.MustNewConstMetric(c.cpuGuest, prometheus.CounterValue, cpuStat.Guest, cpuNum, "user") | ||||
| 			ch <- prometheus.MustNewConstMetric(c.cpuGuest, prometheus.CounterValue, cpuStat.GuestNice, cpuNum, "nice") | ||||
|  |  | |||
|  | @ -218,13 +218,11 @@ type statCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewStatCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("cpu", defaultEnabled, NewStatCollector) | ||||
| } | ||||
| 
 | ||||
| // NewStatCollector returns a new Collector exposing CPU stats.
 | ||||
| func NewStatCollector(logger log.Logger) (Collector, error) { | ||||
| func NewStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &statCollector{ | ||||
| 		cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, | ||||
| 		temp: typedDesc{prometheus.NewDesc( | ||||
|  |  | |||
|  | @ -49,9 +49,7 @@ type cpuCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewCPUCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("cpu", defaultEnabled, NewCPUCollector) | ||||
| } | ||||
| 
 | ||||
| func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
|  |  | |||
|  | @ -33,12 +33,10 @@ type cpuCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewCPUCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("cpu", defaultEnabled, NewCpuCollector) | ||||
| } | ||||
| 
 | ||||
| func NewCpuCollector(logger log.Logger) (Collector, error) { | ||||
| func NewCpuCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &cpuCollector{ | ||||
| 		cpu:    typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, | ||||
| 		logger: logger, | ||||
|  |  | |||
|  | @ -34,20 +34,20 @@ var ( | |||
| 	) | ||||
| ) | ||||
| 
 | ||||
| type cpuVulnerabilitiesCollector struct{} | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector(cpuVulerabilitiesCollector, defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewVulnerabilitySysfsCollector(logger) | ||||
| 	}) | ||||
| type cpuVulnerabilitiesCollector struct { | ||||
| 	config NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func NewVulnerabilitySysfsCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &cpuVulnerabilitiesCollector{}, nil | ||||
| func init() { | ||||
| 	registerCollector(cpuVulerabilitiesCollector, defaultDisabled, NewVulnerabilitySysfsCollector) | ||||
| } | ||||
| 
 | ||||
| func NewVulnerabilitySysfsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &cpuVulnerabilitiesCollector{config}, nil | ||||
| } | ||||
| 
 | ||||
| func (v *cpuVulnerabilitiesCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| 	fs, err := sysfs.NewFS(*v.config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -31,14 +31,12 @@ type cpuFreqCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpufreq", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewCPUFreqCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("cpufreq", defaultEnabled, NewCPUFreqCollector) | ||||
| } | ||||
| 
 | ||||
| // NewCPUFreqCollector returns a new Collector exposing kernel/system statistics.
 | ||||
| func NewCPUFreqCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| func NewCPUFreqCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -33,12 +33,10 @@ type cpuFreqCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpufreq", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewCPUFreqCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("cpufreq", defaultEnabled, NewCPUFreqCollector) | ||||
| } | ||||
| 
 | ||||
| func NewCpuFreqCollector(logger log.Logger) (Collector, error) { | ||||
| func NewCpuFreqCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &cpuFreqCollector{ | ||||
| 		logger: logger, | ||||
| 	}, nil | ||||
|  |  | |||
|  | @ -102,13 +102,11 @@ type devstatCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("devstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewDevstatCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("devstat", defaultDisabled,NewDevstatCollector) | ||||
| } | ||||
| 
 | ||||
| // NewDevstatCollector returns a new Collector exposing Device stats.
 | ||||
| func NewDevstatCollector(logger log.Logger) (Collector, error) { | ||||
| func NewDevstatCollector(config NodeCollectorConfiglogger log.Logger) (Collector, error) { | ||||
| 	return &devstatCollector{ | ||||
| 		bytesDesc: prometheus.NewDesc( | ||||
| 			prometheus.BuildFQName(namespace, devstatSubsystem, "bytes_total"), | ||||
|  |  | |||
|  | @ -47,9 +47,7 @@ type devstatCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("devstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewDevstatCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("devstat", defaultDisabled, NewDevstatCollector) | ||||
| } | ||||
| 
 | ||||
| // NewDevstatCollector returns a new Collector exposing Device stats.
 | ||||
|  |  | |||
|  | @ -39,17 +39,14 @@ type diskstatsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(DiskstatsDeviceFilterConfig) | ||||
| 		return NewDiskstatsCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) | ||||
| } | ||||
| 
 | ||||
| // NewDiskstatsCollector returns a new Collector exposing disk device stats.
 | ||||
| func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger) (Collector, error) { | ||||
| func NewDiskstatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	var diskLabelNames = []string{"device"} | ||||
| 
 | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(config, logger) | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(config.DiskstatsDeviceFilter, logger) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to parse device filter flags: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -86,26 +86,24 @@ type diskstatsCollector struct { | |||
| 	deviceMapperInfoDesc    typedFactorDesc | ||||
| 	ataDescs                map[string]typedFactorDesc | ||||
| 	logger                  log.Logger | ||||
| 	getUdevDeviceProperties func(uint32, uint32) (udevInfo, error) | ||||
| 	getUdevDeviceProperties func(NodeCollectorConfig, uint32, uint32) (udevInfo, error) | ||||
| 	config                  NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(DiskstatsDeviceFilterConfig) | ||||
| 		return NewDiskstatsCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) | ||||
| } | ||||
| 
 | ||||
| // NewDiskstatsCollector returns a new Collector exposing disk device stats.
 | ||||
| // Docs from https://www.kernel.org/doc/Documentation/iostats.txt
 | ||||
| func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger) (Collector, error) { | ||||
| func NewDiskstatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	var diskLabelNames = []string{"device"} | ||||
| 	fs, err := blockdevice.NewFS(*procPath, *sysPath) | ||||
| 	fs, err := blockdevice.NewFS(*config.Path.ProcPath, *config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(config, logger) | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(config.DiskstatsDeviceFilter, logger) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to parse device filter flags: %w", err) | ||||
| 	} | ||||
|  | @ -261,11 +259,12 @@ func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger | |||
| 			}, | ||||
| 		}, | ||||
| 		logger: logger, | ||||
| 		config: config, | ||||
| 	} | ||||
| 
 | ||||
| 	// Only enable getting device properties from udev if the directory is readable.
 | ||||
| 	if stat, err := os.Stat(*udevDataPath); err != nil || !stat.IsDir() { | ||||
| 		level.Error(logger).Log("msg", "Failed to open directory, disabling udev device properties", "path", *udevDataPath) | ||||
| 	if stat, err := os.Stat(*config.Path.UdevDataPath); err != nil || !stat.IsDir() { | ||||
| 		level.Error(logger).Log("msg", "Failed to open directory, disabling udev device properties", "path", *config.Path.UdevDataPath) | ||||
| 	} else { | ||||
| 		collector.getUdevDeviceProperties = getUdevDeviceProperties | ||||
| 	} | ||||
|  | @ -285,7 +284,7 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		info, err := getUdevDeviceProperties(stats.MajorNumber, stats.MinorNumber) | ||||
| 		info, err := getUdevDeviceProperties(c.config, stats.MajorNumber, stats.MinorNumber) | ||||
| 		if err != nil { | ||||
| 			level.Debug(c.logger).Log("msg", "Failed to parse udev info", "err", err) | ||||
| 		} | ||||
|  | @ -373,8 +372,8 @@ func (c *diskstatsCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func getUdevDeviceProperties(major, minor uint32) (udevInfo, error) { | ||||
| 	filename := udevDataFilePath(fmt.Sprintf("b%d:%d", major, minor)) | ||||
| func getUdevDeviceProperties(config NodeCollectorConfig, major, minor uint32) (udevInfo, error) { | ||||
| 	filename := config.Path.udevDataFilePath(fmt.Sprintf("b%d:%d", major, minor)) | ||||
| 
 | ||||
| 	data, err := os.Open(filename) | ||||
| 	if err != nil { | ||||
|  |  | |||
|  | @ -45,15 +45,12 @@ type diskstatsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(DiskstatsDeviceFilterConfig) | ||||
| 		return NewDiskstatsCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) | ||||
| } | ||||
| 
 | ||||
| // NewDiskstatsCollector returns a new Collector exposing disk device stats.
 | ||||
| func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger) (Collector, error) { | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(config, logger) | ||||
| func NewDiskstatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(config.DiskstatsDeviceFilter, logger) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to parse device filter flags: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -56,15 +56,12 @@ type diskstatsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(DiskstatsDeviceFilterConfig) | ||||
| 		return NewDiskstatsCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) | ||||
| } | ||||
| 
 | ||||
| // NewDiskstatsCollector returns a new Collector exposing disk device stats.
 | ||||
| func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger) (Collector, error) { | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(config, logger) | ||||
| func NewDiskstatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(config.DiskstatsDeviceFilter, logger) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to parse device filter flags: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -34,14 +34,12 @@ type dmiCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("dmi", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewDMICollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("dmi", defaultEnabled, NewDMICollector) | ||||
| } | ||||
| 
 | ||||
| // NewDMICollector returns a new Collector exposing DMI information.
 | ||||
| func NewDMICollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| func NewDMICollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -80,15 +80,14 @@ type drbdCollector struct { | |||
| 	stringPair map[string]drbdStringPairMetric | ||||
| 	connected  *prometheus.Desc | ||||
| 	logger     log.Logger | ||||
| 	config     NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("drbd", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return newDRBDCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("drbd", defaultDisabled, newDRBDCollector) | ||||
| } | ||||
| 
 | ||||
| func newDRBDCollector(logger log.Logger) (Collector, error) { | ||||
| func newDRBDCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &drbdCollector{ | ||||
| 		numerical: map[string]drbdNumericalMetric{ | ||||
| 			"ns": newDRBDNumericalMetric( | ||||
|  | @ -185,11 +184,12 @@ func newDRBDCollector(logger log.Logger) (Collector, error) { | |||
| 			nil, | ||||
| 		), | ||||
| 		logger: logger, | ||||
| 		config: config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func (c *drbdCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	statsFile := procFilePath("drbd") | ||||
| 	statsFile := c.config.Path.procFilePath("drbd") | ||||
| 	file, err := os.Open(statsFile) | ||||
| 	if err != nil { | ||||
| 		if errors.Is(err, os.ErrNotExist) { | ||||
|  |  | |||
|  | @ -42,14 +42,12 @@ type drmCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("drm", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewDrmCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("drm", defaultDisabled, NewDrmCollector) | ||||
| } | ||||
| 
 | ||||
| // NewDrmCollector returns a new Collector exposing /sys/class/drm/card?/device stats.
 | ||||
| func NewDrmCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| func NewDrmCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -40,16 +40,15 @@ type edacCollector struct { | |||
| 	csRowCECount *prometheus.Desc | ||||
| 	csRowUECount *prometheus.Desc | ||||
| 	logger       log.Logger | ||||
| 	config       NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("edac", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewEdacCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("edac", defaultEnabled, NewEdacCollector) | ||||
| } | ||||
| 
 | ||||
| // NewEdacCollector returns a new Collector exposing edac stats.
 | ||||
| func NewEdacCollector(logger log.Logger) (Collector, error) { | ||||
| func NewEdacCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &edacCollector{ | ||||
| 		ceCount: prometheus.NewDesc( | ||||
| 			prometheus.BuildFQName(namespace, edacSubsystem, "correctable_errors_total"), | ||||
|  | @ -72,11 +71,12 @@ func NewEdacCollector(logger log.Logger) (Collector, error) { | |||
| 			[]string{"controller", "csrow"}, nil, | ||||
| 		), | ||||
| 		logger: logger, | ||||
| 		config: config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func (c *edacCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	memControllers, err := filepath.Glob(sysFilePath("devices/system/edac/mc/mc[0-9]*")) | ||||
| 	memControllers, err := filepath.Glob(c.config.Path.sysFilePath("devices/system/edac/mc/mc[0-9]*")) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  |  | |||
|  | @ -32,14 +32,12 @@ type entropyCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("entropy", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewEntropyCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("entropy", defaultEnabled, NewEntropyCollector) | ||||
| } | ||||
| 
 | ||||
| // NewEntropyCollector returns a new Collector exposing entropy stats.
 | ||||
| func NewEntropyCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| func NewEntropyCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -87,8 +87,8 @@ type EthtoolConfig struct { | |||
| // makeEthtoolCollector is the internal constructor for EthtoolCollector.
 | ||||
| // This allows NewEthtoolTestCollector to override its .ethtool interface
 | ||||
| // for testing.
 | ||||
| func makeEthtoolCollector(config EthtoolConfig, logger log.Logger) (*ethtoolCollector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| func makeEthtoolCollector(config NodeCollectorConfig, logger log.Logger) (*ethtoolCollector, error) { | ||||
| 	fs, err := sysfs.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  | @ -102,8 +102,8 @@ func makeEthtoolCollector(config EthtoolConfig, logger log.Logger) (*ethtoolColl | |||
| 	return ðtoolCollector{ | ||||
| 		fs:             fs, | ||||
| 		ethtool:        ðtoolLibrary{e}, | ||||
| 		deviceFilter:   newDeviceFilter(*config.DeviceExclude, *config.DeviceInclude), | ||||
| 		metricsPattern: regexp.MustCompile(*config.IncludedMetrics), | ||||
| 		deviceFilter:   newDeviceFilter(*config.Ethtool.DeviceExclude, *config.Ethtool.DeviceInclude), | ||||
| 		metricsPattern: regexp.MustCompile(*config.Ethtool.IncludedMetrics), | ||||
| 		logger:         logger, | ||||
| 		entries: map[string]*prometheus.Desc{ | ||||
| 			"rx_bytes": prometheus.NewDesc( | ||||
|  | @ -203,10 +203,7 @@ func makeEthtoolCollector(config EthtoolConfig, logger log.Logger) (*ethtoolColl | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("ethtool", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(EthtoolConfig) | ||||
| 		return NewEthtoolCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("ethtool", defaultDisabled, NewEthtoolCollector) | ||||
| } | ||||
| 
 | ||||
| // Generate the fully-qualified metric name for the ethool metric.
 | ||||
|  | @ -218,7 +215,7 @@ func buildEthtoolFQName(metric string) string { | |||
| } | ||||
| 
 | ||||
| // NewEthtoolCollector returns a new Collector exposing ethtool stats.
 | ||||
| func NewEthtoolCollector(config EthtoolConfig, logger log.Logger) (Collector, error) { | ||||
| func NewEthtoolCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return makeEthtoolCollector(config, logger) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,6 +23,7 @@ import ( | |||
| 	"syscall" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/docker/cli/cli/config" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
| 	"github.com/prometheus/client_golang/prometheus/testutil" | ||||
|  | @ -365,7 +366,7 @@ node_network_supported_speed_bytes{device="eth0",duplex="full",mode="10baseT"} 1 | |||
| node_network_supported_speed_bytes{device="eth0",duplex="half",mode="100baseT"} 1.25e+07 | ||||
| node_network_supported_speed_bytes{device="eth0",duplex="half",mode="10baseT"} 1.25e+06 | ||||
| ` | ||||
| 	*sysPath = "fixtures/sys" | ||||
| 	*config.Path.SysPath = "fixtures/sys" | ||||
| 
 | ||||
| 	config := NodeCollectorConfig{} | ||||
| 	logger := log.NewLogfmtLogger(os.Stderr) | ||||
|  |  | |||
|  | @ -28,13 +28,11 @@ type execCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("exec", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewExecCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("exec", defaultEnabled, NewExecCollector) | ||||
| } | ||||
| 
 | ||||
| // NewExecCollector returns a new Collector exposing system execution statistics.
 | ||||
| func NewExecCollector(logger log.Logger) (Collector, error) { | ||||
| func NewExecCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	// From sys/vm/vm_meter.c:
 | ||||
| 	// All are of type CTLTYPE_UINT.
 | ||||
| 	//
 | ||||
|  |  | |||
|  | @ -36,17 +36,15 @@ type fibrechannelCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("fibrechannel", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewFibreChannelCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("fibrechannel", defaultEnabled, NewFibreChannelCollector) | ||||
| } | ||||
| 
 | ||||
| // NewFibreChannelCollector returns a new Collector exposing FibreChannel stats.
 | ||||
| func NewFibreChannelCollector(logger log.Logger) (Collector, error) { | ||||
| func NewFibreChannelCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	var i fibrechannelCollector | ||||
| 	var err error | ||||
| 
 | ||||
| 	i.fs, err = sysfs.NewFS(*sysPath) | ||||
| 	i.fs, err = sysfs.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -33,21 +33,20 @@ const ( | |||
| 
 | ||||
| type fileFDStatCollector struct { | ||||
| 	logger log.Logger | ||||
| 	config NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector(fileFDStatSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewFileFDStatCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector(fileFDStatSubsystem, defaultEnabled, NewFileFDStatCollector) | ||||
| } | ||||
| 
 | ||||
| // NewFileFDStatCollector returns a new Collector exposing file-nr stats.
 | ||||
| func NewFileFDStatCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &fileFDStatCollector{logger}, nil | ||||
| func NewFileFDStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &fileFDStatCollector{logger, config}, nil | ||||
| } | ||||
| 
 | ||||
| func (c *fileFDStatCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	fileFDStat, err := parseFileFDStats(procFilePath("sys/fs/file-nr")) | ||||
| 	fileFDStat, err := parseFileFDStats(c.config.Path.procFilePath("sys/fs/file-nr")) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("couldn't get file-nr: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -47,7 +47,7 @@ type filesystemCollector struct { | |||
| 	filesDesc, filesFreeDesc      *prometheus.Desc | ||||
| 	roDesc, deviceErrorDesc       *prometheus.Desc | ||||
| 	logger                        log.Logger | ||||
| 	config                        FilesystemConfig | ||||
| 	config                        NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| type filesystemLabels struct { | ||||
|  | @ -70,46 +70,43 @@ type FilesystemConfig struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("filesystem", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(FilesystemConfig) | ||||
| 		return NewFilesystemCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("filesystem", defaultEnabled, NewFilesystemCollector) | ||||
| } | ||||
| 
 | ||||
| // NewFilesystemCollector returns a new Collector exposing filesystems stats.
 | ||||
| func NewFilesystemCollector(config FilesystemConfig, logger log.Logger) (Collector, error) { | ||||
| 	if *config.OldMountPointsExcluded != "" { | ||||
| func NewFilesystemCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	if *config.Filesystem.OldMountPointsExcluded != "" { | ||||
| 		if !mountPointsExcludeSet { | ||||
| 			level.Warn(logger).Log("msg", "--collector.filesystem.ignored-mount-points is DEPRECATED and will be removed in 2.0.0, use --collector.filesystem.mount-points-exclude") | ||||
| 			*config.MountPointsExclude = *config.OldMountPointsExcluded | ||||
| 			*config.Filesystem.MountPointsExclude = *config.Filesystem.OldMountPointsExcluded | ||||
| 		} else { | ||||
| 			return nil, errors.New("--collector.filesystem.ignored-mount-points and --collector.filesystem.mount-points-exclude are mutually exclusive") | ||||
| 		} | ||||
| 	} | ||||
| 	if *config.MountPointsExclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.mount-points-exclude", "flag", *config.MountPointsExclude) | ||||
| 	if *config.Filesystem.MountPointsExclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.mount-points-exclude", "flag", *config.Filesystem.MountPointsExclude) | ||||
| 	} else { | ||||
| 		*config.MountPointsExclude = defMountPointsExcluded | ||||
| 		*config.Filesystem.MountPointsExclude = defMountPointsExcluded | ||||
| 	} | ||||
| 
 | ||||
| 	if *config.OldFSTypesExcluded != "" { | ||||
| 	if *config.Filesystem.OldFSTypesExcluded != "" { | ||||
| 		if !fsTypesExcludeSet { | ||||
| 			level.Warn(logger).Log("msg", "--collector.filesystem.ignored-fs-types is DEPRECATED and will be removed in 2.0.0, use --collector.filesystem.fs-types-exclude") | ||||
| 			*config.FSTypesExclude = *config.OldFSTypesExcluded | ||||
| 			*config.Filesystem.FSTypesExclude = *config.Filesystem.OldFSTypesExcluded | ||||
| 		} else { | ||||
| 			return nil, errors.New("--collector.filesystem.ignored-fs-types and --collector.filesystem.fs-types-exclude are mutually exclusive") | ||||
| 		} | ||||
| 	} | ||||
| 	if *config.FSTypesExclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.fs-types-exclude", "flag", *config.FSTypesExclude) | ||||
| 	if *config.Filesystem.FSTypesExclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.fs-types-exclude", "flag", *config.Filesystem.FSTypesExclude) | ||||
| 
 | ||||
| 	} else { | ||||
| 		*config.FSTypesExclude = defFSTypesExcluded | ||||
| 		*config.Filesystem.FSTypesExclude = defFSTypesExcluded | ||||
| 	} | ||||
| 
 | ||||
| 	subsystem := "filesystem" | ||||
| 	mountPointPattern := regexp.MustCompile(*config.MountPointsExclude) | ||||
| 	filesystemsTypesPattern := regexp.MustCompile(*config.FSTypesExclude) | ||||
| 	mountPointPattern := regexp.MustCompile(*config.Filesystem.MountPointsExclude) | ||||
| 	filesystemsTypesPattern := regexp.MustCompile(*config.Filesystem.FSTypesExclude) | ||||
| 
 | ||||
| 	sizeDesc := prometheus.NewDesc( | ||||
| 		prometheus.BuildFQName(namespace, subsystem, "size_bytes"), | ||||
|  |  | |||
|  | @ -41,7 +41,7 @@ var stuckMountsMtx = &sync.Mutex{} | |||
| 
 | ||||
| // GetStats returns filesystem stats.
 | ||||
| func (c *filesystemCollector) GetStats() ([]filesystemStats, error) { | ||||
| 	mps, err := mountPointDetails(c.logger) | ||||
| 	mps, err := mountPointDetails(c.config, c.logger) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | @ -50,7 +50,7 @@ func (c *filesystemCollector) GetStats() ([]filesystemStats, error) { | |||
| 	statChan := make(chan filesystemStats) | ||||
| 	wg := sync.WaitGroup{} | ||||
| 
 | ||||
| 	workerCount := *c.config.StatWorkerCount | ||||
| 	workerCount := *c.config.Filesystem.StatWorkerCount | ||||
| 	if workerCount < 1 { | ||||
| 		workerCount = 1 | ||||
| 	} | ||||
|  | @ -103,10 +103,10 @@ func (c *filesystemCollector) GetStats() ([]filesystemStats, error) { | |||
| 
 | ||||
| func (c *filesystemCollector) processStat(labels filesystemLabels) filesystemStats { | ||||
| 	success := make(chan struct{}) | ||||
| 	go stuckMountWatcher(c.config.MountTimeout, labels.mountPoint, success, c.logger) | ||||
| 	go stuckMountWatcher(c.config.Filesystem.MountTimeout, labels.mountPoint, success, c.logger) | ||||
| 
 | ||||
| 	buf := new(unix.Statfs_t) | ||||
| 	err := unix.Statfs(rootfsFilePath(labels.mountPoint), buf) | ||||
| 	err := unix.Statfs(c.config.Path.rootfsFilePath(labels.mountPoint), buf) | ||||
| 	stuckMountsMtx.Lock() | ||||
| 	close(success) | ||||
| 
 | ||||
|  | @ -118,7 +118,7 @@ func (c *filesystemCollector) processStat(labels filesystemLabels) filesystemSta | |||
| 	stuckMountsMtx.Unlock() | ||||
| 
 | ||||
| 	if err != nil { | ||||
| 		level.Debug(c.logger).Log("msg", "Error on statfs() system call", "rootfs", rootfsFilePath(labels.mountPoint), "err", err) | ||||
| 		level.Debug(c.logger).Log("msg", "Error on statfs() system call", "rootfs", c.config.Path.rootfsFilePath(labels.mountPoint), "err", err) | ||||
| 		return filesystemStats{ | ||||
| 			labels:      labels, | ||||
| 			deviceError: 1, | ||||
|  | @ -166,22 +166,22 @@ func stuckMountWatcher(mountTimeout *time.Duration, mountPoint string, success c | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| func mountPointDetails(logger log.Logger) ([]filesystemLabels, error) { | ||||
| 	file, err := os.Open(procFilePath("1/mounts")) | ||||
| func mountPointDetails(config NodeCollectorConfig, logger log.Logger) ([]filesystemLabels, error) { | ||||
| 	file, err := os.Open(config.Path.procFilePath("1/mounts")) | ||||
| 	if errors.Is(err, os.ErrNotExist) { | ||||
| 		// Fallback to `/proc/mounts` if `/proc/1/mounts` is missing due hidepid.
 | ||||
| 		level.Debug(logger).Log("msg", "Reading root mounts failed, falling back to system mounts", "err", err) | ||||
| 		file, err = os.Open(procFilePath("mounts")) | ||||
| 		file, err = os.Open(config.Path.procFilePath("mounts")) | ||||
| 	} | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	defer file.Close() | ||||
| 
 | ||||
| 	return parseFilesystemLabels(file) | ||||
| 	return parseFilesystemLabels(config, file) | ||||
| } | ||||
| 
 | ||||
| func parseFilesystemLabels(r io.Reader) ([]filesystemLabels, error) { | ||||
| func parseFilesystemLabels(config NodeCollectorConfig, r io.Reader) ([]filesystemLabels, error) { | ||||
| 	var filesystems []filesystemLabels | ||||
| 
 | ||||
| 	scanner := bufio.NewScanner(r) | ||||
|  | @ -199,7 +199,7 @@ func parseFilesystemLabels(r io.Reader) ([]filesystemLabels, error) { | |||
| 
 | ||||
| 		filesystems = append(filesystems, filesystemLabels{ | ||||
| 			device:     parts[0], | ||||
| 			mountPoint: rootfsStripPrefix(parts[1]), | ||||
| 			mountPoint: config.Path.rootfsStripPrefix(parts[1]), | ||||
| 			fsType:     parts[2], | ||||
| 			options:    parts[3], | ||||
| 		}) | ||||
|  |  | |||
|  | @ -43,15 +43,13 @@ var ( | |||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("hwmon", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(HwMonConfig) | ||||
| 		return NewHwMonCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("hwmon", defaultEnabled, NewHwMonCollector) | ||||
| } | ||||
| 
 | ||||
| type hwMonCollector struct { | ||||
| 	deviceFilter deviceFilter | ||||
| 	logger       log.Logger | ||||
| 	config       NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| type HwMonConfig struct { | ||||
|  | @ -61,11 +59,12 @@ type HwMonConfig struct { | |||
| 
 | ||||
| // NewHwMonCollector returns a new Collector exposing /sys/class/hwmon stats
 | ||||
| // (similar to lm-sensors).
 | ||||
| func NewHwMonCollector(config HwMonConfig, logger log.Logger) (Collector, error) { | ||||
| func NewHwMonCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 
 | ||||
| 	return &hwMonCollector{ | ||||
| 		logger:       logger, | ||||
| 		deviceFilter: newDeviceFilter(*config.ChipExclude, *config.ChipInclude), | ||||
| 		deviceFilter: newDeviceFilter(*config.HwMon.ChipExclude, *config.HwMon.ChipInclude), | ||||
| 		config:       config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
|  | @ -436,7 +435,7 @@ func (c *hwMonCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 	// Step 1: scan /sys/class/hwmon, resolve all symlinks and call
 | ||||
| 	//         updatesHwmon for each folder
 | ||||
| 
 | ||||
| 	hwmonPathName := filepath.Join(sysFilePath("class"), "hwmon") | ||||
| 	hwmonPathName := filepath.Join(c.config.Path.sysFilePath("class"), "hwmon") | ||||
| 
 | ||||
| 	hwmonFiles, err := os.ReadDir(hwmonPathName) | ||||
| 	if err != nil { | ||||
|  |  | |||
|  | @ -36,17 +36,15 @@ type infinibandCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("infiniband", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewInfiniBandCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("infiniband", defaultEnabled, NewInfiniBandCollector) | ||||
| } | ||||
| 
 | ||||
| // NewInfiniBandCollector returns a new Collector exposing InfiniBand stats.
 | ||||
| func NewInfiniBandCollector(logger log.Logger) (Collector, error) { | ||||
| func NewInfiniBandCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	var i infinibandCollector | ||||
| 	var err error | ||||
| 
 | ||||
| 	i.fs, err = sysfs.NewFS(*sysPath) | ||||
| 	i.fs, err = sysfs.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -25,16 +25,15 @@ import ( | |||
| type interruptsCollector struct { | ||||
| 	desc   typedDesc | ||||
| 	logger log.Logger | ||||
| 	config NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("interrupts", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewInterruptsCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("interrupts", defaultDisabled, NewInterruptsCollector) | ||||
| } | ||||
| 
 | ||||
| // NewInterruptsCollector returns a new Collector exposing interrupts stats.
 | ||||
| func NewInterruptsCollector(logger log.Logger) (Collector, error) { | ||||
| func NewInterruptsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &interruptsCollector{ | ||||
| 		desc: typedDesc{prometheus.NewDesc( | ||||
| 			namespace+"_interrupts_total", | ||||
|  | @ -42,5 +41,6 @@ func NewInterruptsCollector(logger log.Logger) (Collector, error) { | |||
| 			interruptLabelNames, nil, | ||||
| 		), prometheus.CounterValue}, | ||||
| 		logger: logger, | ||||
| 		config: config, | ||||
| 	}, nil | ||||
| } | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ var ( | |||
| ) | ||||
| 
 | ||||
| func (c *interruptsCollector) Update(ch chan<- prometheus.Metric) (err error) { | ||||
| 	interrupts, err := getInterrupts() | ||||
| 	interrupts, err := getInterrupts(c.config) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("couldn't get interrupts: %w", err) | ||||
| 	} | ||||
|  | @ -55,8 +55,8 @@ type interrupt struct { | |||
| 	values  []string | ||||
| } | ||||
| 
 | ||||
| func getInterrupts() (map[string]interrupt, error) { | ||||
| 	file, err := os.Open(procFilePath("interrupts")) | ||||
| func getInterrupts(config NodeCollectorConfig) (map[string]interrupt, error) { | ||||
| 	file, err := os.Open(config.Path.procFilePath("interrupts")) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  |  | |||
|  | @ -66,10 +66,7 @@ var ( | |||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("ipvs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(IPVSConfig) | ||||
| 		return NewIPVSCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("ipvs", defaultEnabled, NewIPVSCollector) | ||||
| } | ||||
| 
 | ||||
| type IPVSConfig struct { | ||||
|  | @ -78,27 +75,27 @@ type IPVSConfig struct { | |||
| 
 | ||||
| // NewIPVSCollector sets up a new collector for IPVS metrics. It accepts the
 | ||||
| // "procfs" config parameter to override the default proc location (/proc).
 | ||||
| func NewIPVSCollector(config IPVSConfig, logger log.Logger) (Collector, error) { | ||||
| func NewIPVSCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return newIPVSCollector(config, logger) | ||||
| } | ||||
| 
 | ||||
| func newIPVSCollector(config IPVSConfig, logger log.Logger) (*ipvsCollector, error) { | ||||
| func newIPVSCollector(config NodeCollectorConfig, logger log.Logger) (*ipvsCollector, error) { | ||||
| 	var ( | ||||
| 		c         ipvsCollector | ||||
| 		err       error | ||||
| 		subsystem = "ipvs" | ||||
| 	) | ||||
| 
 | ||||
| 	if *config.Labels == "" { | ||||
| 		*config.Labels = strings.Join(fullIpvsBackendLabels, ",") | ||||
| 	if *config.IPVS.Labels == "" { | ||||
| 		*config.IPVS.Labels = strings.Join(fullIpvsBackendLabels, ",") | ||||
| 	} | ||||
| 
 | ||||
| 	if c.backendLabels, err = c.parseIpvsLabels(*config.Labels); err != nil { | ||||
| 	if c.backendLabels, err = c.parseIpvsLabels(*config.IPVS.Labels); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	c.logger = logger | ||||
| 	c.fs, err = procfs.NewFS(*procPath) | ||||
| 	c.fs, err = procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -32,12 +32,11 @@ var ( | |||
| type ksmdCollector struct { | ||||
| 	metricDescs map[string]*prometheus.Desc | ||||
| 	logger      log.Logger | ||||
| 	config      NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("ksmd", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewKsmdCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("ksmd", defaultDisabled, NewKsmdCollector) | ||||
| } | ||||
| 
 | ||||
| func getCanonicalMetricName(filename string) string { | ||||
|  | @ -52,7 +51,7 @@ func getCanonicalMetricName(filename string) string { | |||
| } | ||||
| 
 | ||||
| // NewKsmdCollector returns a new Collector exposing kernel/system statistics.
 | ||||
| func NewKsmdCollector(logger log.Logger) (Collector, error) { | ||||
| func NewKsmdCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	subsystem := "ksmd" | ||||
| 	descs := make(map[string]*prometheus.Desc) | ||||
| 
 | ||||
|  | @ -61,13 +60,13 @@ func NewKsmdCollector(logger log.Logger) (Collector, error) { | |||
| 			prometheus.BuildFQName(namespace, subsystem, getCanonicalMetricName(n)), | ||||
| 			fmt.Sprintf("ksmd '%s' file.", n), nil, nil) | ||||
| 	} | ||||
| 	return &ksmdCollector{descs, logger}, nil | ||||
| 	return &ksmdCollector{descs, logger, config}, nil | ||||
| } | ||||
| 
 | ||||
| // Update implements Collector and exposes kernel and system statistics.
 | ||||
| func (c *ksmdCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	for _, n := range ksmdFiles { | ||||
| 		val, err := readUintFromFile(sysFilePath(filepath.Join("kernel/mm/ksm", n))) | ||||
| 		val, err := readUintFromFile(c.config.Path.sysFilePath(filepath.Join("kernel/mm/ksm", n))) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  |  | |||
|  | @ -27,16 +27,15 @@ import ( | |||
| 
 | ||||
| type lnstatCollector struct { | ||||
| 	logger log.Logger | ||||
| 	config NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("lnstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewLnstatCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("lnstat", defaultDisabled, NewLnstatCollector) | ||||
| } | ||||
| 
 | ||||
| func NewLnstatCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &lnstatCollector{logger}, nil | ||||
| func NewLnstatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &lnstatCollector{logger, config}, nil | ||||
| } | ||||
| 
 | ||||
| func (c *lnstatCollector) Update(ch chan<- prometheus.Metric) error { | ||||
|  | @ -44,7 +43,7 @@ func (c *lnstatCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 		subsystem = "lnstat" | ||||
| 	) | ||||
| 
 | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	fs, err := procfs.NewFS(*c.config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -28,16 +28,15 @@ import ( | |||
| type loadavgCollector struct { | ||||
| 	metric []typedDesc | ||||
| 	logger log.Logger | ||||
| 	config NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("loadavg", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewLoadavgCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("loadavg", defaultEnabled, NewLoadavgCollector) | ||||
| } | ||||
| 
 | ||||
| // NewLoadavgCollector returns a new Collector exposing load average stats.
 | ||||
| func NewLoadavgCollector(logger log.Logger) (Collector, error) { | ||||
| func NewLoadavgCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &loadavgCollector{ | ||||
| 		metric: []typedDesc{ | ||||
| 			{prometheus.NewDesc(namespace+"_load1", "1m load average.", nil, nil), prometheus.GaugeValue}, | ||||
|  | @ -45,11 +44,12 @@ func NewLoadavgCollector(logger log.Logger) (Collector, error) { | |||
| 			{prometheus.NewDesc(namespace+"_load15", "15m load average.", nil, nil), prometheus.GaugeValue}, | ||||
| 		}, | ||||
| 		logger: logger, | ||||
| 		config: config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func (c *loadavgCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	loads, err := getLoad() | ||||
| 	loads, err := getLoad(c.config) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("couldn't get load: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -24,12 +24,12 @@ import ( | |||
| ) | ||||
| 
 | ||||
| // Read loadavg from /proc.
 | ||||
| func getLoad() (loads []float64, err error) { | ||||
| 	data, err := os.ReadFile(procFilePath("loadavg")) | ||||
| func getLoad(config NodeCollectorConfig) (loads []float64, err error) { | ||||
| 	data, err := os.ReadFile(config.Path.procFilePath("loadavg")) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	loads, err = parseLoad(string(data)) | ||||
| 	loads, err = parseLoad(config, string(data)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | @ -37,11 +37,11 @@ func getLoad() (loads []float64, err error) { | |||
| } | ||||
| 
 | ||||
| // Parse /proc loadavg and return 1m, 5m and 15m.
 | ||||
| func parseLoad(data string) (loads []float64, err error) { | ||||
| func parseLoad(config NodeCollectorConfig, data string) (loads []float64, err error) { | ||||
| 	loads = make([]float64, 3) | ||||
| 	parts := strings.Fields(data) | ||||
| 	if len(parts) < 3 { | ||||
| 		return nil, fmt.Errorf("unexpected content in %s", procFilePath("loadavg")) | ||||
| 		return nil, fmt.Errorf("unexpected content in %s", config.Path.procFilePath("loadavg")) | ||||
| 	} | ||||
| 	for i, load := range parts[0:3] { | ||||
| 		loads[i], err = strconv.ParseFloat(load, 64) | ||||
|  |  | |||
|  | @ -82,13 +82,11 @@ type logindSeatEntry struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("logind", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewLogindCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("logind", defaultDisabled, NewLogindCollector) | ||||
| } | ||||
| 
 | ||||
| // NewLogindCollector returns a new Collector exposing logind statistics.
 | ||||
| func NewLogindCollector(logger log.Logger) (Collector, error) { | ||||
| func NewLogindCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &logindCollector{logger}, nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -29,17 +29,16 @@ import ( | |||
| 
 | ||||
| type mdadmCollector struct { | ||||
| 	logger log.Logger | ||||
| 	config NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("mdadm", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewMdadmCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("mdadm", defaultEnabled, NewMdadmCollector) | ||||
| } | ||||
| 
 | ||||
| // NewMdadmCollector returns a new Collector exposing raid statistics.
 | ||||
| func NewMdadmCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &mdadmCollector{logger}, nil | ||||
| func NewMdadmCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &mdadmCollector{logger, config}, nil | ||||
| } | ||||
| 
 | ||||
| var ( | ||||
|  | @ -104,7 +103,7 @@ var ( | |||
| ) | ||||
| 
 | ||||
| func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	fs, err := procfs.NewFS(*c.config.Path.ProcPath) | ||||
| 
 | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to open procfs: %w", err) | ||||
|  | @ -114,7 +113,7 @@ func (c *mdadmCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 
 | ||||
| 	if err != nil { | ||||
| 		if errors.Is(err, os.ErrNotExist) { | ||||
| 			level.Debug(c.logger).Log("msg", "Not collecting mdstat, file does not exist", "file", *procPath) | ||||
| 			level.Debug(c.logger).Log("msg", "Not collecting mdstat, file does not exist", "file", *c.config.Path.ProcPath) | ||||
| 			return ErrNoData | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,17 +32,16 @@ const ( | |||
| 
 | ||||
| type meminfoCollector struct { | ||||
| 	logger log.Logger | ||||
| 	config NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("meminfo", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewMeminfoCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("meminfo", defaultEnabled, NewMeminfoCollector) | ||||
| } | ||||
| 
 | ||||
| // NewMeminfoCollector returns a new Collector exposing memory stats.
 | ||||
| func NewMeminfoCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &meminfoCollector{logger}, nil | ||||
| func NewMeminfoCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &meminfoCollector{logger, config}, nil | ||||
| } | ||||
| 
 | ||||
| // Update calls (*meminfoCollector).getMemInfo to get the platform specific
 | ||||
|  |  | |||
|  | @ -31,7 +31,7 @@ var ( | |||
| ) | ||||
| 
 | ||||
| func (c *meminfoCollector) getMemInfo() (map[string]float64, error) { | ||||
| 	file, err := os.Open(procFilePath("meminfo")) | ||||
| 	file, err := os.Open(c.config.Path.procFilePath("meminfo")) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  |  | |||
|  | @ -46,6 +46,7 @@ type meminfoMetric struct { | |||
| type meminfoNumaCollector struct { | ||||
| 	metricDescs map[string]*prometheus.Desc | ||||
| 	logger      log.Logger | ||||
| 	config      NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
|  | @ -57,11 +58,12 @@ func NewMeminfoNumaCollector(config NodeCollectorConfig, logger log.Logger) (Col | |||
| 	return &meminfoNumaCollector{ | ||||
| 		metricDescs: map[string]*prometheus.Desc{}, | ||||
| 		logger:      logger, | ||||
| 		config:      config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func (c *meminfoNumaCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	metrics, err := getMemInfoNuma() | ||||
| 	metrics, err := getMemInfoNuma(c.config) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("couldn't get NUMA meminfo: %w", err) | ||||
| 	} | ||||
|  | @ -79,12 +81,12 @@ func (c *meminfoNumaCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func getMemInfoNuma() ([]meminfoMetric, error) { | ||||
| func getMemInfoNuma(config NodeCollectorConfig) ([]meminfoMetric, error) { | ||||
| 	var ( | ||||
| 		metrics []meminfoMetric | ||||
| 	) | ||||
| 
 | ||||
| 	nodes, err := filepath.Glob(sysFilePath("devices/system/node/node[0-9]*")) | ||||
| 	nodes, err := filepath.Glob(config.Path.sysFilePath("devices/system/node/node[0-9]*")) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  |  | |||
|  | @ -37,9 +37,7 @@ type memoryCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("meminfo", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewMemoryCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("meminfo", defaultEnabled, NewMemoryCollector) | ||||
| } | ||||
| 
 | ||||
| // NewMemoryCollector returns a new Collector exposing memory stats.
 | ||||
|  |  | |||
|  | @ -107,14 +107,12 @@ type nfsDeviceIdentifier struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("mountstats", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewMountStatsCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("mountstats", defaultDisabled, NewMountStatsCollector) | ||||
| } | ||||
| 
 | ||||
| // NewMountStatsCollector returns a new Collector exposing NFS statistics.
 | ||||
| func NewMountStatsCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| func NewMountStatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -35,14 +35,11 @@ type netClassCollector struct { | |||
| 	ignoredDevicesPattern *regexp.Regexp | ||||
| 	metricDescs           map[string]*prometheus.Desc | ||||
| 	logger                log.Logger | ||||
| 	config                NetClassConfig | ||||
| 	config                NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("netclass", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(NetClassConfig) | ||||
| 		return NewNetClassCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("netclass", defaultEnabled, NewNetClassCollector) | ||||
| } | ||||
| 
 | ||||
| type NetClassConfig struct { | ||||
|  | @ -53,12 +50,12 @@ type NetClassConfig struct { | |||
| } | ||||
| 
 | ||||
| // NewNetClassCollector returns a new Collector exposing network class stats.
 | ||||
| func NewNetClassCollector(config NetClassConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| func NewNetClassCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
| 	pattern := regexp.MustCompile(*config.IgnoredDevices) | ||||
| 	pattern := regexp.MustCompile(*config.NetClass.IgnoredDevices) | ||||
| 	return &netClassCollector{ | ||||
| 		fs:                    fs, | ||||
| 		subsystem:             "network", | ||||
|  | @ -70,7 +67,7 @@ func NewNetClassCollector(config NetClassConfig, logger log.Logger) (Collector, | |||
| } | ||||
| 
 | ||||
| func (c *netClassCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	if *c.config.Netlink { | ||||
| 	if *c.config.NetClass.Netlink { | ||||
| 		return c.netClassRTNLUpdate(ch) | ||||
| 	} | ||||
| 	return c.netClassSysfsUpdate(ch) | ||||
|  | @ -126,7 +123,7 @@ func (c *netClassCollector) netClassSysfsUpdate(ch chan<- prometheus.Metric) err | |||
| 
 | ||||
| 		if ifaceInfo.Speed != nil { | ||||
| 			// Some devices return -1 if the speed is unknown.
 | ||||
| 			if *ifaceInfo.Speed >= 0 || !*c.config.InvalidSpeed { | ||||
| 			if *ifaceInfo.Speed >= 0 || !*c.config.NetClass.InvalidSpeed { | ||||
| 				speedBytes := int64(*ifaceInfo.Speed * 1000 * 1000 / 8) | ||||
| 				pushMetric(ch, c.getFieldDesc("speed_bytes"), "speed_bytes", speedBytes, prometheus.GaugeValue, ifaceInfo.Name) | ||||
| 			} | ||||
|  |  | |||
|  | @ -140,7 +140,7 @@ func (c *netClassCollector) netClassRTNLUpdate(ch chan<- prometheus.Metric) erro | |||
| 		pushMetric(ch, c.getFieldDesc("protocol_type"), "protocol_type", msg.Type, prometheus.GaugeValue, msg.Attributes.Name) | ||||
| 
 | ||||
| 		// Skip statistics if argument collector.netclass_rtnl.with-stats is false or statistics are unavailable.
 | ||||
| 		if c.config.RTNLWithStats == nil || !*c.config.RTNLWithStats || msg.Attributes.Stats64 == nil { | ||||
| 		if c.config.NetClass.RTNLWithStats == nil || !*c.config.NetClass.RTNLWithStats || msg.Attributes.Stats64 == nil { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
|  | @ -35,16 +35,13 @@ type netDevCollector struct { | |||
| 	metricDescsMutex sync.Mutex | ||||
| 	metricDescs      map[string]*prometheus.Desc | ||||
| 	logger           log.Logger | ||||
| 	config           NetDevConfig | ||||
| 	config           NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| type netDevStats map[string]map[string]uint64 | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("netdev", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(NetDevConfig) | ||||
| 		return NewNetDevCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("netdev", defaultEnabled, NewNetDevCollector) | ||||
| } | ||||
| 
 | ||||
| type NetDevConfig struct { | ||||
|  | @ -58,40 +55,40 @@ type NetDevConfig struct { | |||
| } | ||||
| 
 | ||||
| // NewNetDevCollector returns a new Collector exposing network device stats.
 | ||||
| func NewNetDevCollector(config NetDevConfig, logger log.Logger) (Collector, error) { | ||||
| 	if *config.OldDeviceInclude != "" { | ||||
| 		if *config.DeviceInclude == "" { | ||||
| func NewNetDevCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	if *config.NetDev.OldDeviceInclude != "" { | ||||
| 		if *config.NetDev.DeviceInclude == "" { | ||||
| 			level.Warn(logger).Log("msg", "--collector.netdev.device-whitelist is DEPRECATED and will be removed in 2.0.0, use --collector.netdev.device-include") | ||||
| 			*config.DeviceInclude = *config.OldDeviceInclude | ||||
| 			*config.NetDev.DeviceInclude = *config.NetDev.OldDeviceInclude | ||||
| 		} else { | ||||
| 			return nil, errors.New("--collector.netdev.device-whitelist and --collector.netdev.device-include are mutually exclusive") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if *config.OldDeviceExclude != "" { | ||||
| 		if *config.DeviceExclude == "" { | ||||
| 	if *config.NetDev.OldDeviceExclude != "" { | ||||
| 		if *config.NetDev.DeviceExclude == "" { | ||||
| 			level.Warn(logger).Log("msg", "--collector.netdev.device-blacklist is DEPRECATED and will be removed in 2.0.0, use --collector.netdev.device-exclude") | ||||
| 			*config.DeviceExclude = *config.OldDeviceExclude | ||||
| 			*config.NetDev.DeviceExclude = *config.NetDev.OldDeviceExclude | ||||
| 		} else { | ||||
| 			return nil, errors.New("--collector.netdev.device-blacklist and --collector.netdev.device-exclude are mutually exclusive") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if *config.DeviceExclude != "" && *config.DeviceInclude != "" { | ||||
| 	if *config.NetDev.DeviceExclude != "" && *config.NetDev.DeviceInclude != "" { | ||||
| 		return nil, errors.New("device-exclude & device-include are mutually exclusive") | ||||
| 	} | ||||
| 
 | ||||
| 	if *config.DeviceExclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed flag --collector.netdev.device-exclude", "flag", *netdevDeviceExclude) | ||||
| 	if *config.NetDev.DeviceExclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed flag --collector.netdev.device-exclude", "flag", *config.NetDev.DeviceExclude) | ||||
| 	} | ||||
| 
 | ||||
| 	if *config.DeviceInclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed Flag --collector.netdev.device-include", "flag", *netdevDeviceInclude) | ||||
| 	if *config.NetDev.DeviceInclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed Flag --collector.netdev.device-include", "flag", *config.NetDev.DeviceInclude) | ||||
| 	} | ||||
| 
 | ||||
| 	return &netDevCollector{ | ||||
| 		subsystem:    "network", | ||||
| 		deviceFilter: newDeviceFilter(*config.DeviceExclude, *config.DeviceInclude), | ||||
| 		deviceFilter: newDeviceFilter(*config.NetDev.DeviceExclude, *config.NetDev.DeviceInclude), | ||||
| 		metricDescs:  map[string]*prometheus.Desc{}, | ||||
| 		logger:       logger, | ||||
| 		config:       config, | ||||
|  | @ -115,12 +112,12 @@ func (c *netDevCollector) metricDesc(key string) *prometheus.Desc { | |||
| } | ||||
| 
 | ||||
| func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	netDev, err := getNetDevStats(c.config.Netlink, &c.deviceFilter, c.logger) | ||||
| 	netDev, err := getNetDevStats(c.config, c.config.NetDev.Netlink, &c.deviceFilter, c.logger) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("couldn't get netstats: %w", err) | ||||
| 	} | ||||
| 	for dev, devStats := range netDev { | ||||
| 		if !*c.config.DetailedMetrics { | ||||
| 		if !*c.config.NetDev.DetailedMetrics { | ||||
| 			legacy(devStats) | ||||
| 		} | ||||
| 		for key, value := range devStats { | ||||
|  | @ -128,7 +125,7 @@ func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 			ch <- prometheus.MustNewConstMetric(desc, prometheus.CounterValue, float64(value), dev) | ||||
| 		} | ||||
| 	} | ||||
| 	if *c.config.AddressInfo { | ||||
| 	if *c.config.NetDev.AddressInfo { | ||||
| 		interfaces, err := net.Interfaces() | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("could not get network interfaces: %w", err) | ||||
|  |  | |||
|  | @ -25,11 +25,11 @@ import ( | |||
| 	"github.com/prometheus/procfs" | ||||
| ) | ||||
| 
 | ||||
| func getNetDevStats(netDevNetlink *bool, filter *deviceFilter, logger log.Logger) (netDevStats, error) { | ||||
| func getNetDevStats(config NodeCollectorConfig, netDevNetlink *bool, filter *deviceFilter, logger log.Logger) (netDevStats, error) { | ||||
| 	if *netDevNetlink { | ||||
| 		return netlinkStats(filter, logger) | ||||
| 	} | ||||
| 	return procNetDevStats(filter, logger) | ||||
| 	return procNetDevStats(config, filter, logger) | ||||
| } | ||||
| 
 | ||||
| func netlinkStats(filter *deviceFilter, logger log.Logger) (netDevStats, error) { | ||||
|  | @ -97,10 +97,10 @@ func parseNetlinkStats(links []rtnetlink.LinkMessage, filter *deviceFilter, logg | |||
| 	return metrics | ||||
| } | ||||
| 
 | ||||
| func procNetDevStats(filter *deviceFilter, logger log.Logger) (netDevStats, error) { | ||||
| func procNetDevStats(config NodeCollectorConfig, filter *deviceFilter, logger log.Logger) (netDevStats, error) { | ||||
| 	metrics := netDevStats{} | ||||
| 
 | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return metrics, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -33,12 +33,10 @@ const ( | |||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("netisr", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewNetisrCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("netisr", defaultEnabled, NewNetisrCollector) | ||||
| } | ||||
| 
 | ||||
| func NewNetisrCollector(logger log.Logger) (Collector, error) { | ||||
| func NewNetisrCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &netisrCollector{ | ||||
| 		sysctls: []bsdSysctl{ | ||||
| 			{ | ||||
|  |  | |||
|  | @ -37,13 +37,11 @@ const ( | |||
| type netStatCollector struct { | ||||
| 	fieldPattern *regexp.Regexp | ||||
| 	logger       log.Logger | ||||
| 	config       NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector(netStatsSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(NetStatConfig) | ||||
| 		return NewNetStatCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector(netStatsSubsystem, defaultEnabled, NewNetStatCollector) | ||||
| } | ||||
| 
 | ||||
| type NetStatConfig struct { | ||||
|  | @ -52,24 +50,25 @@ type NetStatConfig struct { | |||
| 
 | ||||
| // NewNetStatCollector takes and returns
 | ||||
| // a new Collector exposing network stats.
 | ||||
| func NewNetStatCollector(config NetStatConfig, logger log.Logger) (Collector, error) { | ||||
| 	pattern := regexp.MustCompile(*config.Fields) | ||||
| func NewNetStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	pattern := regexp.MustCompile(*config.NetStat.Fields) | ||||
| 	return &netStatCollector{ | ||||
| 		fieldPattern: pattern, | ||||
| 		logger:       logger, | ||||
| 		config:       config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func (c *netStatCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	netStats, err := getNetStats(procFilePath("net/netstat")) | ||||
| 	netStats, err := getNetStats(c.config.Path.procFilePath("net/netstat")) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("couldn't get netstats: %w", err) | ||||
| 	} | ||||
| 	snmpStats, err := getNetStats(procFilePath("net/snmp")) | ||||
| 	snmpStats, err := getNetStats(c.config.Path.procFilePath("net/snmp")) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("couldn't get SNMP stats: %w", err) | ||||
| 	} | ||||
| 	snmp6Stats, err := getSNMP6Stats(procFilePath("net/snmp6")) | ||||
| 	snmp6Stats, err := getSNMP6Stats(c.config.Path.procFilePath("net/snmp6")) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("couldn't get SNMP6 stats: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -35,13 +35,11 @@ type networkRouteCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("network_route", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewNetworkRouteCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("network_route", defaultDisabled, NewNetworkRouteCollector) | ||||
| } | ||||
| 
 | ||||
| // NewNetworkRouteCollector returns a new Collector exposing systemd statistics.
 | ||||
| func NewNetworkRouteCollector(logger log.Logger) (Collector, error) { | ||||
| func NewNetworkRouteCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	const subsystem = "network" | ||||
| 
 | ||||
| 	routeInfoDesc := prometheus.NewDesc( | ||||
|  |  | |||
|  | @ -44,14 +44,12 @@ type nfsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("nfs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewNfsCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("nfs", defaultEnabled, NewNfsCollector) | ||||
| } | ||||
| 
 | ||||
| // NewNfsCollector returns a new Collector exposing NFS statistics.
 | ||||
| func NewNfsCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := nfs.NewFS(*procPath) | ||||
| func NewNfsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := nfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -36,9 +36,7 @@ type nfsdCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("nfsd", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewNFSdCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("nfsd", defaultEnabled, NewNFSdCollector) | ||||
| } | ||||
| 
 | ||||
| const ( | ||||
|  | @ -46,8 +44,8 @@ const ( | |||
| ) | ||||
| 
 | ||||
| // NewNFSdCollector returns a new Collector exposing /proc/net/rpc/nfsd statistics.
 | ||||
| func NewNFSdCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := nfs.NewFS(*procPath) | ||||
| func NewNFSdCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := nfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -41,14 +41,11 @@ var ( | |||
| type ntpCollector struct { | ||||
| 	stratum, leap, rtt, offset, reftime, rootDelay, rootDispersion, sanity typedDesc | ||||
| 	logger                                                                 log.Logger | ||||
| 	config                                                                 NTPConfig | ||||
| 	config                                                                 NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("ntp", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(NTPConfig) | ||||
| 		return NewNtpCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("ntp", defaultDisabled, NewNtpCollector) | ||||
| } | ||||
| 
 | ||||
| type NTPConfig struct { | ||||
|  | @ -65,22 +62,22 @@ type NTPConfig struct { | |||
| // Default definition of "local" is:
 | ||||
| // - collector.ntp.server address is a loopback address (or collector.ntp.server-is-mine flag is turned on)
 | ||||
| // - the server is reachable with outgoin IP_TTL = 1
 | ||||
| func NewNtpCollector(config NTPConfig, logger log.Logger) (Collector, error) { | ||||
| 	ipaddr := net.ParseIP(*config.Server) | ||||
| 	if !*config.ServerIsLocal && (ipaddr == nil || !ipaddr.IsLoopback()) { | ||||
| func NewNtpCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	ipaddr := net.ParseIP(*config.NTP.Server) | ||||
| 	if !*config.NTP.ServerIsLocal && (ipaddr == nil || !ipaddr.IsLoopback()) { | ||||
| 		return nil, fmt.Errorf("only IP address of local NTP server is valid for --collector.ntp.server") | ||||
| 	} | ||||
| 
 | ||||
| 	if *config.ProtocolVersion < 2 || *config.ProtocolVersion > 4 { | ||||
| 		return nil, fmt.Errorf("invalid NTP protocol version %d; must be 2, 3, or 4", *config.ProtocolVersion) | ||||
| 	if *config.NTP.ProtocolVersion < 2 || *config.NTP.ProtocolVersion > 4 { | ||||
| 		return nil, fmt.Errorf("invalid NTP protocol version %d; must be 2, 3, or 4", *config.NTP.ProtocolVersion) | ||||
| 	} | ||||
| 
 | ||||
| 	if *config.OffsetTolerance < 0 { | ||||
| 	if *config.NTP.OffsetTolerance < 0 { | ||||
| 		return nil, fmt.Errorf("offset tolerance must be non-negative") | ||||
| 	} | ||||
| 
 | ||||
| 	if *config.ServerPort < 1 || *config.ServerPort > 65535 { | ||||
| 		return nil, fmt.Errorf("invalid NTP port number %d; must be between 1 and 65535 inclusive", *config.ServerPort) | ||||
| 	if *config.NTP.ServerPort < 1 || *config.NTP.ServerPort > 65535 { | ||||
| 		return nil, fmt.Errorf("invalid NTP port number %d; must be between 1 and 65535 inclusive", *config.NTP.ServerPort) | ||||
| 	} | ||||
| 
 | ||||
| 	level.Warn(logger).Log("msg", "This collector is deprecated and will be removed in the next major version release.") | ||||
|  | @ -130,11 +127,11 @@ func NewNtpCollector(config NTPConfig, logger log.Logger) (Collector, error) { | |||
| } | ||||
| 
 | ||||
| func (c *ntpCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	resp, err := ntp.QueryWithOptions(*c.config.Server, ntp.QueryOptions{ | ||||
| 		Version: *c.config.ProtocolVersion, | ||||
| 		TTL:     *c.config.IPTTL, | ||||
| 	resp, err := ntp.QueryWithOptions(*c.config.NTP.Server, ntp.QueryOptions{ | ||||
| 		Version: *c.config.NTP.ProtocolVersion, | ||||
| 		TTL:     *c.config.NTP.IPTTL, | ||||
| 		Timeout: time.Second, // default `ntpdate` timeout
 | ||||
| 		Port:    *c.config.ServerPort, | ||||
| 		Port:    *c.config.NTP.ServerPort, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("couldn't get SNTP reply: %w", err) | ||||
|  | @ -159,7 +156,7 @@ func (c *ntpCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 	// Here is SNTP packet sanity check that is exposed to move burden of
 | ||||
| 	// configuration from node_exporter user to the developer.
 | ||||
| 
 | ||||
| 	maxerr := *c.config.OffsetTolerance | ||||
| 	maxerr := *c.config.NTP.OffsetTolerance | ||||
| 	leapMidnightMutex.Lock() | ||||
| 	if resp.Leap == ntp.LeapAddSecond || resp.Leap == ntp.LeapDelSecond { | ||||
| 		// state of leapMidnight is cached as leap flag is dropped right after midnight
 | ||||
|  | @ -171,7 +168,7 @@ func (c *ntpCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 	} | ||||
| 	leapMidnightMutex.Unlock() | ||||
| 
 | ||||
| 	if resp.Validate() == nil && resp.RootDistance <= *c.config.MaxDistance && resp.MinError <= maxerr { | ||||
| 	if resp.Validate() == nil && resp.RootDistance <= *c.config.NTP.MaxDistance && resp.MinError <= maxerr { | ||||
| 		ch <- c.sanity.mustNewConstMetric(1) | ||||
| 	} else { | ||||
| 		ch <- c.sanity.mustNewConstMetric(0) | ||||
|  |  | |||
|  | @ -33,14 +33,12 @@ type nvmeCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("nvme", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewNVMeCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("nvme", defaultEnabled, NewNVMeCollector) | ||||
| } | ||||
| 
 | ||||
| // NewNVMeCollector returns a new Collector exposing NVMe stats.
 | ||||
| func NewNVMeCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| func NewNVMeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -65,6 +65,7 @@ type osReleaseCollector struct { | |||
| 	osReleaseFilenames []string // all os-release file names to check
 | ||||
| 	version            float64 | ||||
| 	versionDesc        *prometheus.Desc | ||||
| 	config             NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| type Plist struct { | ||||
|  | @ -77,13 +78,11 @@ type Dict struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("os", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewOSCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("os", defaultEnabled, NewOSCollector) | ||||
| } | ||||
| 
 | ||||
| // NewOSCollector returns a new Collector exposing os-release information.
 | ||||
| func NewOSCollector(logger log.Logger) (Collector, error) { | ||||
| func NewOSCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &osReleaseCollector{ | ||||
| 		logger: logger, | ||||
| 		infoDesc: prometheus.NewDesc( | ||||
|  | @ -99,6 +98,7 @@ func NewOSCollector(logger log.Logger) (Collector, error) { | |||
| 			"Metric containing the major.minor part of the OS version.", | ||||
| 			[]string{"id", "id_like", "name"}, nil, | ||||
| 		), | ||||
| 		config: config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
|  | @ -176,7 +176,7 @@ func (c *osReleaseCollector) UpdateStruct(path string) error { | |||
| 
 | ||||
| func (c *osReleaseCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	for i, path := range c.osReleaseFilenames { | ||||
| 		err := c.UpdateStruct(*rootfsPath + path) | ||||
| 		err := c.UpdateStruct(*c.config.Path.RootfsPath + path) | ||||
| 		if err == nil { | ||||
| 			break | ||||
| 		} | ||||
|  |  | |||
|  | @ -16,40 +16,36 @@ package collector | |||
| import ( | ||||
| 	"path/filepath" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/prometheus/procfs" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	// The path of the proc filesystem.
 | ||||
| 	procPath     = kingpin.Flag("path.procfs", "procfs mountpoint.").Default(procfs.DefaultMountPoint).String() | ||||
| 	sysPath      = kingpin.Flag("path.sysfs", "sysfs mountpoint.").Default("/sys").String() | ||||
| 	rootfsPath   = kingpin.Flag("path.rootfs", "rootfs mountpoint.").Default("/").String() | ||||
| 	udevDataPath = kingpin.Flag("path.udev.data", "udev data path.").Default("/run/udev/data").String() | ||||
| ) | ||||
| 
 | ||||
| func procFilePath(name string) string { | ||||
| 	return filepath.Join(*procPath, name) | ||||
| type PathConfig struct { | ||||
| 	ProcPath     *string | ||||
| 	SysPath      *string | ||||
| 	RootfsPath   *string | ||||
| 	UdevDataPath *string | ||||
| } | ||||
| 
 | ||||
| func sysFilePath(name string) string { | ||||
| 	return filepath.Join(*sysPath, name) | ||||
| func (p *PathConfig) procFilePath(name string) string { | ||||
| 	return filepath.Join(*p.ProcPath, name) | ||||
| } | ||||
| 
 | ||||
| func rootfsFilePath(name string) string { | ||||
| 	return filepath.Join(*rootfsPath, name) | ||||
| func (p *PathConfig) sysFilePath(name string) string { | ||||
| 	return filepath.Join(*p.SysPath, name) | ||||
| } | ||||
| 
 | ||||
| func udevDataFilePath(name string) string { | ||||
| 	return filepath.Join(*udevDataPath, name) | ||||
| func (p *PathConfig) rootfsFilePath(name string) string { | ||||
| 	return filepath.Join(*p.RootfsPath, name) | ||||
| } | ||||
| 
 | ||||
| func rootfsStripPrefix(path string) string { | ||||
| 	if *rootfsPath == "/" { | ||||
| func (p *PathConfig) udevDataFilePath(name string) string { | ||||
| 	return filepath.Join(*p.UdevDataPath, name) | ||||
| } | ||||
| 
 | ||||
| func (p *PathConfig) rootfsStripPrefix(path string) string { | ||||
| 	if *p.RootfsPath == "/" { | ||||
| 		return path | ||||
| 	} | ||||
| 	stripped := strings.TrimPrefix(path, *rootfsPath) | ||||
| 	stripped := strings.TrimPrefix(path, *p.RootfsPath) | ||||
| 	if stripped == "" { | ||||
| 		return "/" | ||||
| 	} | ||||
|  |  | |||
|  | @ -25,11 +25,11 @@ func TestDefaultProcPath(t *testing.T) { | |||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	if got, want := procFilePath("somefile"), "/proc/somefile"; got != want { | ||||
| 	if got, want := c.config.Path.procFilePath("somefile"), "/proc/somefile"; got != want { | ||||
| 		t.Errorf("Expected: %s, Got: %s", want, got) | ||||
| 	} | ||||
| 
 | ||||
| 	if got, want := procFilePath("some/file"), "/proc/some/file"; got != want { | ||||
| 	if got, want := c.config.Path.procFilePath("some/file"), "/proc/some/file"; got != want { | ||||
| 		t.Errorf("Expected: %s, Got: %s", want, got) | ||||
| 	} | ||||
| } | ||||
|  | @ -39,39 +39,39 @@ func TestCustomProcPath(t *testing.T) { | |||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	if got, want := procFilePath("somefile"), "../some/place/somefile"; got != want { | ||||
| 	if got, want := c.config.Path.procFilePath("somefile"), "../some/place/somefile"; got != want { | ||||
| 		t.Errorf("Expected: %s, Got: %s", want, got) | ||||
| 	} | ||||
| 
 | ||||
| 	if got, want := procFilePath("some/file"), "../some/place/some/file"; got != want { | ||||
| 	if got, want := c.config.Path.procFilePath("some/file"), "../some/place/some/file"; got != want { | ||||
| 		t.Errorf("Expected: %s, Got: %s", want, got) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestDefaultSysPath(t *testing.T) { | ||||
| func TestDefault*config.Path.SysPath(t *testing.T) { | ||||
| 	if _, err := kingpin.CommandLine.Parse([]string{"--path.sysfs", "/sys"}); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	if got, want := sysFilePath("somefile"), "/sys/somefile"; got != want { | ||||
| 	if got, want := *config.Path.SysPath("somefile"), "/sys/somefile"; got != want { | ||||
| 		t.Errorf("Expected: %s, Got: %s", want, got) | ||||
| 	} | ||||
| 
 | ||||
| 	if got, want := sysFilePath("some/file"), "/sys/some/file"; got != want { | ||||
| 	if got, want := *config.Path.SysPath("some/file"), "/sys/some/file"; got != want { | ||||
| 		t.Errorf("Expected: %s, Got: %s", want, got) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestCustomSysPath(t *testing.T) { | ||||
| func TestCustom*config.Path.SysPath(t *testing.T) { | ||||
| 	if _, err := kingpin.CommandLine.Parse([]string{"--path.sysfs", "./../some/./place/"}); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	if got, want := sysFilePath("somefile"), "../some/place/somefile"; got != want { | ||||
| 	if got, want := *config.Path.SysPath("somefile"), "../some/place/somefile"; got != want { | ||||
| 		t.Errorf("Expected: %s, Got: %s", want, got) | ||||
| 	} | ||||
| 
 | ||||
| 	if got, want := sysFilePath("some/file"), "../some/place/some/file"; got != want { | ||||
| 	if got, want := *config.Path.SysPath("some/file"), "../some/place/some/file"; got != want { | ||||
| 		t.Errorf("Expected: %s, Got: %s", want, got) | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -34,10 +34,7 @@ const ( | |||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector(perfSubsystem, defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(PerfConfig) | ||||
| 		return NewPerfCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector(perfSubsystem, defaultDisabled, NewPerfCollector) | ||||
| } | ||||
| 
 | ||||
| type PerfConfig struct { | ||||
|  | @ -303,7 +300,7 @@ func newPerfTracepointCollector( | |||
| 
 | ||||
| // NewPerfCollector returns a new perf based collector, it creates a profiler
 | ||||
| // per CPU.
 | ||||
| func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { | ||||
| func NewPerfCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	collector := &perfCollector{ | ||||
| 		perfHwProfilers:     map[int]*perf.HardwareProfiler{}, | ||||
| 		perfSwProfilers:     map[int]*perf.SoftwareProfiler{}, | ||||
|  | @ -318,8 +315,8 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { | |||
| 		cpus []int | ||||
| 		err  error | ||||
| 	) | ||||
| 	if config.CPUs != nil && *config.CPUs != "" { | ||||
| 		cpus, err = perfCPUFlagToCPUs(*config.CPUs) | ||||
| 	if config.Perf.CPUs != nil && *config.Perf.CPUs != "" { | ||||
| 		cpus, err = perfCPUFlagToCPUs(*config.Perf.CPUs) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | @ -331,8 +328,8 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { | |||
| 	} | ||||
| 
 | ||||
| 	// First configure any tracepoints.
 | ||||
| 	if *config.Tracepoint != nil && len(*config.Tracepoint) > 0 { | ||||
| 		tracepointCollector, err := newPerfTracepointCollector(logger, *config.Tracepoint, cpus) | ||||
| 	if *config.Perf.Tracepoint != nil && len(*config.Perf.Tracepoint) > 0 { | ||||
| 		tracepointCollector, err := newPerfTracepointCollector(logger, *config.Perf.Tracepoint, cpus) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | @ -341,27 +338,27 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { | |||
| 
 | ||||
| 	// Configure perf profilers
 | ||||
| 	hardwareProfilers := perf.AllHardwareProfilers | ||||
| 	if *config.HwProfiler != nil && len(*config.HwProfiler) > 0 { | ||||
| 	if *config.Perf.HwProfiler != nil && len(*config.Perf.HwProfiler) > 0 { | ||||
| 		// hardwareProfilers = 0
 | ||||
| 		for _, hf := range *config.HwProfiler { | ||||
| 		for _, hf := range *config.Perf.HwProfiler { | ||||
| 			if v, ok := perfHardwareProfilerMap[hf]; ok { | ||||
| 				hardwareProfilers |= v | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	softwareProfilers := perf.AllSoftwareProfilers | ||||
| 	if *config.SwProfiler != nil && len(*config.SwProfiler) > 0 { | ||||
| 	if *config.Perf.SwProfiler != nil && len(*config.Perf.SwProfiler) > 0 { | ||||
| 		// softwareProfilers = 0
 | ||||
| 		for _, sf := range *config.SwProfiler { | ||||
| 		for _, sf := range *config.Perf.SwProfiler { | ||||
| 			if v, ok := perfSoftwareProfilerMap[sf]; ok { | ||||
| 				softwareProfilers |= v | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	cacheProfilers := perf.L1DataReadHitProfiler | perf.L1DataReadMissProfiler | perf.L1DataWriteHitProfiler | perf.L1InstrReadMissProfiler | perf.InstrTLBReadHitProfiler | perf.InstrTLBReadMissProfiler | perf.LLReadHitProfiler | perf.LLReadMissProfiler | perf.LLWriteHitProfiler | perf.LLWriteMissProfiler | perf.BPUReadHitProfiler | perf.BPUReadMissProfiler | ||||
| 	if *config.CaProfilerFlag != nil && len(*config.CaProfilerFlag) > 0 { | ||||
| 	if *config.Perf.CaProfilerFlag != nil && len(*config.Perf.CaProfilerFlag) > 0 { | ||||
| 		cacheProfilers = 0 | ||||
| 		for _, cf := range *config.CaProfilerFlag { | ||||
| 		for _, cf := range *config.Perf.CaProfilerFlag { | ||||
| 			if v, ok := perfCacheProfilerMap[cf]; ok { | ||||
| 				cacheProfilers |= v | ||||
| 			} | ||||
|  | @ -372,7 +369,7 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { | |||
| 	for _, cpu := range cpus { | ||||
| 		// Use -1 to profile all processes on the CPU, see:
 | ||||
| 		// man perf_event_open
 | ||||
| 		if !*config.NoHwProfiler { | ||||
| 		if !*config.Perf.NoHwProfiler { | ||||
| 			hwProf, err := perf.NewHardwareProfiler( | ||||
| 				-1, | ||||
| 				cpu, | ||||
|  | @ -388,7 +385,7 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { | |||
| 			collector.hwProfilerCPUMap[&hwProf] = cpu | ||||
| 		} | ||||
| 
 | ||||
| 		if !*config.NoSwProfiler { | ||||
| 		if !*config.Perf.NoSwProfiler { | ||||
| 			swProf, err := perf.NewSoftwareProfiler(-1, cpu, softwareProfilers) | ||||
| 			if err != nil && !swProf.HasProfilers() { | ||||
| 				return nil, err | ||||
|  | @ -400,7 +397,7 @@ func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { | |||
| 			collector.swProfilerCPUMap[&swProf] = cpu | ||||
| 		} | ||||
| 
 | ||||
| 		if !*config.NoCaProfiler { | ||||
| 		if !*config.Perf.NoCaProfiler { | ||||
| 			cacheProf, err := perf.NewCacheProfiler( | ||||
| 				-1, | ||||
| 				cpu, | ||||
|  |  | |||
|  | @ -29,21 +29,19 @@ type powerSupplyClassCollector struct { | |||
| 	ignoredPattern *regexp.Regexp | ||||
| 	metricDescs    map[string]*prometheus.Desc | ||||
| 	logger         log.Logger | ||||
| 	config         NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("powersupplyclass", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(PowerSupplyClassConfig) | ||||
| 		return NewPowerSupplyClassCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("powersupplyclass", defaultEnabled, NewPowerSupplyClassCollector) | ||||
| } | ||||
| 
 | ||||
| type PowerSupplyClassConfig struct { | ||||
| 	IgnoredPowerSupplies *string | ||||
| } | ||||
| 
 | ||||
| func NewPowerSupplyClassCollector(config PowerSupplyClassConfig, logger log.Logger) (Collector, error) { | ||||
| 	pattern := regexp.MustCompile(*config.IgnoredPowerSupplies) | ||||
| func NewPowerSupplyClassCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	pattern := regexp.MustCompile(*config.PowerSupplyClass.IgnoredPowerSupplies) | ||||
| 	return &powerSupplyClassCollector{ | ||||
| 		subsystem:      "power_supply", | ||||
| 		ignoredPattern: pattern, | ||||
|  |  | |||
|  | @ -28,7 +28,7 @@ import ( | |||
| ) | ||||
| 
 | ||||
| func (c *powerSupplyClassCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	powerSupplyClass, err := getPowerSupplyClassInfo(c.ignoredPattern) | ||||
| 	powerSupplyClass, err := getPowerSupplyClassInfo(c.config, c.ignoredPattern) | ||||
| 	if err != nil { | ||||
| 		if errors.Is(err, os.ErrNotExist) { | ||||
| 			return ErrNoData | ||||
|  | @ -155,8 +155,8 @@ func pushPowerSupplyMetric(ch chan<- prometheus.Metric, subsystem string, name s | |||
| 	ch <- prometheus.MustNewConstMetric(fieldDesc, valueType, value, powerSupplyName) | ||||
| } | ||||
| 
 | ||||
| func getPowerSupplyClassInfo(ignore *regexp.Regexp) (sysfs.PowerSupplyClass, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| func getPowerSupplyClassInfo(config NodeCollectorConfig, ignore *regexp.Regexp) (sysfs.PowerSupplyClass, error) { | ||||
| 	fs, err := sysfs.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  |  | |||
|  | @ -45,14 +45,12 @@ type pressureStatsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("pressure", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewPressureStatsCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("pressure", defaultEnabled, NewPressureStatsCollector) | ||||
| } | ||||
| 
 | ||||
| // NewPressureStatsCollector returns a Collector exposing pressure stall information
 | ||||
| func NewPressureStatsCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| func NewPressureStatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -40,17 +40,16 @@ type processCollector struct { | |||
| 	pidUsed      *prometheus.Desc | ||||
| 	pidMax       *prometheus.Desc | ||||
| 	logger       log.Logger | ||||
| 	config       NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("processes", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewProcessStatCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("processes", defaultEnabled, NewProcessStatCollector) | ||||
| } | ||||
| 
 | ||||
| // NewProcessStatCollector returns a new Collector exposing process data read from the proc filesystem.
 | ||||
| func NewProcessStatCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| func NewProcessStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  | @ -93,7 +92,7 @@ func (c *processCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 	} | ||||
| 
 | ||||
| 	ch <- prometheus.MustNewConstMetric(c.threadAlloc, prometheus.GaugeValue, float64(threads)) | ||||
| 	maxThreads, err := readUintFromFile(procFilePath("sys/kernel/threads-max")) | ||||
| 	maxThreads, err := readUintFromFile(c.config.Path.procFilePath("sys/kernel/threads-max")) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("unable to retrieve limit number of threads: %w", err) | ||||
| 	} | ||||
|  | @ -107,7 +106,7 @@ func (c *processCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 		ch <- prometheus.MustNewConstMetric(c.threadsState, prometheus.GaugeValue, float64(threadStates[state]), state) | ||||
| 	} | ||||
| 
 | ||||
| 	pidM, err := readUintFromFile(procFilePath("sys/kernel/pid_max")) | ||||
| 	pidM, err := readUintFromFile(c.config.Path.procFilePath("sys/kernel/pid_max")) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("unable to retrieve limit number of maximum pids alloved: %w", err) | ||||
| 	} | ||||
|  | @ -150,7 +149,7 @@ func (c *processCollector) getAllocatedThreads() (int, map[string]int32, int, ma | |||
| } | ||||
| 
 | ||||
| func (c *processCollector) getThreadStates(pid int, pidStat procfs.ProcStat, threadStates map[string]int32) error { | ||||
| 	fs, err := procfs.NewFS(procFilePath(path.Join(strconv.Itoa(pid), "task"))) | ||||
| 	fs, err := procfs.NewFS(c.config.Path.procFilePath(path.Join(strconv.Itoa(pid), "task"))) | ||||
| 	if err != nil { | ||||
| 		if c.isIgnoredError(err) { | ||||
| 			level.Debug(c.logger).Log("msg", "file not found when retrieving tasks for pid", "pid", pid, "err", err) | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ import ( | |||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/docker/cli/cli/config" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/prometheus/procfs" | ||||
| ) | ||||
|  | @ -29,7 +30,7 @@ func TestReadProcessStatus(t *testing.T) { | |||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	want := 1 | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		t.Errorf("failed to open procfs: %v", err) | ||||
| 	} | ||||
|  | @ -45,7 +46,7 @@ func TestReadProcessStatus(t *testing.T) { | |||
| 
 | ||||
| 		t.Fatalf("Process states cannot be nil %v:", states) | ||||
| 	} | ||||
| 	maxPid, err := readUintFromFile(procFilePath("sys/kernel/pid_max")) | ||||
| 	maxPid, err := readUintFromFile(c.config.Path.procFilePath("sys/kernel/pid_max")) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("Unable to retrieve limit number of maximum pids alloved %v\n", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -37,14 +37,11 @@ type qdiscStatCollector struct { | |||
| 	overlimits   typedDesc | ||||
| 	qlength      typedDesc | ||||
| 	backlog      typedDesc | ||||
| 	config       QdiscConfig | ||||
| 	config       NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("qdisc", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(QdiscConfig) | ||||
| 		return NewQdiscStatCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("qdisc", defaultDisabled, NewQdiscStatCollector) | ||||
| } | ||||
| 
 | ||||
| type QdiscConfig struct { | ||||
|  | @ -54,8 +51,8 @@ type QdiscConfig struct { | |||
| } | ||||
| 
 | ||||
| // NewQdiscStatCollector returns a new Collector exposing queuing discipline statistics.
 | ||||
| func NewQdiscStatCollector(config QdiscConfig, logger log.Logger) (Collector, error) { | ||||
| 	if *config.DeviceExclude != "" && *config.DeviceInclude != "" { | ||||
| func NewQdiscStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	if *config.Qdisc.DeviceExclude != "" && *config.Qdisc.DeviceInclude != "" { | ||||
| 		return nil, fmt.Errorf("collector.qdisk.device-include and collector.qdisk.device-exclude are mutaly exclusive") | ||||
| 	} | ||||
| 
 | ||||
|  | @ -96,7 +93,7 @@ func NewQdiscStatCollector(config QdiscConfig, logger log.Logger) (Collector, er | |||
| 			[]string{"device", "kind"}, nil, | ||||
| 		), prometheus.GaugeValue}, | ||||
| 		logger:       logger, | ||||
| 		deviceFilter: newDeviceFilter(*config.DeviceExclude, *config.DeviceExclude), | ||||
| 		deviceFilter: newDeviceFilter(*config.Qdisc.DeviceExclude, *config.Qdisc.DeviceExclude), | ||||
| 		config:       config, | ||||
| 	}, nil | ||||
| } | ||||
|  | @ -117,7 +114,7 @@ func (c *qdiscStatCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 	var msgs []qdisc.QdiscInfo | ||||
| 	var err error | ||||
| 
 | ||||
| 	fixtures := *c.config.Fixtures | ||||
| 	fixtures := *c.config.Qdisc.Fixtures | ||||
| 
 | ||||
| 	if fixtures == "" { | ||||
| 		msgs, err = qdisc.Get() | ||||
|  |  | |||
|  | @ -35,14 +35,11 @@ type raplCollector struct { | |||
| 	logger log.Logger | ||||
| 
 | ||||
| 	joulesMetricDesc *prometheus.Desc | ||||
| 	config           RaplConfig | ||||
| 	config           NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector(raplCollectorSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(RaplConfig) | ||||
| 		return NewRaplCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector(raplCollectorSubsystem, defaultEnabled, NewRaplCollector) | ||||
| } | ||||
| 
 | ||||
| type RaplConfig struct { | ||||
|  | @ -50,8 +47,8 @@ type RaplConfig struct { | |||
| } | ||||
| 
 | ||||
| // NewRaplCollector returns a new Collector exposing RAPL metrics.
 | ||||
| func NewRaplCollector(config RaplConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| func NewRaplCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*config.Path.SysPath) | ||||
| 
 | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
|  | @ -100,7 +97,7 @@ func (c *raplCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 
 | ||||
| 		joules := float64(microJoules) / 1000000.0 | ||||
| 
 | ||||
| 		if *c.config.ZoneLabel { | ||||
| 		if *c.config.Rapl.ZoneLabel { | ||||
| 			ch <- c.joulesMetricWithZoneLabel(rz, joules) | ||||
| 		} else { | ||||
| 			ch <- c.joulesMetric(rz, joules) | ||||
|  |  | |||
|  | @ -29,14 +29,11 @@ type runitCollector struct { | |||
| 	stateNormal    typedDesc | ||||
| 	stateTimestamp typedDesc | ||||
| 	logger         log.Logger | ||||
| 	config         RunitConfig | ||||
| 	config         NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("runit", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(RunitConfig) | ||||
| 		return NewRunitCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("runit", defaultDisabled, NewRunitCollector) | ||||
| } | ||||
| 
 | ||||
| type RunitConfig struct { | ||||
|  | @ -44,7 +41,7 @@ type RunitConfig struct { | |||
| } | ||||
| 
 | ||||
| // NewRunitCollector returns a new Collector exposing runit statistics.
 | ||||
| func NewRunitCollector(config RunitConfig, logger log.Logger) (Collector, error) { | ||||
| func NewRunitCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	var ( | ||||
| 		subsystem   = "service" | ||||
| 		constLabels = prometheus.Labels{"supervisor": "runit"} | ||||
|  | @ -80,7 +77,7 @@ func NewRunitCollector(config RunitConfig, logger log.Logger) (Collector, error) | |||
| } | ||||
| 
 | ||||
| func (c *runitCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	services, err := runit.GetServices(*c.config.ServiceDir) | ||||
| 	services, err := runit.GetServices(*c.config.Runit.ServiceDir) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  |  | |||
|  | @ -53,8 +53,8 @@ var ( | |||
| ) | ||||
| 
 | ||||
| // NewSchedstatCollector returns a new Collector exposing task scheduler statistics
 | ||||
| func NewSchedstatCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| func NewSchedstatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  | @ -68,9 +68,7 @@ type schedstatCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("schedstat", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewSchedstatCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("schedstat", defaultEnabled, NewSchedstatCollector) | ||||
| } | ||||
| 
 | ||||
| func (c *schedstatCollector) Update(ch chan<- prometheus.Metric) error { | ||||
|  |  | |||
|  | @ -30,13 +30,11 @@ type selinuxCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("selinux", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewSelinuxCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("selinux", defaultEnabled, NewSelinuxCollector) | ||||
| } | ||||
| 
 | ||||
| // NewSelinuxCollector returns a new Collector exposing SELinux statistics.
 | ||||
| func NewSelinuxCollector(logger log.Logger) (Collector, error) { | ||||
| func NewSelinuxCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	const subsystem = "selinux" | ||||
| 
 | ||||
| 	return &selinuxCollector{ | ||||
|  |  | |||
|  | @ -32,13 +32,11 @@ type slabinfoCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("slabinfo", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewSlabinfoCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("slabinfo", defaultDisabled, NewSlabinfoCollector) | ||||
| } | ||||
| 
 | ||||
| func NewSlabinfoCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| func NewSlabinfoCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -36,21 +36,20 @@ var pageSize = os.Getpagesize() | |||
| 
 | ||||
| type sockStatCollector struct { | ||||
| 	logger log.Logger | ||||
| 	config NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector(sockStatSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewSockStatCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector(sockStatSubsystem, defaultEnabled, NewSockStatCollector) | ||||
| } | ||||
| 
 | ||||
| // NewSockStatCollector returns a new Collector exposing socket stats.
 | ||||
| func NewSockStatCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &sockStatCollector{logger}, nil | ||||
| func NewSockStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &sockStatCollector{logger, config}, nil | ||||
| } | ||||
| 
 | ||||
| func (c *sockStatCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	fs, err := procfs.NewFS(*c.config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -31,20 +31,18 @@ type softirqsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("softirqs", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewSoftirqsCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("softirqs", defaultDisabled, NewSoftirqsCollector) | ||||
| } | ||||
| 
 | ||||
| // NewSoftirqsCollector returns a new Collector exposing softirq stats.
 | ||||
| func NewSoftirqsCollector(logger log.Logger) (Collector, error) { | ||||
| func NewSoftirqsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	desc := typedDesc{prometheus.NewDesc( | ||||
| 		namespace+"_softirqs_functions_total", | ||||
| 		"Softirq counts per CPU.", | ||||
| 		softirqLabelNames, nil, | ||||
| 	), prometheus.CounterValue} | ||||
| 
 | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -42,14 +42,12 @@ const ( | |||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("softnet", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewSoftnetCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("softnet", defaultEnabled, NewSoftnetCollector) | ||||
| } | ||||
| 
 | ||||
| // NewSoftnetCollector returns a new Collector exposing softnet metrics.
 | ||||
| func NewSoftnetCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| func NewSoftnetCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -34,14 +34,11 @@ type statCollector struct { | |||
| 	procsBlocked *prometheus.Desc | ||||
| 	softIRQ      *prometheus.Desc | ||||
| 	logger       log.Logger | ||||
| 	config       StatConfig | ||||
| 	config       NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("stat", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(StatConfig) | ||||
| 		return NewStatCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("stat", defaultEnabled, NewStatCollector) | ||||
| } | ||||
| 
 | ||||
| type StatConfig struct { | ||||
|  | @ -49,8 +46,8 @@ type StatConfig struct { | |||
| } | ||||
| 
 | ||||
| // NewStatCollector returns a new Collector exposing kernel/system statistics.
 | ||||
| func NewStatCollector(config StatConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| func NewStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  | @ -112,7 +109,7 @@ func (c *statCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 	ch <- prometheus.MustNewConstMetric(c.procsRunning, prometheus.GaugeValue, float64(stats.ProcessesRunning)) | ||||
| 	ch <- prometheus.MustNewConstMetric(c.procsBlocked, prometheus.GaugeValue, float64(stats.ProcessesBlocked)) | ||||
| 
 | ||||
| 	if *c.config.Softirq { | ||||
| 	if *c.config.Stat.Softirq { | ||||
| 		si := stats.SoftIRQ | ||||
| 
 | ||||
| 		for _, vec := range []struct { | ||||
|  |  | |||
|  | @ -43,10 +43,7 @@ type supervisordCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("supervisord", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(SupervisordConfig) | ||||
| 		return NewSupervisordCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("supervisord", defaultDisabled, NewSupervisordCollector) | ||||
| } | ||||
| 
 | ||||
| type SupervisordConfig struct { | ||||
|  | @ -54,13 +51,13 @@ type SupervisordConfig struct { | |||
| } | ||||
| 
 | ||||
| // NewSupervisordCollector returns a new Collector exposing supervisord statistics.
 | ||||
| func NewSupervisordCollector(config SupervisordConfig, logger log.Logger) (Collector, error) { | ||||
| func NewSupervisordCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	var ( | ||||
| 		subsystem  = "supervisord" | ||||
| 		labelNames = []string{"name", "group"} | ||||
| 	) | ||||
| 
 | ||||
| 	if u, err := url.Parse(*config.URL); err == nil && u.Scheme == "unix" { | ||||
| 	if u, err := url.Parse(*config.Supervisord.URL); err == nil && u.Scheme == "unix" { | ||||
| 		// Fake the URI scheme as http, since net/http.*Transport.roundTrip will complain
 | ||||
| 		// about a non-http(s) transport.
 | ||||
| 		xrpc = xmlrpc.NewClient("http://unix/RPC2") | ||||
|  | @ -71,7 +68,7 @@ func NewSupervisordCollector(config SupervisordConfig, logger log.Logger) (Colle | |||
| 			}, | ||||
| 		} | ||||
| 	} else { | ||||
| 		xrpc = xmlrpc.NewClient(*config.URL) | ||||
| 		xrpc = xmlrpc.NewClient(*config.Supervisord.URL) | ||||
| 	} | ||||
| 
 | ||||
| 	level.Warn(logger).Log("msg", "This collector is deprecated and will be removed in the next major version release.") | ||||
|  |  | |||
|  | @ -34,10 +34,7 @@ type sysctlCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("sysctl", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(SysctlConfig) | ||||
| 		return NewSysctlCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("sysctl", defaultDisabled, NewSysctlCollector) | ||||
| } | ||||
| 
 | ||||
| type SysctlConfig struct { | ||||
|  | @ -45,8 +42,8 @@ type SysctlConfig struct { | |||
| 	IncludeInfo *[]string | ||||
| } | ||||
| 
 | ||||
| func NewSysctlCollector(config SysctlConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| func NewSysctlCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  | @ -56,7 +53,7 @@ func NewSysctlCollector(config SysctlConfig, logger log.Logger) (Collector, erro | |||
| 		sysctls: []*sysctl{}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, include := range *config.Include { | ||||
| 	for _, include := range *config.Sysctl.Include { | ||||
| 		sysctl, err := newSysctl(include, true) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
|  | @ -64,7 +61,7 @@ func NewSysctlCollector(config SysctlConfig, logger log.Logger) (Collector, erro | |||
| 		c.sysctls = append(c.sysctls, sysctl) | ||||
| 	} | ||||
| 
 | ||||
| 	for _, include := range *config.IncludeInfo { | ||||
| 	for _, include := range *config.Sysctl.IncludeInfo { | ||||
| 		sysctl, err := newSysctl(include, false) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
|  |  | |||
|  | @ -64,16 +64,13 @@ type systemdCollector struct { | |||
| 	systemdUnitIncludePattern *regexp.Regexp | ||||
| 	systemdUnitExcludePattern *regexp.Regexp | ||||
| 	logger                    log.Logger | ||||
| 	config                    SystemdConfig | ||||
| 	config                    NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| var unitStatesName = []string{"active", "activating", "deactivating", "inactive", "failed"} | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("systemd", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(SystemdConfig) | ||||
| 		return NewSystemdCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("systemd", defaultDisabled, NewSystemdCollector) | ||||
| } | ||||
| 
 | ||||
| type SystemdConfig struct { | ||||
|  | @ -88,7 +85,7 @@ type SystemdConfig struct { | |||
| } | ||||
| 
 | ||||
| // NewSystemdCollector returns a new Collector exposing systemd statistics.
 | ||||
| func NewSystemdCollector(config SystemdConfig, logger log.Logger) (Collector, error) { | ||||
| func NewSystemdCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	const subsystem = "systemd" | ||||
| 
 | ||||
| 	unitDesc := prometheus.NewDesc( | ||||
|  | @ -134,26 +131,26 @@ func NewSystemdCollector(config SystemdConfig, logger log.Logger) (Collector, er | |||
| 		prometheus.BuildFQName(namespace, subsystem, "version"), | ||||
| 		"Detected systemd version", []string{"version"}, nil) | ||||
| 
 | ||||
| 	if *config.OldUnitExclude != "" { | ||||
| 	if *config.Systemd.OldUnitExclude != "" { | ||||
| 		if !systemdUnitExcludeSet { | ||||
| 			level.Warn(logger).Log("msg", "--collector.systemd.unit-blacklist is DEPRECATED and will be removed in 2.0.0, use --collector.systemd.unit-exclude") | ||||
| 			*config.UnitExclude = *config.OldUnitExclude | ||||
| 			*config.Systemd.UnitExclude = *config.Systemd.OldUnitExclude | ||||
| 		} else { | ||||
| 			return nil, errors.New("--collector.systemd.unit-blacklist and --collector.systemd.unit-exclude are mutually exclusive") | ||||
| 		} | ||||
| 	} | ||||
| 	if *config.OldUnitInclude != "" { | ||||
| 	if *config.Systemd.OldUnitInclude != "" { | ||||
| 		if !systemdUnitIncludeSet { | ||||
| 			level.Warn(logger).Log("msg", "--collector.systemd.unit-whitelist is DEPRECATED and will be removed in 2.0.0, use --collector.systemd.unit-include") | ||||
| 			*config.UnitInclude = *config.OldUnitInclude | ||||
| 			*config.Systemd.UnitInclude = *config.Systemd.OldUnitInclude | ||||
| 		} else { | ||||
| 			return nil, errors.New("--collector.systemd.unit-whitelist and --collector.systemd.unit-include are mutually exclusive") | ||||
| 		} | ||||
| 	} | ||||
| 	level.Info(logger).Log("msg", "Parsed flag --collector.systemd.unit-include", "flag", *config.UnitInclude) | ||||
| 	systemdUnitIncludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *config.UnitInclude)) | ||||
| 	level.Info(logger).Log("msg", "Parsed flag --collector.systemd.unit-exclude", "flag", *config.UnitExclude) | ||||
| 	systemdUnitExcludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *config.UnitExclude)) | ||||
| 	level.Info(logger).Log("msg", "Parsed flag --collector.systemd.unit-include", "flag", *config.Systemd.UnitInclude) | ||||
| 	systemdUnitIncludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *config.Systemd.UnitInclude)) | ||||
| 	level.Info(logger).Log("msg", "Parsed flag --collector.systemd.unit-exclude", "flag", *config.Systemd.UnitExclude) | ||||
| 	systemdUnitExcludePattern := regexp.MustCompile(fmt.Sprintf("^(?:%s)$", *config.Systemd.UnitExclude)) | ||||
| 
 | ||||
| 	return &systemdCollector{ | ||||
| 		unitDesc:                      unitDesc, | ||||
|  | @ -178,7 +175,7 @@ func NewSystemdCollector(config SystemdConfig, logger log.Logger) (Collector, er | |||
| // to reduce wait time for responses.
 | ||||
| func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	begin := time.Now() | ||||
| 	conn, err := newSystemdDbusConn(c.config.Private) | ||||
| 	conn, err := newSystemdDbusConn(c.config.Systemd.Private) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("couldn't get dbus connection: %w", err) | ||||
| 	} | ||||
|  | @ -221,7 +218,7 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 		level.Debug(c.logger).Log("msg", "collectUnitStatusMetrics took", "duration_seconds", time.Since(begin).Seconds()) | ||||
| 	}() | ||||
| 
 | ||||
| 	if *c.config.EnableStartTimeMetrics { | ||||
| 	if *c.config.Systemd.EnableStartTimeMetrics { | ||||
| 		wg.Add(1) | ||||
| 		go func() { | ||||
| 			defer wg.Done() | ||||
|  | @ -231,7 +228,7 @@ func (c *systemdCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 		}() | ||||
| 	} | ||||
| 
 | ||||
| 	if *c.config.EnableTaskMetrics { | ||||
| 	if *c.config.Systemd.EnableTaskMetrics { | ||||
| 		wg.Add(1) | ||||
| 		go func() { | ||||
| 			defer wg.Done() | ||||
|  | @ -295,7 +292,7 @@ func (c *systemdCollector) collectUnitStatusMetrics(conn *dbus.Conn, ch chan<- p | |||
| 				c.unitDesc, prometheus.GaugeValue, isActive, | ||||
| 				unit.Name, stateName, serviceType) | ||||
| 		} | ||||
| 		if *c.config.EnableRestartsMetrics && strings.HasSuffix(unit.Name, ".service") { | ||||
| 		if *c.config.Systemd.EnableRestartsMetrics && strings.HasSuffix(unit.Name, ".service") { | ||||
| 			// NRestarts wasn't added until systemd 235.
 | ||||
| 			restartsCount, err := conn.GetUnitTypePropertyContext(context.TODO(), unit.Name, "Service", "NRestarts") | ||||
| 			if err != nil { | ||||
|  |  | |||
|  | @ -44,10 +44,7 @@ type tapestatsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("tapestats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(TapestatsConfig) | ||||
| 		return NewTapestatsCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("tapestats", defaultEnabled, NewTapestatsCollector) | ||||
| } | ||||
| 
 | ||||
| type TapestatsConfig struct { | ||||
|  | @ -56,10 +53,10 @@ type TapestatsConfig struct { | |||
| 
 | ||||
| // NewTapestatsCollector returns a new Collector exposing tape device stats.
 | ||||
| // Docs from https://www.kernel.org/doc/html/latest/scsi/st.html#sysfs-and-statistics-for-tape-devices
 | ||||
| func NewTapestatsCollector(config TapestatsConfig, logger log.Logger) (Collector, error) { | ||||
| func NewTapestatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	var tapeLabelNames = []string{"device"} | ||||
| 
 | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| 	fs, err := sysfs.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  | @ -67,7 +64,7 @@ func NewTapestatsCollector(config TapestatsConfig, logger log.Logger) (Collector | |||
| 	tapeSubsystem := "tape" | ||||
| 
 | ||||
| 	return &tapestatsCollector{ | ||||
| 		ignoredDevicesPattern: regexp.MustCompile(*config.IgnoredDevices), | ||||
| 		ignoredDevicesPattern: regexp.MustCompile(*config.Tapestats.IgnoredDevices), | ||||
| 
 | ||||
| 		ioNow: prometheus.NewDesc( | ||||
| 			prometheus.BuildFQName(namespace, tapeSubsystem, "io_now"), | ||||
|  |  | |||
|  | @ -61,16 +61,15 @@ const ( | |||
| type tcpStatCollector struct { | ||||
| 	desc   typedDesc | ||||
| 	logger log.Logger | ||||
| 	config NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("tcpstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewTCPStatCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("tcpstat", defaultDisabled, NewTCPStatCollector) | ||||
| } | ||||
| 
 | ||||
| // NewTCPStatCollector returns a new Collector exposing network stats.
 | ||||
| func NewTCPStatCollector(logger log.Logger) (Collector, error) { | ||||
| func NewTCPStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &tcpStatCollector{ | ||||
| 		desc: typedDesc{prometheus.NewDesc( | ||||
| 			prometheus.BuildFQName(namespace, "tcp", "connection_states"), | ||||
|  | @ -78,6 +77,7 @@ func NewTCPStatCollector(logger log.Logger) (Collector, error) { | |||
| 			[]string{"state"}, nil, | ||||
| 		), prometheus.GaugeValue}, | ||||
| 		logger: logger, | ||||
| 		config: config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
|  | @ -137,7 +137,7 @@ func (c *tcpStatCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 	} | ||||
| 
 | ||||
| 	// if enabled ipv6 system
 | ||||
| 	if _, hasIPv6 := os.Stat(procFilePath("net/tcp6")); hasIPv6 == nil { | ||||
| 	if _, hasIPv6 := os.Stat(c.config.Path.procFilePath("net/tcp6")); hasIPv6 == nil { | ||||
| 		tcp6Stats, err := getTCPStats(syscall.AF_INET6) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("couldn't get tcp6stats: %w", err) | ||||
|  |  | |||
|  | @ -48,10 +48,7 @@ type textFileCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("textfile", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(TextFileConfig) | ||||
| 		return NewTextFileCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("textfile", defaultEnabled, NewTextFileCollector) | ||||
| } | ||||
| 
 | ||||
| type TextFileConfig struct { | ||||
|  | @ -60,9 +57,9 @@ type TextFileConfig struct { | |||
| 
 | ||||
| // NewTextFileCollector returns a new Collector exposing metrics read from files
 | ||||
| // in the given textfile directory.
 | ||||
| func NewTextFileCollector(config TextFileConfig, logger log.Logger) (Collector, error) { | ||||
| func NewTextFileCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	c := &textFileCollector{ | ||||
| 		path:   *config.Directory, | ||||
| 		path:   *config.TextFile.Directory, | ||||
| 		logger: logger, | ||||
| 	} | ||||
| 	return c, nil | ||||
|  |  | |||
|  | @ -63,9 +63,7 @@ type thermCollector struct { | |||
| const thermal = "thermal" | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector(thermal, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewThermCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector(thermal, defaultEnabled, NewThermCollector) | ||||
| } | ||||
| 
 | ||||
| // NewThermCollector returns a new Collector exposing current CPU power levels.
 | ||||
|  |  | |||
|  | @ -39,14 +39,12 @@ type thermalZoneCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("thermal_zone", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewThermalZoneCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("thermal_zone", defaultEnabled, NewThermalZoneCollector) | ||||
| } | ||||
| 
 | ||||
| // NewThermalZoneCollector returns a new Collector exposing kernel/system statistics.
 | ||||
| func NewThermalZoneCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| func NewThermalZoneCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -30,17 +30,16 @@ type timeCollector struct { | |||
| 	clocksourcesAvailable typedDesc | ||||
| 	clocksourceCurrent    typedDesc | ||||
| 	logger                log.Logger | ||||
| 	config                NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("time", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewTimeCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("time", defaultEnabled, NewTimeCollector) | ||||
| } | ||||
| 
 | ||||
| // NewTimeCollector returns a new Collector exposing the current system time in
 | ||||
| // seconds since epoch.
 | ||||
| func NewTimeCollector(logger log.Logger) (Collector, error) { | ||||
| func NewTimeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	const subsystem = "time" | ||||
| 	return &timeCollector{ | ||||
| 		now: typedDesc{prometheus.NewDesc( | ||||
|  | @ -64,6 +63,7 @@ func NewTimeCollector(logger log.Logger) (Collector, error) { | |||
| 			[]string{"device", "clocksource"}, nil, | ||||
| 		), prometheus.GaugeValue}, | ||||
| 		logger: logger, | ||||
| 		config: config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ import ( | |||
| ) | ||||
| 
 | ||||
| func (c *timeCollector) update(ch chan<- prometheus.Metric) error { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| 	fs, err := sysfs.NewFS(*c.config.Path.SysPath) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -62,13 +62,11 @@ type timexCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("timex", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewTimexCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("timex", defaultEnabled, NewTimexCollector) | ||||
| } | ||||
| 
 | ||||
| // NewTimexCollector returns a new Collector exposing adjtime(3) stats.
 | ||||
| func NewTimexCollector(logger log.Logger) (Collector, error) { | ||||
| func NewTimexCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	const subsystem = "timex" | ||||
| 
 | ||||
| 	return &timexCollector{ | ||||
|  |  | |||
|  | @ -36,14 +36,12 @@ type ( | |||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("udp_queues", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewUDPqueuesCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("udp_queues", defaultEnabled, NewUDPqueuesCollector) | ||||
| } | ||||
| 
 | ||||
| // NewUDPqueuesCollector returns a new Collector exposing network udp queued bytes.
 | ||||
| func NewUDPqueuesCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| func NewUDPqueuesCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*config.Path.ProcPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -49,13 +49,11 @@ type uname struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("uname", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return newUnameCollector(logger) | ||||
| 	}) | ||||
| 	registerCollector("uname", defaultEnabled, newUnameCollector) | ||||
| } | ||||
| 
 | ||||
| // NewUnameCollector returns new unameCollector.
 | ||||
| func newUnameCollector(logger log.Logger) (Collector, error) { | ||||
| func newUnameCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	return &unameCollector{logger}, nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -35,13 +35,11 @@ const ( | |||
| type vmStatCollector struct { | ||||
| 	fieldPattern *regexp.Regexp | ||||
| 	logger       log.Logger | ||||
| 	config       NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector(vmStatSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(VmStatConfig) | ||||
| 		return NewvmStatCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector(vmStatSubsystem, defaultEnabled, NewvmStatCollector) | ||||
| } | ||||
| 
 | ||||
| type VmStatConfig struct { | ||||
|  | @ -49,16 +47,17 @@ type VmStatConfig struct { | |||
| } | ||||
| 
 | ||||
| // NewvmStatCollector returns a new Collector exposing vmstat stats.
 | ||||
| func NewvmStatCollector(config VmStatConfig, logger log.Logger) (Collector, error) { | ||||
| 	pattern := regexp.MustCompile(*config.Fields) | ||||
| func NewvmStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	pattern := regexp.MustCompile(*config.VmStat.Fields) | ||||
| 	return &vmStatCollector{ | ||||
| 		fieldPattern: pattern, | ||||
| 		logger:       logger, | ||||
| 		config:       config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func (c *vmStatCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	file, err := os.Open(procFilePath("vmstat")) | ||||
| 	file, err := os.Open(c.config.Path.procFilePath("vmstat")) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  |  | |||
|  | @ -45,14 +45,11 @@ type wifiCollector struct { | |||
| 	stationBeaconLossTotal       *prometheus.Desc | ||||
| 
 | ||||
| 	logger log.Logger | ||||
| 	config WifiConfig | ||||
| 	config NodeCollectorConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("wifi", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(WifiConfig) | ||||
| 		return NewWifiCollector(cfg, logger) | ||||
| 	}) | ||||
| 	registerCollector("wifi", defaultDisabled, NewWifiCollector) | ||||
| } | ||||
| 
 | ||||
| type WifiConfig struct { | ||||
|  | @ -70,7 +67,7 @@ type wifiStater interface { | |||
| } | ||||
| 
 | ||||
| // NewWifiCollector returns a new Collector exposing Wifi statistics.
 | ||||
| func NewWifiCollector(config WifiConfig, logger log.Logger) (Collector, error) { | ||||
| func NewWifiCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	const ( | ||||
| 		subsystem = "wifi" | ||||
| 	) | ||||
|  | @ -169,7 +166,7 @@ func NewWifiCollector(config WifiConfig, logger log.Logger) (Collector, error) { | |||
| } | ||||
| 
 | ||||
| func (c *wifiCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	stat, err := newWifiStater(*c.config.Fixtures) | ||||
| 	stat, err := newWifiStater(*c.config.Wifi.Fixtures) | ||||
| 	if err != nil { | ||||
| 		// Cannot access wifi metrics, report no error.
 | ||||
| 		if errors.Is(err, os.ErrNotExist) { | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
		Reference in a new issue