mirror of
				https://github.com/prometheus/node_exporter.git
				synced 2025-08-20 18:33:52 -07:00 
			
		
		
		
	Refactor collectors - part 1
This commit is contained in:
		
							parent
							
								
									fe42dec972
								
							
						
					
					
						commit
						58a99510d2
					
				|  | @ -19,29 +19,32 @@ package collector | |||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
| 	"github.com/prometheus/procfs/bcache" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	priorityStats = kingpin.Flag("collector.bcache.priorityStats", "Expose expensive priority stats.").Bool() | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("bcache", defaultEnabled, NewBcacheCollector) | ||||
| 	registerCollector("bcache", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		bcacheConfig := config.(BcacheConfig) | ||||
| 		return NewBcacheCollector(bcacheConfig, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // A bcacheCollector is a Collector which gathers metrics from Linux bcache.
 | ||||
| type bcacheCollector struct { | ||||
| 	fs     bcache.FS | ||||
| 	logger log.Logger | ||||
| 	config BcacheConfig | ||||
| } | ||||
| 
 | ||||
| type BcacheConfig struct { | ||||
| 	PriorityStats *bool | ||||
| } | ||||
| 
 | ||||
| // NewBcacheCollector returns a newly allocated bcacheCollector.
 | ||||
| // It exposes a number of Linux bcache statistics.
 | ||||
| func NewBcacheCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewBcacheCollector(config BcacheConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := bcache.NewFS(*sysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
|  | @ -50,6 +53,7 @@ func NewBcacheCollector(config NodeCollectorConfig, logger log.Logger) (Collecto | |||
| 	return &bcacheCollector{ | ||||
| 		fs:     fs, | ||||
| 		logger: logger, | ||||
| 		config: config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
|  | @ -58,7 +62,7 @@ func NewBcacheCollector(config NodeCollectorConfig, logger log.Logger) (Collecto | |||
| func (c *bcacheCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	var stats []*bcache.Stats | ||||
| 	var err error | ||||
| 	if *priorityStats { | ||||
| 	if *c.config.PriorityStats { | ||||
| 		stats, err = c.fs.Stats() | ||||
| 	} else { | ||||
| 		stats, err = c.fs.StatsWithoutPriority() | ||||
|  | @ -317,7 +321,7 @@ func (c *bcacheCollector) updateBcacheStats(ch chan<- prometheus.Metric, s *bcac | |||
| 				extraLabelValue: cache.Name, | ||||
| 			}, | ||||
| 		} | ||||
| 		if *priorityStats { | ||||
| 		if *c.config.PriorityStats { | ||||
| 			// metrics in /sys/fs/bcache/<uuid>/<cache>/priority_stats
 | ||||
| 			priorityStatsMetrics := []bcacheMetric{ | ||||
| 				{ | ||||
|  |  | |||
|  | @ -34,12 +34,14 @@ type bondingCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("bonding", defaultEnabled, NewBondingCollector) | ||||
| 	registerCollector("bonding", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewBondingCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewBondingCollector returns a newly allocated bondingCollector.
 | ||||
| // It exposes the number of configured and active slave of linux bonding interfaces.
 | ||||
| func NewBondingCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewBondingCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &bondingCollector{ | ||||
| 		slaves: typedDesc{prometheus.NewDesc( | ||||
| 			prometheus.BuildFQName(namespace, "bonding", "slaves"), | ||||
|  |  | |||
|  | @ -28,11 +28,13 @@ type bootTimeCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("boottime", defaultEnabled, newBootTimeCollector) | ||||
| 	registerCollector("boottime", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return newBootTimeCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // newBootTimeCollector returns a new Collector exposing system boot time on BSD systems.
 | ||||
| func newBootTimeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func newBootTimeCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &bootTimeCollector{ | ||||
| 		logger: logger, | ||||
| 	}, nil | ||||
|  |  | |||
|  | @ -28,10 +28,12 @@ type bootTimeCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("boottime", defaultEnabled, newBootTimeCollector) | ||||
| 	registerCollector("boottime", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return newBootTimeCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func newBootTimeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func newBootTimeCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &bootTimeCollector{ | ||||
| 		boottime: typedDesc{ | ||||
| 			prometheus.NewDesc( | ||||
|  |  | |||
|  | @ -36,11 +36,13 @@ type btrfsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("btrfs", defaultEnabled, NewBtrfsCollector) | ||||
| 	registerCollector("btrfs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewBtrfsCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewBtrfsCollector returns a new Collector exposing Btrfs statistics.
 | ||||
| func NewBtrfsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewBtrfsCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := btrfs.NewFS(*sysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
|  |  | |||
|  | @ -37,11 +37,13 @@ type buddyinfoCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("buddyinfo", defaultDisabled, NewBuddyinfoCollector) | ||||
| 	registerCollector("buddyinfo", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewBuddyinfoCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewBuddyinfoCollector returns a new Collector exposing buddyinfo stats.
 | ||||
| func NewBuddyinfoCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewBuddyinfoCollector(logger log.Logger) (Collector, error) { | ||||
| 	desc := prometheus.NewDesc( | ||||
| 		prometheus.BuildFQName(namespace, buddyInfoSubsystem, "blocks"), | ||||
| 		"Count of free blocks according to size.", | ||||
|  |  | |||
|  | @ -34,11 +34,13 @@ type cgroupSummaryCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector(cgroupsCollectorSubsystem, defaultDisabled, NewCgroupSummaryCollector) | ||||
| 	registerCollector(cgroupsCollectorSubsystem, defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewCgroupSummaryCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewCgroupSummaryCollector returns a new Collector exposing a summary of cgroups.
 | ||||
| func NewCgroupSummaryCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewCgroupSummaryCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
|  |  | |||
|  | @ -17,5 +17,18 @@ | |||
| package collector | ||||
| 
 | ||||
| type NodeCollectorConfig struct { | ||||
| 	Arp ArpConfig | ||||
| 	Arp                   ArpConfig | ||||
| 	Bcache                BcacheConfig | ||||
| 	CPU                   CPUConfig | ||||
| 	DiskstatsDeviceFilter DiskstatsDeviceFilterConfig | ||||
| 	Ethtool               EthtoolConfig | ||||
| 	Filesystem            FilesystemConfig | ||||
| 	HwMon                 HwMonConfig | ||||
| 	IPVS                  IPVSConfig | ||||
| 	NetClass              NetClassConfig | ||||
| 	NetDev                NetDevConfig | ||||
| 	NetStat               NetStatConfig | ||||
| 	NTP                   NTPConfig | ||||
| 	Perf                  PerfConfig | ||||
| 	PowerSupplyClass      PowerSupplyClassConfig | ||||
| } | ||||
|  |  | |||
|  | @ -53,11 +53,13 @@ type conntrackStatistics struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("conntrack", defaultEnabled, NewConntrackCollector) | ||||
| 	registerCollector("conntrack", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewConntrackCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewConntrackCollector returns a new Collector exposing conntrack stats.
 | ||||
| func NewConntrackCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewConntrackCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &conntrackCollector{ | ||||
| 		current: prometheus.NewDesc( | ||||
| 			prometheus.BuildFQName(namespace, "", "nf_conntrack_entries"), | ||||
|  |  | |||
|  | @ -57,11 +57,13 @@ type statCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, NewCPUCollector) | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewCPUCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewCPUCollector returns a new Collector exposing CPU stats.
 | ||||
| func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewCPUCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &statCollector{ | ||||
| 		cpu:    nodeCPUSecondsDesc, | ||||
| 		logger: logger, | ||||
|  |  | |||
|  | @ -82,11 +82,13 @@ type statCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, NewStatCollector) | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewStatCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewStatCollector returns a new Collector exposing CPU stats.
 | ||||
| func NewStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewStatCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &statCollector{ | ||||
| 		cpu:    nodeCPUSecondsDesc, | ||||
| 		logger: logger, | ||||
|  |  | |||
|  | @ -89,11 +89,13 @@ type statCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, NewStatCollector) | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewStatCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewStatCollector returns a new Collector exposing CPU stats.
 | ||||
| func NewStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewStatCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &statCollector{ | ||||
| 		cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, | ||||
| 		temp: typedDesc{prometheus.NewDesc( | ||||
|  |  | |||
|  | @ -24,7 +24,6 @@ import ( | |||
| 	"strconv" | ||||
| 	"sync" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/go-kit/log/level" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
|  | @ -51,25 +50,33 @@ type cpuCollector struct { | |||
| 
 | ||||
| 	cpuFlagsIncludeRegexp *regexp.Regexp | ||||
| 	cpuBugsIncludeRegexp  *regexp.Regexp | ||||
| 
 | ||||
| 	config CPUConfig | ||||
| } | ||||
| 
 | ||||
| // Idle jump back limit in seconds.
 | ||||
| const jumpBackSeconds = 3.0 | ||||
| 
 | ||||
| var ( | ||||
| 	enableCPUGuest       = kingpin.Flag("collector.cpu.guest", "Enables metric node_cpu_guest_seconds_total").Default("true").Bool() | ||||
| 	enableCPUInfo        = kingpin.Flag("collector.cpu.info", "Enables metric cpu_info").Bool() | ||||
| 	flagsInclude         = kingpin.Flag("collector.cpu.info.flags-include", "Filter the `flags` field in cpuInfo with a value that must be a regular expression").String() | ||||
| 	bugsInclude          = kingpin.Flag("collector.cpu.info.bugs-include", "Filter the `bugs` field in cpuInfo with a value that must be a regular expression").String() | ||||
| 	jumpBackDebugMessage = fmt.Sprintf("CPU Idle counter jumped backwards more than %f seconds, possible hotplug event, resetting CPU stats", jumpBackSeconds) | ||||
| ) | ||||
| 
 | ||||
| type CPUConfig struct { | ||||
| 	EnableCPUGuest *bool | ||||
| 	EnableCPUInfo  *bool | ||||
| 	FlagsInclude   *string | ||||
| 	BugsInclude    *string | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, NewCPUCollector) | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cpuConfig := config.(CPUConfig) | ||||
| 		return NewCPUCollector(cpuConfig, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewCPUCollector returns a new Collector exposing kernel/system statistics.
 | ||||
| func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewCPUCollector(config CPUConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
|  | @ -129,8 +136,9 @@ func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, | |||
| 		logger:       logger, | ||||
| 		isolatedCpus: isolcpus, | ||||
| 		cpuStats:     make(map[int64]procfs.CPUStat), | ||||
| 		config:       config, | ||||
| 	} | ||||
| 	err = c.compileIncludeFlags(flagsInclude, bugsInclude) | ||||
| 	err = c.compileIncludeFlags(c.config.FlagsInclude, c.config.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) | ||||
| 	} | ||||
|  | @ -138,8 +146,8 @@ func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, | |||
| } | ||||
| 
 | ||||
| func (c *cpuCollector) compileIncludeFlags(flagsIncludeFlag, bugsIncludeFlag *string) error { | ||||
| 	if (*flagsIncludeFlag != "" || *bugsIncludeFlag != "") && !*enableCPUInfo { | ||||
| 		*enableCPUInfo = true | ||||
| 	if (*flagsIncludeFlag != "" || *bugsIncludeFlag != "") && !*c.config.EnableCPUInfo { | ||||
| 		*c.config.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") | ||||
| 	} | ||||
| 
 | ||||
|  | @ -161,7 +169,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 *enableCPUInfo { | ||||
| 	if *c.config.EnableCPUInfo { | ||||
| 		if err := c.updateInfo(ch); err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | @ -337,7 +345,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 *enableCPUGuest { | ||||
| 		if *c.config.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,11 +218,13 @@ type statCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, NewStatCollector) | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewStatCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewStatCollector returns a new Collector exposing CPU stats.
 | ||||
| func NewStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewStatCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &statCollector{ | ||||
| 		cpu: typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, | ||||
| 		temp: typedDesc{prometheus.NewDesc( | ||||
|  |  | |||
|  | @ -49,7 +49,9 @@ type cpuCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, NewCPUCollector) | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewCPUCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func NewCPUCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
|  |  | |||
|  | @ -33,10 +33,12 @@ type cpuCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpu", defaultEnabled, NewCpuCollector) | ||||
| 	registerCollector("cpu", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewCPUCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func NewCpuCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewCpuCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &cpuCollector{ | ||||
| 		cpu:    typedDesc{nodeCPUSecondsDesc, prometheus.CounterValue}, | ||||
| 		logger: logger, | ||||
|  |  | |||
|  | @ -37,10 +37,12 @@ var ( | |||
| type cpuVulnerabilitiesCollector struct{} | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector(cpuVulerabilitiesCollector, defaultDisabled, NewVulnerabilitySysfsCollector) | ||||
| 	registerCollector(cpuVulerabilitiesCollector, defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewVulnerabilitySysfsCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func NewVulnerabilitySysfsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewVulnerabilitySysfsCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &cpuVulnerabilitiesCollector{}, nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,10 +18,11 @@ package collector | |||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
| 	"github.com/prometheus/procfs/sysfs" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| type cpuFreqCollector struct { | ||||
|  | @ -30,11 +31,13 @@ type cpuFreqCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpufreq", defaultEnabled, NewCPUFreqCollector) | ||||
| 	registerCollector("cpufreq", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewCPUFreqCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewCPUFreqCollector returns a new Collector exposing kernel/system statistics.
 | ||||
| func NewCPUFreqCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewCPUFreqCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
|  |  | |||
|  | @ -33,10 +33,12 @@ type cpuFreqCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("cpufreq", defaultEnabled, NewCpuFreqCollector) | ||||
| 	registerCollector("cpufreq", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewCPUFreqCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func NewCpuFreqCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewCpuFreqCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &cpuFreqCollector{ | ||||
| 		logger: logger, | ||||
| 	}, nil | ||||
|  |  | |||
|  | @ -102,11 +102,13 @@ type devstatCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("devstat", defaultDisabled, NewDevstatCollector) | ||||
| 	registerCollector("devstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewDevstatCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewDevstatCollector returns a new Collector exposing Device stats.
 | ||||
| func NewDevstatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewDevstatCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &devstatCollector{ | ||||
| 		bytesDesc: prometheus.NewDesc( | ||||
| 			prometheus.BuildFQName(namespace, devstatSubsystem, "bytes_total"), | ||||
|  |  | |||
|  | @ -47,7 +47,9 @@ type devstatCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("devstat", defaultDisabled, NewDevstatCollector) | ||||
| 	registerCollector("devstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewDevstatCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewDevstatCollector returns a new Collector exposing Device stats.
 | ||||
|  |  | |||
|  | @ -20,7 +20,6 @@ package collector | |||
| import ( | ||||
| 	"errors" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/go-kit/log/level" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
|  | @ -34,19 +33,6 @@ var ( | |||
| 	diskLabelNames = []string{"device"} | ||||
| 
 | ||||
| 	diskstatsDeviceExcludeSet bool | ||||
| 	diskstatsDeviceExclude    = kingpin.Flag( | ||||
| 		"collector.diskstats.device-exclude", | ||||
| 		"Regexp of diskstats devices to exclude (mutually exclusive to device-include).", | ||||
| 	).Default(diskstatsDefaultIgnoredDevices).PreAction(func(c *kingpin.ParseContext) error { | ||||
| 		diskstatsDeviceExcludeSet = true | ||||
| 		return nil | ||||
| 	}).String() | ||||
| 	oldDiskstatsDeviceExclude = kingpin.Flag( | ||||
| 		"collector.diskstats.ignored-devices", | ||||
| 		"DEPRECATED: Use collector.diskstats.device-exclude", | ||||
| 	).Hidden().String() | ||||
| 
 | ||||
| 	diskstatsDeviceInclude = kingpin.Flag("collector.diskstats.device-include", "Regexp of diskstats devices to include (mutually exclusive to device-exclude).").String() | ||||
| 
 | ||||
| 	readsCompletedDesc = prometheus.NewDesc( | ||||
| 		prometheus.BuildFQName(namespace, diskSubsystem, "reads_completed_total"), | ||||
|  | @ -93,27 +79,35 @@ var ( | |||
| 	) | ||||
| ) | ||||
| 
 | ||||
| func newDiskstatsDeviceFilter(logger log.Logger) (deviceFilter, error) { | ||||
| 	if *oldDiskstatsDeviceExclude != "" { | ||||
| type DiskstatsDeviceFilterConfig struct { | ||||
| 	DiskstatsDeviceExclude    *string | ||||
| 	OldDiskstatsDeviceExclude *string | ||||
| 	DiskstatsDeviceInclude    *string | ||||
| } | ||||
| 
 | ||||
| func newDiskstatsDeviceFilter(config DiskstatsDeviceFilterConfig, logger log.Logger) (deviceFilter, error) { | ||||
| 	if *config.OldDiskstatsDeviceExclude != "" { | ||||
| 		if !diskstatsDeviceExcludeSet { | ||||
| 			level.Warn(logger).Log("msg", "--collector.diskstats.ignored-devices is DEPRECATED and will be removed in 2.0.0, use --collector.diskstats.device-exclude") | ||||
| 			*diskstatsDeviceExclude = *oldDiskstatsDeviceExclude | ||||
| 			*config.DiskstatsDeviceExclude = *config.OldDiskstatsDeviceExclude | ||||
| 		} else { | ||||
| 			return deviceFilter{}, errors.New("--collector.diskstats.ignored-devices and --collector.diskstats.device-exclude are mutually exclusive") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if *diskstatsDeviceExclude != "" && *diskstatsDeviceInclude != "" { | ||||
| 	if *config.DiskstatsDeviceExclude != "" && *config.DiskstatsDeviceInclude != "" { | ||||
| 		return deviceFilter{}, errors.New("device-exclude & device-include are mutually exclusive") | ||||
| 	} | ||||
| 
 | ||||
| 	if *diskstatsDeviceExclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed flag --collector.diskstats.device-exclude", "flag", *diskstatsDeviceExclude) | ||||
| 	if *config.DiskstatsDeviceExclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed flag --collector.diskstats.device-exclude", "flag", *config.DiskstatsDeviceExclude) | ||||
| 	} else { | ||||
| 		*config.DiskstatsDeviceExclude = diskstatsDefaultIgnoredDevices | ||||
| 	} | ||||
| 
 | ||||
| 	if *diskstatsDeviceInclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed Flag --collector.diskstats.device-include", "flag", *diskstatsDeviceInclude) | ||||
| 	if *config.DiskstatsDeviceInclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed Flag --collector.diskstats.device-include", "flag", *config.DiskstatsDeviceInclude) | ||||
| 	} | ||||
| 
 | ||||
| 	return newDeviceFilter(*diskstatsDeviceExclude, *diskstatsDeviceInclude), nil | ||||
| 	return newDeviceFilter(*config.DiskstatsDeviceExclude, *config.DiskstatsDeviceInclude), nil | ||||
| } | ||||
|  |  | |||
|  | @ -39,14 +39,17 @@ type diskstatsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) | ||||
| 	registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(DiskstatsDeviceFilterConfig) | ||||
| 		return NewDiskstatsCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewDiskstatsCollector returns a new Collector exposing disk device stats.
 | ||||
| func NewDiskstatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger) (Collector, error) { | ||||
| 	var diskLabelNames = []string{"device"} | ||||
| 
 | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(logger) | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(config, logger) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to parse device filter flags: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -90,19 +90,22 @@ type diskstatsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) | ||||
| 	registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(DiskstatsDeviceFilterConfig) | ||||
| 		return NewDiskstatsCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewDiskstatsCollector returns a new Collector exposing disk device stats.
 | ||||
| // Docs from https://www.kernel.org/doc/Documentation/iostats.txt
 | ||||
| func NewDiskstatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger) (Collector, error) { | ||||
| 	var diskLabelNames = []string{"device"} | ||||
| 	fs, err := blockdevice.NewFS(*procPath, *sysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
| 
 | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(logger) | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(config, logger) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to parse device filter flags: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -45,12 +45,15 @@ type diskstatsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) | ||||
| 	registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(DiskstatsDeviceFilterConfig) | ||||
| 		return NewDiskstatsCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewDiskstatsCollector returns a new Collector exposing disk device stats.
 | ||||
| func NewDiskstatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(logger) | ||||
| func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger) (Collector, error) { | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(config, logger) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to parse device filter flags: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -56,12 +56,15 @@ type diskstatsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("diskstats", defaultEnabled, NewDiskstatsCollector) | ||||
| 	registerCollector("diskstats", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(DiskstatsDeviceFilterConfig) | ||||
| 		return NewDiskstatsCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewDiskstatsCollector returns a new Collector exposing disk device stats.
 | ||||
| func NewDiskstatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(logger) | ||||
| func NewDiskstatsCollector(config DiskstatsDeviceFilterConfig, logger log.Logger) (Collector, error) { | ||||
| 	deviceFilter, err := newDiskstatsDeviceFilter(config, logger) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to parse device filter flags: %w", err) | ||||
| 	} | ||||
|  |  | |||
|  | @ -34,11 +34,13 @@ type dmiCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("dmi", defaultEnabled, NewDMICollector) | ||||
| 	registerCollector("dmi", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewDMICollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewDMICollector returns a new Collector exposing DMI information.
 | ||||
| func NewDMICollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewDMICollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
|  |  | |||
|  | @ -83,10 +83,12 @@ type drbdCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("drbd", defaultDisabled, newDRBDCollector) | ||||
| 	registerCollector("drbd", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return newDRBDCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func newDRBDCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func newDRBDCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &drbdCollector{ | ||||
| 		numerical: map[string]drbdNumericalMetric{ | ||||
| 			"ns": newDRBDNumericalMetric( | ||||
|  |  | |||
|  | @ -42,11 +42,13 @@ type drmCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("drm", defaultDisabled, NewDrmCollector) | ||||
| 	registerCollector("drm", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewDrmCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewDrmCollector returns a new Collector exposing /sys/class/drm/card?/device stats.
 | ||||
| func NewDrmCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewDrmCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
|  |  | |||
|  | @ -43,11 +43,13 @@ type edacCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("edac", defaultEnabled, NewEdacCollector) | ||||
| 	registerCollector("edac", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewEdacCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewEdacCollector returns a new Collector exposing edac stats.
 | ||||
| func NewEdacCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewEdacCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &edacCollector{ | ||||
| 		ceCount: prometheus.NewDesc( | ||||
| 			prometheus.BuildFQName(namespace, edacSubsystem, "correctable_errors_total"), | ||||
|  |  | |||
|  | @ -32,11 +32,13 @@ type entropyCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("entropy", defaultEnabled, NewEntropyCollector) | ||||
| 	registerCollector("entropy", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewEntropyCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewEntropyCollector returns a new Collector exposing entropy stats.
 | ||||
| func NewEntropyCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewEntropyCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
|  |  | |||
|  | @ -30,7 +30,6 @@ import ( | |||
| 	"sync" | ||||
| 	"syscall" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/go-kit/log/level" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
|  | @ -40,11 +39,8 @@ import ( | |||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	ethtoolDeviceInclude   = kingpin.Flag("collector.ethtool.device-include", "Regexp of ethtool devices to include (mutually exclusive to device-exclude).").String() | ||||
| 	ethtoolDeviceExclude   = kingpin.Flag("collector.ethtool.device-exclude", "Regexp of ethtool devices to exclude (mutually exclusive to device-include).").String() | ||||
| 	ethtoolIncludedMetrics = kingpin.Flag("collector.ethtool.metrics-include", "Regexp of ethtool stats to include.").Default(".*").String() | ||||
| 	ethtoolReceivedRegex   = regexp.MustCompile(`(^|_)rx(_|$)`) | ||||
| 	ethtoolTransmitRegex   = regexp.MustCompile(`(^|_)tx(_|$)`) | ||||
| 	ethtoolReceivedRegex = regexp.MustCompile(`(^|_)rx(_|$)`) | ||||
| 	ethtoolTransmitRegex = regexp.MustCompile(`(^|_)tx(_|$)`) | ||||
| ) | ||||
| 
 | ||||
| type Ethtool interface { | ||||
|  | @ -82,10 +78,16 @@ type ethtoolCollector struct { | |||
| 	logger         log.Logger | ||||
| } | ||||
| 
 | ||||
| type EthtoolConfig struct { | ||||
| 	DeviceInclude   *string | ||||
| 	DeviceExclude   *string | ||||
| 	IncludedMetrics *string | ||||
| } | ||||
| 
 | ||||
| // makeEthtoolCollector is the internal constructor for EthtoolCollector.
 | ||||
| // This allows NewEthtoolTestCollector to override its .ethtool interface
 | ||||
| // for testing.
 | ||||
| func makeEthtoolCollector(config NodeCollectorConfig, logger log.Logger) (*ethtoolCollector, error) { | ||||
| func makeEthtoolCollector(config EthtoolConfig, logger log.Logger) (*ethtoolCollector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
|  | @ -100,8 +102,8 @@ func makeEthtoolCollector(config NodeCollectorConfig, logger log.Logger) (*ethto | |||
| 	return ðtoolCollector{ | ||||
| 		fs:             fs, | ||||
| 		ethtool:        ðtoolLibrary{e}, | ||||
| 		deviceFilter:   newDeviceFilter(*ethtoolDeviceExclude, *ethtoolDeviceInclude), | ||||
| 		metricsPattern: regexp.MustCompile(*ethtoolIncludedMetrics), | ||||
| 		deviceFilter:   newDeviceFilter(*config.DeviceExclude, *config.DeviceInclude), | ||||
| 		metricsPattern: regexp.MustCompile(*config.IncludedMetrics), | ||||
| 		logger:         logger, | ||||
| 		entries: map[string]*prometheus.Desc{ | ||||
| 			"rx_bytes": prometheus.NewDesc( | ||||
|  | @ -201,7 +203,10 @@ func makeEthtoolCollector(config NodeCollectorConfig, logger log.Logger) (*ethto | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("ethtool", defaultDisabled, NewEthtoolCollector) | ||||
| 	registerCollector("ethtool", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(EthtoolConfig) | ||||
| 		return NewEthtoolCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // Generate the fully-qualified metric name for the ethool metric.
 | ||||
|  | @ -213,7 +218,7 @@ func buildEthtoolFQName(metric string) string { | |||
| } | ||||
| 
 | ||||
| // NewEthtoolCollector returns a new Collector exposing ethtool stats.
 | ||||
| func NewEthtoolCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewEthtoolCollector(config EthtoolConfig, logger log.Logger) (Collector, error) { | ||||
| 	return makeEthtoolCollector(config, logger) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -28,11 +28,13 @@ type execCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("exec", defaultEnabled, NewExecCollector) | ||||
| 	registerCollector("exec", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewExecCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewExecCollector returns a new Collector exposing system execution statistics.
 | ||||
| func NewExecCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewExecCollector(logger log.Logger) (Collector, error) { | ||||
| 	// From sys/vm/vm_meter.c:
 | ||||
| 	// All are of type CTLTYPE_UINT.
 | ||||
| 	//
 | ||||
|  |  | |||
|  | @ -36,11 +36,13 @@ type fibrechannelCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("fibrechannel", defaultEnabled, NewFibreChannelCollector) | ||||
| 	registerCollector("fibrechannel", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewFibreChannelCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewFibreChannelCollector returns a new Collector exposing FibreChannel stats.
 | ||||
| func NewFibreChannelCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewFibreChannelCollector(logger log.Logger) (Collector, error) { | ||||
| 	var i fibrechannelCollector | ||||
| 	var err error | ||||
| 
 | ||||
|  |  | |||
|  | @ -36,11 +36,13 @@ type fileFDStatCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector(fileFDStatSubsystem, defaultEnabled, NewFileFDStatCollector) | ||||
| 	registerCollector(fileFDStatSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewFileFDStatCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewFileFDStatCollector returns a new Collector exposing file-nr stats.
 | ||||
| func NewFileFDStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewFileFDStatCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &fileFDStatCollector{logger}, nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,8 +20,8 @@ package collector | |||
| import ( | ||||
| 	"errors" | ||||
| 	"regexp" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/go-kit/log/level" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
|  | @ -35,30 +35,7 @@ import ( | |||
| 
 | ||||
| var ( | ||||
| 	mountPointsExcludeSet bool | ||||
| 	mountPointsExclude    = kingpin.Flag( | ||||
| 		"collector.filesystem.mount-points-exclude", | ||||
| 		"Regexp of mount points to exclude for filesystem collector.", | ||||
| 	).Default(defMountPointsExcluded).PreAction(func(c *kingpin.ParseContext) error { | ||||
| 		mountPointsExcludeSet = true | ||||
| 		return nil | ||||
| 	}).String() | ||||
| 	oldMountPointsExcluded = kingpin.Flag( | ||||
| 		"collector.filesystem.ignored-mount-points", | ||||
| 		"Regexp of mount points to ignore for filesystem collector.", | ||||
| 	).Hidden().String() | ||||
| 
 | ||||
| 	fsTypesExcludeSet bool | ||||
| 	fsTypesExclude    = kingpin.Flag( | ||||
| 		"collector.filesystem.fs-types-exclude", | ||||
| 		"Regexp of filesystem types to exclude for filesystem collector.", | ||||
| 	).Default(defFSTypesExcluded).PreAction(func(c *kingpin.ParseContext) error { | ||||
| 		fsTypesExcludeSet = true | ||||
| 		return nil | ||||
| 	}).String() | ||||
| 	oldFSTypesExcluded = kingpin.Flag( | ||||
| 		"collector.filesystem.ignored-fs-types", | ||||
| 		"Regexp of filesystem types to ignore for filesystem collector.", | ||||
| 	).Hidden().String() | ||||
| 	fsTypesExcludeSet     bool | ||||
| 
 | ||||
| 	filesystemLabelNames = []string{"device", "mountpoint", "fstype"} | ||||
| ) | ||||
|  | @ -70,6 +47,7 @@ type filesystemCollector struct { | |||
| 	filesDesc, filesFreeDesc      *prometheus.Desc | ||||
| 	roDesc, deviceErrorDesc       *prometheus.Desc | ||||
| 	logger                        log.Logger | ||||
| 	config                        FilesystemConfig | ||||
| } | ||||
| 
 | ||||
| type filesystemLabels struct { | ||||
|  | @ -82,36 +60,56 @@ type filesystemStats struct { | |||
| 	files, filesFree  float64 | ||||
| 	ro, deviceError   float64 | ||||
| } | ||||
| type FilesystemConfig struct { | ||||
| 	MountPointsExclude     *string | ||||
| 	OldMountPointsExcluded *string | ||||
| 	FSTypesExclude         *string | ||||
| 	OldFSTypesExcluded     *string | ||||
| 	MountTimeout           *time.Duration | ||||
| 	StatWorkerCount        *int | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("filesystem", defaultEnabled, NewFilesystemCollector) | ||||
| 	registerCollector("filesystem", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(FilesystemConfig) | ||||
| 		return NewFilesystemCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewFilesystemCollector returns a new Collector exposing filesystems stats.
 | ||||
| func NewFilesystemCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	if *oldMountPointsExcluded != "" { | ||||
| func NewFilesystemCollector(config FilesystemConfig, logger log.Logger) (Collector, error) { | ||||
| 	if *config.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") | ||||
| 			*mountPointsExclude = *oldMountPointsExcluded | ||||
| 			*config.MountPointsExclude = *config.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) | ||||
| 	} else { | ||||
| 		*config.MountPointsExclude = defMountPointsExcluded | ||||
| 	} | ||||
| 
 | ||||
| 	if *oldFSTypesExcluded != "" { | ||||
| 	if *config.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") | ||||
| 			*fsTypesExclude = *oldFSTypesExcluded | ||||
| 			*config.FSTypesExclude = *config.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) | ||||
| 
 | ||||
| 	} else { | ||||
| 		*config.FSTypesExclude = defFSTypesExcluded | ||||
| 	} | ||||
| 
 | ||||
| 	subsystem := "filesystem" | ||||
| 	level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.mount-points-exclude", "flag", *mountPointsExclude) | ||||
| 	mountPointPattern := regexp.MustCompile(*mountPointsExclude) | ||||
| 	level.Info(logger).Log("msg", "Parsed flag --collector.filesystem.fs-types-exclude", "flag", *fsTypesExclude) | ||||
| 	filesystemsTypesPattern := regexp.MustCompile(*fsTypesExclude) | ||||
| 	mountPointPattern := regexp.MustCompile(*config.MountPointsExclude) | ||||
| 	filesystemsTypesPattern := regexp.MustCompile(*config.FSTypesExclude) | ||||
| 
 | ||||
| 	sizeDesc := prometheus.NewDesc( | ||||
| 		prometheus.BuildFQName(namespace, subsystem, "size_bytes"), | ||||
|  | @ -166,6 +164,7 @@ func NewFilesystemCollector(config NodeCollectorConfig, logger log.Logger) (Coll | |||
| 		roDesc:                     roDesc, | ||||
| 		deviceErrorDesc:            deviceErrorDesc, | ||||
| 		logger:                     logger, | ||||
| 		config:                     config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -26,7 +26,6 @@ import ( | |||
| 	"sync" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/go-kit/log/level" | ||||
| 	"golang.org/x/sys/unix" | ||||
|  | @ -37,12 +36,6 @@ const ( | |||
| 	defFSTypesExcluded     = "^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|iso9660|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$" | ||||
| ) | ||||
| 
 | ||||
| var mountTimeout = kingpin.Flag("collector.filesystem.mount-timeout", | ||||
| 	"how long to wait for a mount to respond before marking it as stale"). | ||||
| 	Hidden().Default("5s").Duration() | ||||
| var statWorkerCount = kingpin.Flag("collector.filesystem.stat-workers", | ||||
| 	"how many stat calls to process simultaneously"). | ||||
| 	Hidden().Default("4").Int() | ||||
| var stuckMounts = make(map[string]struct{}) | ||||
| var stuckMountsMtx = &sync.Mutex{} | ||||
| 
 | ||||
|  | @ -57,7 +50,7 @@ func (c *filesystemCollector) GetStats() ([]filesystemStats, error) { | |||
| 	statChan := make(chan filesystemStats) | ||||
| 	wg := sync.WaitGroup{} | ||||
| 
 | ||||
| 	workerCount := *statWorkerCount | ||||
| 	workerCount := *c.config.StatWorkerCount | ||||
| 	if workerCount < 1 { | ||||
| 		workerCount = 1 | ||||
| 	} | ||||
|  | @ -110,7 +103,7 @@ func (c *filesystemCollector) GetStats() ([]filesystemStats, error) { | |||
| 
 | ||||
| func (c *filesystemCollector) processStat(labels filesystemLabels) filesystemStats { | ||||
| 	success := make(chan struct{}) | ||||
| 	go stuckMountWatcher(labels.mountPoint, success, c.logger) | ||||
| 	go stuckMountWatcher(c.config.MountTimeout, labels.mountPoint, success, c.logger) | ||||
| 
 | ||||
| 	buf := new(unix.Statfs_t) | ||||
| 	err := unix.Statfs(rootfsFilePath(labels.mountPoint), buf) | ||||
|  | @ -153,7 +146,7 @@ func (c *filesystemCollector) processStat(labels filesystemLabels) filesystemSta | |||
| // stuckMountWatcher listens on the given success channel and if the channel closes
 | ||||
| // then the watcher does nothing. If instead the timeout is reached, the
 | ||||
| // mount point that is being watched is marked as stuck.
 | ||||
| func stuckMountWatcher(mountPoint string, success chan struct{}, logger log.Logger) { | ||||
| func stuckMountWatcher(mountTimeout *time.Duration, mountPoint string, success chan struct{}, logger log.Logger) { | ||||
| 	mountCheckTimer := time.NewTimer(*mountTimeout) | ||||
| 	defer mountCheckTimer.Stop() | ||||
| 	select { | ||||
|  |  | |||
|  | @ -24,7 +24,6 @@ import ( | |||
| 	"strconv" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/go-kit/log/level" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
|  | @ -32,9 +31,6 @@ import ( | |||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	collectorHWmonChipInclude = kingpin.Flag("collector.hwmon.chip-include", "Regexp of hwmon chip to include (mutually exclusive to device-exclude).").String() | ||||
| 	collectorHWmonChipExclude = kingpin.Flag("collector.hwmon.chip-exclude", "Regexp of hwmon chip to exclude (mutually exclusive to device-include).").String() | ||||
| 
 | ||||
| 	hwmonInvalidMetricChars = regexp.MustCompile("[^a-z0-9:_]") | ||||
| 	hwmonFilenameFormat     = regexp.MustCompile(`^(?P<type>[^0-9]+)(?P<id>[0-9]*)?(_(?P<property>.+))?$`) | ||||
| 	hwmonLabelDesc          = []string{"chip", "sensor"} | ||||
|  | @ -47,7 +43,10 @@ var ( | |||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("hwmon", defaultEnabled, NewHwMonCollector) | ||||
| 	registerCollector("hwmon", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(HwMonConfig) | ||||
| 		return NewHwMonCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| type hwMonCollector struct { | ||||
|  | @ -55,13 +54,18 @@ type hwMonCollector struct { | |||
| 	logger       log.Logger | ||||
| } | ||||
| 
 | ||||
| type HwMonConfig struct { | ||||
| 	ChipInclude *string | ||||
| 	ChipExclude *string | ||||
| } | ||||
| 
 | ||||
| // NewHwMonCollector returns a new Collector exposing /sys/class/hwmon stats
 | ||||
| // (similar to lm-sensors).
 | ||||
| func NewHwMonCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewHwMonCollector(config HwMonConfig, logger log.Logger) (Collector, error) { | ||||
| 
 | ||||
| 	return &hwMonCollector{ | ||||
| 		logger:       logger, | ||||
| 		deviceFilter: newDeviceFilter(*collectorHWmonChipExclude, *collectorHWmonChipInclude), | ||||
| 		deviceFilter: newDeviceFilter(*config.ChipExclude, *config.ChipInclude), | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -36,11 +36,13 @@ type infinibandCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("infiniband", defaultEnabled, NewInfiniBandCollector) | ||||
| 	registerCollector("infiniband", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewInfiniBandCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewInfiniBandCollector returns a new Collector exposing InfiniBand stats.
 | ||||
| func NewInfiniBandCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewInfiniBandCollector(logger log.Logger) (Collector, error) { | ||||
| 	var i infinibandCollector | ||||
| 	var err error | ||||
| 
 | ||||
|  |  | |||
|  | @ -28,11 +28,13 @@ type interruptsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("interrupts", defaultDisabled, NewInterruptsCollector) | ||||
| 	registerCollector("interrupts", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewInterruptsCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewInterruptsCollector returns a new Collector exposing interrupts stats.
 | ||||
| func NewInterruptsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewInterruptsCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &interruptsCollector{ | ||||
| 		desc: typedDesc{prometheus.NewDesc( | ||||
| 			namespace+"_interrupts_total", | ||||
|  |  | |||
|  | @ -24,7 +24,6 @@ import ( | |||
| 	"strconv" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/go-kit/log/level" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
|  | @ -64,27 +63,37 @@ var ( | |||
| 		ipvsLabelProto, | ||||
| 		ipvsLabelLocalMark, | ||||
| 	} | ||||
| 	ipvsLabels = kingpin.Flag("collector.ipvs.backend-labels", "Comma separated list for IPVS backend stats labels.").Default(strings.Join(fullIpvsBackendLabels, ",")).String() | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("ipvs", defaultEnabled, NewIPVSCollector) | ||||
| 	registerCollector("ipvs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(IPVSConfig) | ||||
| 		return NewIPVSCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| type IPVSConfig struct { | ||||
| 	Labels *string | ||||
| } | ||||
| 
 | ||||
| // 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 NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewIPVSCollector(config IPVSConfig, logger log.Logger) (Collector, error) { | ||||
| 	return newIPVSCollector(config, logger) | ||||
| } | ||||
| 
 | ||||
| func newIPVSCollector(config NodeCollectorConfig, logger log.Logger) (*ipvsCollector, error) { | ||||
| func newIPVSCollector(config IPVSConfig, logger log.Logger) (*ipvsCollector, error) { | ||||
| 	var ( | ||||
| 		c         ipvsCollector | ||||
| 		err       error | ||||
| 		subsystem = "ipvs" | ||||
| 	) | ||||
| 
 | ||||
| 	if c.backendLabels, err = c.parseIpvsLabels(*ipvsLabels); err != nil { | ||||
| 	if *config.Labels == "" { | ||||
| 		*config.Labels = strings.Join(fullIpvsBackendLabels, ",") | ||||
| 	} | ||||
| 
 | ||||
| 	if c.backendLabels, err = c.parseIpvsLabels(*config.Labels); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -35,7 +35,9 @@ type ksmdCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("ksmd", defaultDisabled, NewKsmdCollector) | ||||
| 	registerCollector("ksmd", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewKsmdCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func getCanonicalMetricName(filename string) string { | ||||
|  | @ -50,7 +52,7 @@ func getCanonicalMetricName(filename string) string { | |||
| } | ||||
| 
 | ||||
| // NewKsmdCollector returns a new Collector exposing kernel/system statistics.
 | ||||
| func NewKsmdCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewKsmdCollector(logger log.Logger) (Collector, error) { | ||||
| 	subsystem := "ksmd" | ||||
| 	descs := make(map[string]*prometheus.Desc) | ||||
| 
 | ||||
|  |  | |||
|  | @ -30,10 +30,12 @@ type lnstatCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("lnstat", defaultDisabled, NewLnstatCollector) | ||||
| 	registerCollector("lnstat", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewLnstatCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func NewLnstatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewLnstatCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &lnstatCollector{logger}, nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -31,11 +31,13 @@ type loadavgCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("loadavg", defaultEnabled, NewLoadavgCollector) | ||||
| 	registerCollector("loadavg", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewLoadavgCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewLoadavgCollector returns a new Collector exposing load average stats.
 | ||||
| func NewLoadavgCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewLoadavgCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &loadavgCollector{ | ||||
| 		metric: []typedDesc{ | ||||
| 			{prometheus.NewDesc(namespace+"_load1", "1m load average.", nil, nil), prometheus.GaugeValue}, | ||||
|  |  | |||
|  | @ -83,10 +83,13 @@ type logindSeatEntry struct { | |||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("logind", defaultDisabled, NewLogindCollector) | ||||
| 	registerCollector("logind", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewLogindCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewLogindCollector returns a new Collector exposing logind statistics.
 | ||||
| func NewLogindCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewLogindCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &logindCollector{logger}, nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -32,11 +32,13 @@ type mdadmCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("mdadm", defaultEnabled, NewMdadmCollector) | ||||
| 	registerCollector("mdadm", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewMdadmCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewMdadmCollector returns a new Collector exposing raid statistics.
 | ||||
| func NewMdadmCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewMdadmCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &mdadmCollector{logger}, nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -35,11 +35,13 @@ type meminfoCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("meminfo", defaultEnabled, NewMeminfoCollector) | ||||
| 	registerCollector("meminfo", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewMeminfoCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewMeminfoCollector returns a new Collector exposing memory stats.
 | ||||
| func NewMeminfoCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewMeminfoCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &meminfoCollector{logger}, nil | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -37,7 +37,9 @@ type memoryCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("meminfo", defaultEnabled, NewMemoryCollector) | ||||
| 	registerCollector("meminfo", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewMemoryCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewMemoryCollector returns a new Collector exposing memory stats.
 | ||||
|  |  | |||
|  | @ -107,11 +107,13 @@ type nfsDeviceIdentifier struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("mountstats", defaultDisabled, NewMountStatsCollector) | ||||
| 	registerCollector("mountstats", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewMountStatsCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewMountStatsCollector returns a new Collector exposing NFS statistics.
 | ||||
| func NewMountStatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewMountStatsCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
|  |  | |||
|  | @ -23,49 +23,54 @@ import ( | |||
| 	"os" | ||||
| 	"regexp" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/go-kit/log/level" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
| 	"github.com/prometheus/procfs/sysfs" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	netclassIgnoredDevices = kingpin.Flag("collector.netclass.ignored-devices", "Regexp of net devices to ignore for netclass collector.").Default("^$").String() | ||||
| 	netclassInvalidSpeed   = kingpin.Flag("collector.netclass.ignore-invalid-speed", "Ignore devices where the speed is invalid. This will be the default behavior in 2.x.").Bool() | ||||
| 	netclassNetlink        = kingpin.Flag("collector.netclass.netlink", "Use netlink to gather stats instead of /proc/net/dev.").Default("false").Bool() | ||||
| ) | ||||
| 
 | ||||
| type netClassCollector struct { | ||||
| 	fs                    sysfs.FS | ||||
| 	subsystem             string | ||||
| 	ignoredDevicesPattern *regexp.Regexp | ||||
| 	metricDescs           map[string]*prometheus.Desc | ||||
| 	logger                log.Logger | ||||
| 	config                NetClassConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("netclass", defaultEnabled, NewNetClassCollector) | ||||
| 	registerCollector("netclass", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(NetClassConfig) | ||||
| 		return NewNetClassCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| type NetClassConfig struct { | ||||
| 	IgnoredDevices *string | ||||
| 	InvalidSpeed   *bool | ||||
| 	Netlink        *bool | ||||
| 	RTNLWithStats  *bool | ||||
| } | ||||
| 
 | ||||
| // NewNetClassCollector returns a new Collector exposing network class stats.
 | ||||
| func NewNetClassCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewNetClassCollector(config NetClassConfig, logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
| 	} | ||||
| 	pattern := regexp.MustCompile(*netclassIgnoredDevices) | ||||
| 	pattern := regexp.MustCompile(*config.IgnoredDevices) | ||||
| 	return &netClassCollector{ | ||||
| 		fs:                    fs, | ||||
| 		subsystem:             "network", | ||||
| 		ignoredDevicesPattern: pattern, | ||||
| 		metricDescs:           map[string]*prometheus.Desc{}, | ||||
| 		logger:                logger, | ||||
| 		config:                config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func (c *netClassCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	if *netclassNetlink { | ||||
| 	if *c.config.Netlink { | ||||
| 		return c.netClassRTNLUpdate(ch) | ||||
| 	} | ||||
| 	return c.netClassSysfsUpdate(ch) | ||||
|  | @ -121,7 +126,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 || !*netclassInvalidSpeed { | ||||
| 			if *ifaceInfo.Speed >= 0 || !*c.config.InvalidSpeed { | ||||
| 				speedBytes := int64(*ifaceInfo.Speed * 1000 * 1000 / 8) | ||||
| 				pushMetric(ch, c.getFieldDesc("speed_bytes"), "speed_bytes", speedBytes, prometheus.GaugeValue, ifaceInfo.Name) | ||||
| 			} | ||||
|  |  | |||
|  | @ -22,7 +22,6 @@ import ( | |||
| 	"io/fs" | ||||
| 	"path/filepath" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log/level" | ||||
| 	"github.com/jsimonetti/rtnetlink" | ||||
| 	"github.com/mdlayher/ethtool" | ||||
|  | @ -31,8 +30,7 @@ import ( | |||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	netclassRTNLWithStats = kingpin.Flag("collector.netclass_rtnl.with-stats", "Expose the statistics for each network device, replacing netdev collector.").Bool() | ||||
| 	operstateStr          = []string{ | ||||
| 	operstateStr = []string{ | ||||
| 		"unknown", "notpresent", "down", "lowerlayerdown", "testing", | ||||
| 		"dormant", "up", | ||||
| 	} | ||||
|  | @ -142,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 netclassRTNLWithStats == nil || !*netclassRTNLWithStats || msg.Attributes.Stats64 == nil { | ||||
| 		if c.config.RTNLWithStats == nil || !*c.config.RTNLWithStats || msg.Attributes.Stats64 == nil { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
|  | @ -24,72 +24,77 @@ import ( | |||
| 	"strconv" | ||||
| 	"sync" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/go-kit/log/level" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	netdevDeviceInclude    = kingpin.Flag("collector.netdev.device-include", "Regexp of net devices to include (mutually exclusive to device-exclude).").String() | ||||
| 	oldNetdevDeviceInclude = kingpin.Flag("collector.netdev.device-whitelist", "DEPRECATED: Use collector.netdev.device-include").Hidden().String() | ||||
| 	netdevDeviceExclude    = kingpin.Flag("collector.netdev.device-exclude", "Regexp of net devices to exclude (mutually exclusive to device-include).").String() | ||||
| 	oldNetdevDeviceExclude = kingpin.Flag("collector.netdev.device-blacklist", "DEPRECATED: Use collector.netdev.device-exclude").Hidden().String() | ||||
| 	netdevAddressInfo      = kingpin.Flag("collector.netdev.address-info", "Collect address-info for every device").Bool() | ||||
| 	netdevDetailedMetrics  = kingpin.Flag("collector.netdev.enable-detailed-metrics", "Use (incompatible) metric names that provide more detailed stats on Linux").Bool() | ||||
| ) | ||||
| 
 | ||||
| type netDevCollector struct { | ||||
| 	subsystem        string | ||||
| 	deviceFilter     deviceFilter | ||||
| 	metricDescsMutex sync.Mutex | ||||
| 	metricDescs      map[string]*prometheus.Desc | ||||
| 	logger           log.Logger | ||||
| 	config           NetDevConfig | ||||
| } | ||||
| 
 | ||||
| type netDevStats map[string]map[string]uint64 | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("netdev", defaultEnabled, NewNetDevCollector) | ||||
| 	registerCollector("netdev", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(NetDevConfig) | ||||
| 		return NewNetDevCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| type NetDevConfig struct { | ||||
| 	DeviceInclude    *string | ||||
| 	OldDeviceInclude *string | ||||
| 	DeviceExclude    *string | ||||
| 	OldDeviceExclude *string | ||||
| 	AddressInfo      *bool | ||||
| 	DetailedMetrics  *bool | ||||
| 	Netlink          *bool | ||||
| } | ||||
| 
 | ||||
| // NewNetDevCollector returns a new Collector exposing network device stats.
 | ||||
| func NewNetDevCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	if *oldNetdevDeviceInclude != "" { | ||||
| 		if *netdevDeviceInclude == "" { | ||||
| func NewNetDevCollector(config NetDevConfig, logger log.Logger) (Collector, error) { | ||||
| 	if *config.OldDeviceInclude != "" { | ||||
| 		if *config.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") | ||||
| 			*netdevDeviceInclude = *oldNetdevDeviceInclude | ||||
| 			*config.DeviceInclude = *config.OldDeviceInclude | ||||
| 		} else { | ||||
| 			return nil, errors.New("--collector.netdev.device-whitelist and --collector.netdev.device-include are mutually exclusive") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if *oldNetdevDeviceExclude != "" { | ||||
| 		if *netdevDeviceExclude == "" { | ||||
| 	if *config.OldDeviceExclude != "" { | ||||
| 		if *config.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") | ||||
| 			*netdevDeviceExclude = *oldNetdevDeviceExclude | ||||
| 			*config.DeviceExclude = *config.OldDeviceExclude | ||||
| 		} else { | ||||
| 			return nil, errors.New("--collector.netdev.device-blacklist and --collector.netdev.device-exclude are mutually exclusive") | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if *netdevDeviceExclude != "" && *netdevDeviceInclude != "" { | ||||
| 	if *config.DeviceExclude != "" && *config.DeviceInclude != "" { | ||||
| 		return nil, errors.New("device-exclude & device-include are mutually exclusive") | ||||
| 	} | ||||
| 
 | ||||
| 	if *netdevDeviceExclude != "" { | ||||
| 	if *config.DeviceExclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed flag --collector.netdev.device-exclude", "flag", *netdevDeviceExclude) | ||||
| 	} | ||||
| 
 | ||||
| 	if *netdevDeviceInclude != "" { | ||||
| 	if *config.DeviceInclude != "" { | ||||
| 		level.Info(logger).Log("msg", "Parsed Flag --collector.netdev.device-include", "flag", *netdevDeviceInclude) | ||||
| 	} | ||||
| 
 | ||||
| 	return &netDevCollector{ | ||||
| 		subsystem:    "network", | ||||
| 		deviceFilter: newDeviceFilter(*netdevDeviceExclude, *netdevDeviceInclude), | ||||
| 		deviceFilter: newDeviceFilter(*config.DeviceExclude, *config.DeviceInclude), | ||||
| 		metricDescs:  map[string]*prometheus.Desc{}, | ||||
| 		logger:       logger, | ||||
| 		config:       config, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
|  | @ -110,12 +115,12 @@ func (c *netDevCollector) metricDesc(key string) *prometheus.Desc { | |||
| } | ||||
| 
 | ||||
| func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	netDev, err := getNetDevStats(&c.deviceFilter, c.logger) | ||||
| 	netDev, err := getNetDevStats(c.config.Netlink, &c.deviceFilter, c.logger) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("couldn't get netstats: %w", err) | ||||
| 	} | ||||
| 	for dev, devStats := range netDev { | ||||
| 		if !*netdevDetailedMetrics { | ||||
| 		if !*c.config.DetailedMetrics { | ||||
| 			legacy(devStats) | ||||
| 		} | ||||
| 		for key, value := range devStats { | ||||
|  | @ -123,7 +128,7 @@ func (c *netDevCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 			ch <- prometheus.MustNewConstMetric(desc, prometheus.CounterValue, float64(value), dev) | ||||
| 		} | ||||
| 	} | ||||
| 	if *netdevAddressInfo { | ||||
| 	if *c.config.AddressInfo { | ||||
| 		interfaces, err := net.Interfaces() | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("could not get network interfaces: %w", err) | ||||
|  |  | |||
|  | @ -19,18 +19,13 @@ package collector | |||
| import ( | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/go-kit/log/level" | ||||
| 	"github.com/jsimonetti/rtnetlink" | ||||
| 	"github.com/prometheus/procfs" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	netDevNetlink = kingpin.Flag("collector.netdev.netlink", "Use netlink to gather stats instead of /proc/net/dev.").Default("true").Bool() | ||||
| ) | ||||
| 
 | ||||
| func getNetDevStats(filter *deviceFilter, logger log.Logger) (netDevStats, error) { | ||||
| func getNetDevStats(netDevNetlink *bool, filter *deviceFilter, logger log.Logger) (netDevStats, error) { | ||||
| 	if *netDevNetlink { | ||||
| 		return netlinkStats(filter, logger) | ||||
| 	} | ||||
|  |  | |||
|  | @ -33,10 +33,12 @@ const ( | |||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("netisr", defaultEnabled, NewNetisrCollector) | ||||
| 	registerCollector("netisr", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewNetisrCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func NewNetisrCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewNetisrCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &netisrCollector{ | ||||
| 		sysctls: []bsdSysctl{ | ||||
| 			{ | ||||
|  |  | |||
|  | @ -26,7 +26,6 @@ import ( | |||
| 	"strconv" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
| ) | ||||
|  | @ -35,23 +34,26 @@ const ( | |||
| 	netStatsSubsystem = "netstat" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	netStatFields = kingpin.Flag("collector.netstat.fields", "Regexp of fields to return for netstat collector.").Default("^(.*_(InErrors|InErrs)|Ip_Forwarding|Ip(6|Ext)_(InOctets|OutOctets)|Icmp6?_(InMsgs|OutMsgs)|TcpExt_(Listen.*|Syncookies.*|TCPSynRetrans|TCPTimeouts)|Tcp_(ActiveOpens|InSegs|OutSegs|OutRsts|PassiveOpens|RetransSegs|CurrEstab)|Udp6?_(InDatagrams|OutDatagrams|NoPorts|RcvbufErrors|SndbufErrors))$").String() | ||||
| ) | ||||
| 
 | ||||
| type netStatCollector struct { | ||||
| 	fieldPattern *regexp.Regexp | ||||
| 	logger       log.Logger | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("netstat", defaultEnabled, NewNetStatCollector) | ||||
| 	registerCollector(netStatsSubsystem, defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(NetStatConfig) | ||||
| 		return NewNetStatCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| type NetStatConfig struct { | ||||
| 	Fields *string | ||||
| } | ||||
| 
 | ||||
| // NewNetStatCollector takes and returns
 | ||||
| // a new Collector exposing network stats.
 | ||||
| func NewNetStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	pattern := regexp.MustCompile(*netStatFields) | ||||
| func NewNetStatCollector(config NetStatConfig, logger log.Logger) (Collector, error) { | ||||
| 	pattern := regexp.MustCompile(*config.Fields) | ||||
| 	return &netStatCollector{ | ||||
| 		fieldPattern: pattern, | ||||
| 		logger:       logger, | ||||
|  |  | |||
|  | @ -18,10 +18,11 @@ package collector | |||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"golang.org/x/sys/unix" | ||||
| 	"net" | ||||
| 	"strconv" | ||||
| 
 | ||||
| 	"golang.org/x/sys/unix" | ||||
| 
 | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/jsimonetti/rtnetlink" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
|  | @ -34,11 +35,13 @@ type networkRouteCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("network_route", defaultDisabled, NewNetworkRouteCollector) | ||||
| 	registerCollector("network_route", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewNetworkRouteCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewNetworkRouteCollector returns a new Collector exposing systemd statistics.
 | ||||
| func NewNetworkRouteCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewNetworkRouteCollector(logger log.Logger) (Collector, error) { | ||||
| 	const subsystem = "network" | ||||
| 
 | ||||
| 	routeInfoDesc := prometheus.NewDesc( | ||||
|  |  | |||
|  | @ -44,11 +44,13 @@ type nfsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("nfs", defaultEnabled, NewNfsCollector) | ||||
| 	registerCollector("nfs", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewNfsCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewNfsCollector returns a new Collector exposing NFS statistics.
 | ||||
| func NewNfsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewNfsCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := nfs.NewFS(*procPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
|  |  | |||
|  | @ -36,7 +36,9 @@ type nfsdCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("nfsd", defaultEnabled, NewNFSdCollector) | ||||
| 	registerCollector("nfsd", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewNFSdCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| const ( | ||||
|  | @ -44,7 +46,7 @@ const ( | |||
| ) | ||||
| 
 | ||||
| // NewNFSdCollector returns a new Collector exposing /proc/net/rpc/nfsd statistics.
 | ||||
| func NewNFSdCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewNFSdCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := nfs.NewFS(*procPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
|  |  | |||
|  | @ -22,7 +22,6 @@ import ( | |||
| 	"sync" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/beevik/ntp" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/go-kit/log/level" | ||||
|  | @ -35,16 +34,6 @@ const ( | |||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	ntpServer          = kingpin.Flag("collector.ntp.server", "NTP server to use for ntp collector").Default("127.0.0.1").String() | ||||
| 	ntpServerPort      = kingpin.Flag("collector.ntp.server-port", "UDP port number to connect to on NTP server").Default("123").Int() | ||||
| 	ntpProtocolVersion = kingpin.Flag("collector.ntp.protocol-version", "NTP protocol version").Default("4").Int() | ||||
| 	ntpServerIsLocal   = kingpin.Flag("collector.ntp.server-is-local", "Certify that collector.ntp.server address is not a public ntp server").Default("false").Bool() | ||||
| 	ntpIPTTL           = kingpin.Flag("collector.ntp.ip-ttl", "IP TTL to use while sending NTP query").Default("1").Int() | ||||
| 	// 3.46608s ~ 1.5s + PHI * (1 << maxPoll), where 1.5s is MAXDIST from ntp.org, it is 1.0 in RFC5905
 | ||||
| 	// max-distance option is used as-is without phi*(1<<poll)
 | ||||
| 	ntpMaxDistance     = kingpin.Flag("collector.ntp.max-distance", "Max accumulated distance to the root").Default("3.46608s").Duration() | ||||
| 	ntpOffsetTolerance = kingpin.Flag("collector.ntp.local-offset-tolerance", "Offset between local clock and local ntpd time to tolerate").Default("1ms").Duration() | ||||
| 
 | ||||
| 	leapMidnight      time.Time | ||||
| 	leapMidnightMutex = &sync.Mutex{} | ||||
| ) | ||||
|  | @ -52,32 +41,46 @@ var ( | |||
| type ntpCollector struct { | ||||
| 	stratum, leap, rtt, offset, reftime, rootDelay, rootDispersion, sanity typedDesc | ||||
| 	logger                                                                 log.Logger | ||||
| 	config                                                                 NTPConfig | ||||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("ntp", defaultDisabled, NewNtpCollector) | ||||
| 	registerCollector("ntp", defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(NTPConfig) | ||||
| 		return NewNtpCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| type NTPConfig struct { | ||||
| 	Server          *string | ||||
| 	ServerPort      *int | ||||
| 	ProtocolVersion *int | ||||
| 	ServerIsLocal   *bool | ||||
| 	IPTTL           *int | ||||
| 	MaxDistance     *time.Duration | ||||
| 	OffsetTolerance *time.Duration | ||||
| } | ||||
| 
 | ||||
| // NewNtpCollector returns a new Collector exposing sanity of local NTP server.
 | ||||
| // 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 NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	ipaddr := net.ParseIP(*ntpServer) | ||||
| 	if !*ntpServerIsLocal && (ipaddr == nil || !ipaddr.IsLoopback()) { | ||||
| func NewNtpCollector(config NTPConfig, logger log.Logger) (Collector, error) { | ||||
| 	ipaddr := net.ParseIP(*config.Server) | ||||
| 	if !*config.ServerIsLocal && (ipaddr == nil || !ipaddr.IsLoopback()) { | ||||
| 		return nil, fmt.Errorf("only IP address of local NTP server is valid for --collector.ntp.server") | ||||
| 	} | ||||
| 
 | ||||
| 	if *ntpProtocolVersion < 2 || *ntpProtocolVersion > 4 { | ||||
| 		return nil, fmt.Errorf("invalid NTP protocol version %d; must be 2, 3, or 4", *ntpProtocolVersion) | ||||
| 	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 *ntpOffsetTolerance < 0 { | ||||
| 	if *config.OffsetTolerance < 0 { | ||||
| 		return nil, fmt.Errorf("offset tolerance must be non-negative") | ||||
| 	} | ||||
| 
 | ||||
| 	if *ntpServerPort < 1 || *ntpServerPort > 65535 { | ||||
| 		return nil, fmt.Errorf("invalid NTP port number %d; must be between 1 and 65535 inclusive", *ntpServerPort) | ||||
| 	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) | ||||
| 	} | ||||
| 
 | ||||
| 	level.Warn(logger).Log("msg", "This collector is deprecated and will be removed in the next major version release.") | ||||
|  | @ -127,11 +130,11 @@ func NewNtpCollector(config NodeCollectorConfig, logger log.Logger) (Collector, | |||
| } | ||||
| 
 | ||||
| func (c *ntpCollector) Update(ch chan<- prometheus.Metric) error { | ||||
| 	resp, err := ntp.QueryWithOptions(*ntpServer, ntp.QueryOptions{ | ||||
| 		Version: *ntpProtocolVersion, | ||||
| 		TTL:     *ntpIPTTL, | ||||
| 	resp, err := ntp.QueryWithOptions(*c.config.Server, ntp.QueryOptions{ | ||||
| 		Version: *c.config.ProtocolVersion, | ||||
| 		TTL:     *c.config.IPTTL, | ||||
| 		Timeout: time.Second, // default `ntpdate` timeout
 | ||||
| 		Port:    *ntpServerPort, | ||||
| 		Port:    *c.config.ServerPort, | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("couldn't get SNTP reply: %w", err) | ||||
|  | @ -156,7 +159,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 := *ntpOffsetTolerance | ||||
| 	maxerr := *c.config.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
 | ||||
|  | @ -168,7 +171,7 @@ func (c *ntpCollector) Update(ch chan<- prometheus.Metric) error { | |||
| 	} | ||||
| 	leapMidnightMutex.Unlock() | ||||
| 
 | ||||
| 	if resp.Validate() == nil && resp.RootDistance <= *ntpMaxDistance && resp.MinError <= maxerr { | ||||
| 	if resp.Validate() == nil && resp.RootDistance <= *c.config.MaxDistance && resp.MinError <= maxerr { | ||||
| 		ch <- c.sanity.mustNewConstMetric(1) | ||||
| 	} else { | ||||
| 		ch <- c.sanity.mustNewConstMetric(0) | ||||
|  |  | |||
|  | @ -33,11 +33,13 @@ type nvmeCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("nvme", defaultEnabled, NewNVMeCollector) | ||||
| 	registerCollector("nvme", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewNVMeCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewNVMeCollector returns a new Collector exposing NVMe stats.
 | ||||
| func NewNVMeCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewNVMeCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := sysfs.NewFS(*sysPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open sysfs: %w", err) | ||||
|  |  | |||
|  | @ -77,11 +77,13 @@ type Dict struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("os", defaultEnabled, NewOSCollector) | ||||
| 	registerCollector("os", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewOSCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewOSCollector returns a new Collector exposing os-release information.
 | ||||
| func NewOSCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewOSCollector(logger log.Logger) (Collector, error) { | ||||
| 	return &osReleaseCollector{ | ||||
| 		logger: logger, | ||||
| 		infoDesc: prometheus.NewDesc( | ||||
|  |  | |||
|  | @ -22,7 +22,6 @@ import ( | |||
| 	"strconv" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/go-kit/log/level" | ||||
| 	"github.com/hodgesds/perf-utils" | ||||
|  | @ -34,19 +33,22 @@ const ( | |||
| 	perfSubsystem = "perf" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	perfCPUsFlag       = kingpin.Flag("collector.perf.cpus", "List of CPUs from which perf metrics should be collected").Default("").String() | ||||
| 	perfTracepointFlag = kingpin.Flag("collector.perf.tracepoint", "perf tracepoint that should be collected").Strings() | ||||
| 	perfNoHwProfiler   = kingpin.Flag("collector.perf.disable-hardware-profilers", "disable perf hardware profilers").Default("false").Bool() | ||||
| 	perfHwProfilerFlag = kingpin.Flag("collector.perf.hardware-profilers", "perf hardware profilers that should be collected").Strings() | ||||
| 	perfNoSwProfiler   = kingpin.Flag("collector.perf.disable-software-profilers", "disable perf software profilers").Default("false").Bool() | ||||
| 	perfSwProfilerFlag = kingpin.Flag("collector.perf.software-profilers", "perf software profilers that should be collected").Strings() | ||||
| 	perfNoCaProfiler   = kingpin.Flag("collector.perf.disable-cache-profilers", "disable perf cache profilers").Default("false").Bool() | ||||
| 	perfCaProfilerFlag = kingpin.Flag("collector.perf.cache-profilers", "perf cache profilers that should be collected").Strings() | ||||
| ) | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector(perfSubsystem, defaultDisabled, NewPerfCollector) | ||||
| 	registerCollector(perfSubsystem, defaultDisabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(PerfConfig) | ||||
| 		return NewPerfCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| type PerfConfig struct { | ||||
| 	CPUs           *string | ||||
| 	Tracepoint     *[]string | ||||
| 	NoHwProfiler   *bool | ||||
| 	HwProfiler     *[]string | ||||
| 	NoSwProfiler   *bool | ||||
| 	SwProfiler     *[]string | ||||
| 	NoCaProfiler   *bool | ||||
| 	CaProfilerFlag *[]string | ||||
| } | ||||
| 
 | ||||
| var ( | ||||
|  | @ -301,7 +303,7 @@ func newPerfTracepointCollector( | |||
| 
 | ||||
| // NewPerfCollector returns a new perf based collector, it creates a profiler
 | ||||
| // per CPU.
 | ||||
| func NewPerfCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewPerfCollector(config PerfConfig, logger log.Logger) (Collector, error) { | ||||
| 	collector := &perfCollector{ | ||||
| 		perfHwProfilers:     map[int]*perf.HardwareProfiler{}, | ||||
| 		perfSwProfilers:     map[int]*perf.SoftwareProfiler{}, | ||||
|  | @ -316,8 +318,8 @@ func NewPerfCollector(config NodeCollectorConfig, logger log.Logger) (Collector, | |||
| 		cpus []int | ||||
| 		err  error | ||||
| 	) | ||||
| 	if perfCPUsFlag != nil && *perfCPUsFlag != "" { | ||||
| 		cpus, err = perfCPUFlagToCPUs(*perfCPUsFlag) | ||||
| 	if config.CPUs != nil && *config.CPUs != "" { | ||||
| 		cpus, err = perfCPUFlagToCPUs(*config.CPUs) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | @ -329,8 +331,8 @@ func NewPerfCollector(config NodeCollectorConfig, logger log.Logger) (Collector, | |||
| 	} | ||||
| 
 | ||||
| 	// First configure any tracepoints.
 | ||||
| 	if *perfTracepointFlag != nil && len(*perfTracepointFlag) > 0 { | ||||
| 		tracepointCollector, err := newPerfTracepointCollector(logger, *perfTracepointFlag, cpus) | ||||
| 	if *config.Tracepoint != nil && len(*config.Tracepoint) > 0 { | ||||
| 		tracepointCollector, err := newPerfTracepointCollector(logger, *config.Tracepoint, cpus) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|  | @ -339,27 +341,27 @@ func NewPerfCollector(config NodeCollectorConfig, logger log.Logger) (Collector, | |||
| 
 | ||||
| 	// Configure perf profilers
 | ||||
| 	hardwareProfilers := perf.AllHardwareProfilers | ||||
| 	if *perfHwProfilerFlag != nil && len(*perfHwProfilerFlag) > 0 { | ||||
| 	if *config.HwProfiler != nil && len(*config.HwProfiler) > 0 { | ||||
| 		// hardwareProfilers = 0
 | ||||
| 		for _, hf := range *perfHwProfilerFlag { | ||||
| 		for _, hf := range *config.HwProfiler { | ||||
| 			if v, ok := perfHardwareProfilerMap[hf]; ok { | ||||
| 				hardwareProfilers |= v | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	softwareProfilers := perf.AllSoftwareProfilers | ||||
| 	if *perfSwProfilerFlag != nil && len(*perfSwProfilerFlag) > 0 { | ||||
| 	if *config.SwProfiler != nil && len(*config.SwProfiler) > 0 { | ||||
| 		// softwareProfilers = 0
 | ||||
| 		for _, sf := range *perfSwProfilerFlag { | ||||
| 		for _, sf := range *config.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 *perfCaProfilerFlag != nil && len(*perfCaProfilerFlag) > 0 { | ||||
| 	if *config.CaProfilerFlag != nil && len(*config.CaProfilerFlag) > 0 { | ||||
| 		cacheProfilers = 0 | ||||
| 		for _, cf := range *perfCaProfilerFlag { | ||||
| 		for _, cf := range *config.CaProfilerFlag { | ||||
| 			if v, ok := perfCacheProfilerMap[cf]; ok { | ||||
| 				cacheProfilers |= v | ||||
| 			} | ||||
|  | @ -370,7 +372,7 @@ func NewPerfCollector(config NodeCollectorConfig, logger log.Logger) (Collector, | |||
| 	for _, cpu := range cpus { | ||||
| 		// Use -1 to profile all processes on the CPU, see:
 | ||||
| 		// man perf_event_open
 | ||||
| 		if !*perfNoHwProfiler { | ||||
| 		if !*config.NoHwProfiler { | ||||
| 			hwProf, err := perf.NewHardwareProfiler( | ||||
| 				-1, | ||||
| 				cpu, | ||||
|  | @ -386,7 +388,7 @@ func NewPerfCollector(config NodeCollectorConfig, logger log.Logger) (Collector, | |||
| 			collector.hwProfilerCPUMap[&hwProf] = cpu | ||||
| 		} | ||||
| 
 | ||||
| 		if !*perfNoSwProfiler { | ||||
| 		if !*config.NoSwProfiler { | ||||
| 			swProf, err := perf.NewSoftwareProfiler(-1, cpu, softwareProfilers) | ||||
| 			if err != nil && !swProf.HasProfilers() { | ||||
| 				return nil, err | ||||
|  | @ -398,7 +400,7 @@ func NewPerfCollector(config NodeCollectorConfig, logger log.Logger) (Collector, | |||
| 			collector.swProfilerCPUMap[&swProf] = cpu | ||||
| 		} | ||||
| 
 | ||||
| 		if !*perfNoCaProfiler { | ||||
| 		if !*config.NoCaProfiler { | ||||
| 			cacheProf, err := perf.NewCacheProfiler( | ||||
| 				-1, | ||||
| 				cpu, | ||||
|  |  | |||
|  | @ -20,15 +20,10 @@ package collector | |||
| import ( | ||||
| 	"regexp" | ||||
| 
 | ||||
| 	"github.com/alecthomas/kingpin/v2" | ||||
| 	"github.com/go-kit/log" | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	powerSupplyClassIgnoredPowerSupplies = kingpin.Flag("collector.powersupply.ignored-supplies", "Regexp of power supplies to ignore for powersupplyclass collector.").Default("^$").String() | ||||
| ) | ||||
| 
 | ||||
| type powerSupplyClassCollector struct { | ||||
| 	subsystem      string | ||||
| 	ignoredPattern *regexp.Regexp | ||||
|  | @ -37,11 +32,18 @@ type powerSupplyClassCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("powersupplyclass", defaultEnabled, NewPowerSupplyClassCollector) | ||||
| 	registerCollector("powersupplyclass", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		cfg := config.(PowerSupplyClassConfig) | ||||
| 		return NewPowerSupplyClassCollector(cfg, logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func NewPowerSupplyClassCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| 	pattern := regexp.MustCompile(*powerSupplyClassIgnoredPowerSupplies) | ||||
| type PowerSupplyClassConfig struct { | ||||
| 	IgnoredPowerSupplies *string | ||||
| } | ||||
| 
 | ||||
| func NewPowerSupplyClassCollector(config PowerSupplyClassConfig, logger log.Logger) (Collector, error) { | ||||
| 	pattern := regexp.MustCompile(*config.IgnoredPowerSupplies) | ||||
| 	return &powerSupplyClassCollector{ | ||||
| 		subsystem:      "power_supply", | ||||
| 		ignoredPattern: pattern, | ||||
|  |  | |||
|  | @ -45,11 +45,13 @@ type pressureStatsCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("pressure", defaultEnabled, NewPressureStatsCollector) | ||||
| 	registerCollector("pressure", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewPressureStatsCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewPressureStatsCollector returns a Collector exposing pressure stall information
 | ||||
| func NewPressureStatsCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewPressureStatsCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
|  |  | |||
|  | @ -43,11 +43,13 @@ type processCollector struct { | |||
| } | ||||
| 
 | ||||
| func init() { | ||||
| 	registerCollector("processes", defaultDisabled, NewProcessStatCollector) | ||||
| 	registerCollector("processes", defaultEnabled, func(config any, logger log.Logger) (Collector, error) { | ||||
| 		return NewProcessStatCollector(logger) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| // NewProcessStatCollector returns a new Collector exposing process data read from the proc filesystem.
 | ||||
| func NewProcessStatCollector(config NodeCollectorConfig, logger log.Logger) (Collector, error) { | ||||
| func NewProcessStatCollector(logger log.Logger) (Collector, error) { | ||||
| 	fs, err := procfs.NewFS(*procPath) | ||||
| 	if err != nil { | ||||
| 		return nil, fmt.Errorf("failed to open procfs: %w", err) | ||||
|  |  | |||
|  | @ -24,5 +24,99 @@ func AddFlags(a *kingpin.Application) collector.NodeCollectorConfig { | |||
| 	config.Arp.DeviceInclude = a.Flag("collector.arp.device-include", "Regexp of arp devices to include (mutually exclusive to device-exclude).").String() | ||||
| 	config.Arp.DeviceExclude = a.Flag("collector.arp.device-exclude", "Regexp of arp devices to exclude (mutually exclusive to device-include).").String() | ||||
| 
 | ||||
| 	config.Bcache.PriorityStats = a.Flag("collector.bcache.priorityStats", "Expose expensive priority stats.").Bool() | ||||
| 
 | ||||
| 	config.CPU.EnableCPUGuest = a.Flag("collector.cpu.guest", "Enables metric node_cpu_guest_seconds_total").Default("true").Bool() | ||||
| 	config.CPU.EnableCPUInfo = a.Flag("collector.cpu.info", "Enables metric cpu_info").Bool() | ||||
| 	config.CPU.FlagsInclude = a.Flag("collector.cpu.info.flags-include", "Filter the `flags` field in cpuInfo with a value that must be a regular expression").String() | ||||
| 	config.CPU.BugsInclude = a.Flag("collector.cpu.info.bugs-include", "Filter the `bugs` field in cpuInfo with a value that must be a regular expression").String() | ||||
| 
 | ||||
| 	config.DiskstatsDeviceFilter.DiskstatsDeviceExclude = a.Flag( | ||||
| 		"collector.diskstats.device-exclude", | ||||
| 		"Regexp of diskstats devices to exclude (mutually exclusive to device-include).", | ||||
| 	).PreAction(func(c *kingpin.ParseContext) error { | ||||
| 		diskstatsDeviceExcludeSet = true | ||||
| 		return nil | ||||
| 	}).String() | ||||
| 	config.DiskstatsDeviceFilter.OldDiskstatsDeviceExclude = a.Flag( | ||||
| 		"collector.diskstats.ignored-devices", | ||||
| 		"DEPRECATED: Use collector.diskstats.device-exclude", | ||||
| 	).Hidden().String() | ||||
| 	config.DiskstatsDeviceFilter.DiskstatsDeviceInclude = a.Flag("collector.diskstats.device-include", "Regexp of diskstats devices to include (mutually exclusive to device-exclude).").String() | ||||
| 
 | ||||
| 	config.Ethtool.DeviceInclude = a.Flag("collector.ethtool.device-include", "Regexp of ethtool devices to include (mutually exclusive to device-exclude).").String() | ||||
| 	config.Ethtool.DeviceExclude = a.Flag("collector.ethtool.device-exclude", "Regexp of ethtool devices to exclude (mutually exclusive to device-include).").String() | ||||
| 	config.Ethtool.IncludedMetrics = a.Flag("collector.ethtool.metrics-include", "Regexp of ethtool stats to include.").Default(".*").String() | ||||
| 
 | ||||
| 	config.Filesystem.MountPointsExclude = a.Flag( | ||||
| 		"collector.filesystem.mount-points-exclude", | ||||
| 		"Regexp of mount points to exclude for filesystem collector.", | ||||
| 	).PreAction(func(c *kingpin.ParseContext) error { | ||||
| 		mountPointsExcludeSet = true | ||||
| 		return nil | ||||
| 	}).String() | ||||
| 	config.Filesystem.OldMountPointsExcluded = a.Flag( | ||||
| 		"collector.filesystem.ignored-mount-points", | ||||
| 		"Regexp of mount points to ignore for filesystem collector.", | ||||
| 	).Hidden().String() | ||||
| 
 | ||||
| 	config.Filesystem.FSTypesExclude = a.Flag( | ||||
| 		"collector.filesystem.fs-types-exclude", | ||||
| 		"Regexp of filesystem types to exclude for filesystem collector.", | ||||
| 	).PreAction(func(c *kingpin.ParseContext) error { | ||||
| 		fsTypesExcludeSet = true | ||||
| 		return nil | ||||
| 	}).String() | ||||
| 	config.Filesystem.OldFSTypesExcluded = a.Flag( | ||||
| 		"collector.filesystem.ignored-fs-types", | ||||
| 		"Regexp of filesystem types to ignore for filesystem collector.", | ||||
| 	).Hidden().String() | ||||
| 	config.Filesystem.MountTimeout = a.Flag("collector.filesystem.mount-timeout", | ||||
| 		"how long to wait for a mount to respond before marking it as stale"). | ||||
| 		Hidden().Default("5s").Duration() | ||||
| 	config.Filesystem.StatWorkerCount = a.Flag("collector.filesystem.stat-workers", | ||||
| 		"how many stat calls to process simultaneously"). | ||||
| 		Hidden().Default("4").Int() | ||||
| 
 | ||||
| 	config.HwMon.ChipInclude = a.Flag("collector.hwmon.chip-include", "Regexp of hwmon chip to include (mutually exclusive to device-exclude).").String() | ||||
| 	config.HwMon.ChipExclude = a.Flag("collector.hwmon.chip-exclude", "Regexp of hwmon chip to exclude (mutually exclusive to device-include).").String() | ||||
| 
 | ||||
| 	config.IPVS.Labels = a.Flag("collector.ipvs.backend-labels", "Comma separated list for IPVS backend stats labels.").String() | ||||
| 
 | ||||
| 	config.NetClass.IgnoredDevices = a.Flag("collector.netclass.ignored-devices", "Regexp of net devices to ignore for netclass collector.").Default("^$").String() | ||||
| 	config.NetClass.InvalidSpeed = a.Flag("collector.netclass.ignore-invalid-speed", "Ignore devices where the speed is invalid. This will be the default behavior in 2.x.").Bool() | ||||
| 	config.NetClass.Netlink = a.Flag("collector.netclass.netlink", "Use netlink to gather stats instead of /proc/net/dev.").Default("false").Bool() | ||||
| 	config.NetClass.RTNLWithStats = a.Flag("collector.netclass_rtnl.with-stats", "Expose the statistics for each network device, replacing netdev collector.").Bool() | ||||
| 
 | ||||
| 	config.NetDev.DeviceInclude = a.Flag("collector.netdev.device-include", "Regexp of net devices to include (mutually exclusive to device-exclude).").String() | ||||
| 	config.NetDev.OldDeviceInclude = a.Flag("collector.netdev.device-whitelist", "DEPRECATED: Use collector.netdev.device-include").Hidden().String() | ||||
| 	config.NetDev.DeviceExclude = a.Flag("collector.netdev.device-exclude", "Regexp of net devices to exclude (mutually exclusive to device-include).").String() | ||||
| 	config.NetDev.OldDeviceExclude = a.Flag("collector.netdev.device-blacklist", "DEPRECATED: Use collector.netdev.device-exclude").Hidden().String() | ||||
| 	config.NetDev.AddressInfo = a.Flag("collector.netdev.address-info", "Collect address-info for every device").Bool() | ||||
| 	config.NetDev.DetailedMetrics = a.Flag("collector.netdev.enable-detailed-metrics", "Use (incompatible) metric names that provide more detailed stats on Linux").Bool() | ||||
| 	config.NetDev.Netlink = a.Flag("collector.netdev.netlink", "Use netlink to gather stats instead of /proc/net/dev.").Default("true").Bool() | ||||
| 
 | ||||
| 	config.NetStat.Fields = a.Flag("collector.netstat.fields", "Regexp of fields to return for netstat collector.").Default("^(.*_(InErrors|InErrs)|Ip_Forwarding|Ip(6|Ext)_(InOctets|OutOctets)|Icmp6?_(InMsgs|OutMsgs)|TcpExt_(Listen.*|Syncookies.*|TCPSynRetrans|TCPTimeouts)|Tcp_(ActiveOpens|InSegs|OutSegs|OutRsts|PassiveOpens|RetransSegs|CurrEstab)|Udp6?_(InDatagrams|OutDatagrams|NoPorts|RcvbufErrors|SndbufErrors))$").String() | ||||
| 
 | ||||
| 	config.NTP.Server = a.Flag("collector.ntp.server", "NTP server to use for ntp collector").Default("127.0.0.1").String() | ||||
| 	config.NTP.ServerPort = a.Flag("collector.ntp.server-port", "UDP port number to connect to on NTP server").Default("123").Int() | ||||
| 	config.NTP.ProtocolVersion = a.Flag("collector.ntp.protocol-version", "NTP protocol version").Default("4").Int() | ||||
| 	config.NTP.ServerIsLocal = a.Flag("collector.ntp.server-is-local", "Certify that collector.ntp.server address is not a public ntp server").Default("false").Bool() | ||||
| 	config.NTP.IPTTL = a.Flag("collector.ntp.ip-ttl", "IP TTL to use while sending NTP query").Default("1").Int() | ||||
| 	// 3.46608s ~ 1.5s + PHI * (1 << maxPoll), where 1.5s is MAXDIST from ntp.org, it is 1.0 in RFC5905
 | ||||
| 	// max-distance option is used as-is without phi*(1<<poll)
 | ||||
| 	config.NTP.MaxDistance = a.Flag("collector.ntp.max-distance", "Max accumulated distance to the root").Default("3.46608s").Duration() | ||||
| 	config.NTP.OffsetTolerance = a.Flag("collector.ntp.local-offset-tolerance", "Offset between local clock and local ntpd time to tolerate").Default("1ms").Duration() | ||||
| 
 | ||||
| 	config.Perf.CPUs = a.Flag("collector.perf.cpus", "List of CPUs from which perf metrics should be collected").Default("").String() | ||||
| 	config.Perf.Tracepoint = a.Flag("collector.perf.tracepoint", "perf tracepoint that should be collected").Strings() | ||||
| 	config.Perf.NoHwProfiler = a.Flag("collector.perf.disable-hardware-profilers", "disable perf hardware profilers").Default("false").Bool() | ||||
| 	config.Perf.HwProfiler = a.Flag("collector.perf.hardware-profilers", "perf hardware profilers that should be collected").Strings() | ||||
| 	config.Perf.NoSwProfiler = a.Flag("collector.perf.disable-software-profilers", "disable perf software profilers").Default("false").Bool() | ||||
| 	config.Perf.SwProfiler = a.Flag("collector.perf.software-profilers", "perf software profilers that should be collected").Strings() | ||||
| 	config.Perf.NoCaProfiler = a.Flag("collector.perf.disable-cache-profilers", "disable perf cache profilers").Default("false").Bool() | ||||
| 	config.Perf.CaProfilerFlag = a.Flag("collector.perf.cache-profilers", "perf cache profilers that should be collected").Strings() | ||||
| 
 | ||||
| 	config.PowerSupplyClass.IgnoredPowerSupplies = a.Flag("collector.powersupply.ignored-supplies", "Regexp of power supplies to ignore for powersupplyclass collector.").Default("^$").String() | ||||
| 	return config | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue