diff --git a/collector/bcache_linux.go b/collector/bcache_linux.go index c61ac274..0102a15f 100644 --- a/collector/bcache_linux.go +++ b/collector/bcache_linux.go @@ -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///priority_stats priorityStatsMetrics := []bcacheMetric{ { diff --git a/collector/bonding_linux.go b/collector/bonding_linux.go index c69fc312..36752266 100644 --- a/collector/bonding_linux.go +++ b/collector/bonding_linux.go @@ -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"), diff --git a/collector/boot_time_bsd.go b/collector/boot_time_bsd.go index f8831854..06b8807a 100644 --- a/collector/boot_time_bsd.go +++ b/collector/boot_time_bsd.go @@ -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 diff --git a/collector/boot_time_solaris.go b/collector/boot_time_solaris.go index 6782cd72..0271571a 100644 --- a/collector/boot_time_solaris.go +++ b/collector/boot_time_solaris.go @@ -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( diff --git a/collector/btrfs_linux.go b/collector/btrfs_linux.go index f551f169..d9279c53 100644 --- a/collector/btrfs_linux.go +++ b/collector/btrfs_linux.go @@ -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) diff --git a/collector/buddyinfo.go b/collector/buddyinfo.go index d0ad8cae..af442b5e 100644 --- a/collector/buddyinfo.go +++ b/collector/buddyinfo.go @@ -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.", diff --git a/collector/cgroups_linux.go b/collector/cgroups_linux.go index 47f0c117..87501368 100644 --- a/collector/cgroups_linux.go +++ b/collector/cgroups_linux.go @@ -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) diff --git a/collector/config.go b/collector/config.go index 416d3c05..a2247a71 100644 --- a/collector/config.go +++ b/collector/config.go @@ -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 } diff --git a/collector/conntrack_linux.go b/collector/conntrack_linux.go index 989f74f2..7a221216 100644 --- a/collector/conntrack_linux.go +++ b/collector/conntrack_linux.go @@ -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"), diff --git a/collector/cpu_darwin.go b/collector/cpu_darwin.go index bacde20a..df21148b 100644 --- a/collector/cpu_darwin.go +++ b/collector/cpu_darwin.go @@ -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, diff --git a/collector/cpu_dragonfly.go b/collector/cpu_dragonfly.go index 1420c436..5d74e7db 100644 --- a/collector/cpu_dragonfly.go +++ b/collector/cpu_dragonfly.go @@ -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, diff --git a/collector/cpu_freebsd.go b/collector/cpu_freebsd.go index d75b8adc..6a44e036 100644 --- a/collector/cpu_freebsd.go +++ b/collector/cpu_freebsd.go @@ -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( diff --git a/collector/cpu_linux.go b/collector/cpu_linux.go index ce6608ce..ebd676fb 100644 --- a/collector/cpu_linux.go +++ b/collector/cpu_linux.go @@ -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") diff --git a/collector/cpu_netbsd.go b/collector/cpu_netbsd.go index 4f1e63fb..5b312ab7 100644 --- a/collector/cpu_netbsd.go +++ b/collector/cpu_netbsd.go @@ -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( diff --git a/collector/cpu_openbsd.go b/collector/cpu_openbsd.go index 31c3d49e..088f1d57 100644 --- a/collector/cpu_openbsd.go +++ b/collector/cpu_openbsd.go @@ -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) { diff --git a/collector/cpu_solaris.go b/collector/cpu_solaris.go index 702ba3f8..ed39d5bb 100644 --- a/collector/cpu_solaris.go +++ b/collector/cpu_solaris.go @@ -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, diff --git a/collector/cpu_vulnerabilities_linux.go b/collector/cpu_vulnerabilities_linux.go index ccbda762..1f75d43e 100644 --- a/collector/cpu_vulnerabilities_linux.go +++ b/collector/cpu_vulnerabilities_linux.go @@ -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 } diff --git a/collector/cpufreq_linux.go b/collector/cpufreq_linux.go index b926218f..03ed1b5d 100644 --- a/collector/cpufreq_linux.go +++ b/collector/cpufreq_linux.go @@ -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) diff --git a/collector/cpufreq_solaris.go b/collector/cpufreq_solaris.go index 00046e48..37ecdf31 100644 --- a/collector/cpufreq_solaris.go +++ b/collector/cpufreq_solaris.go @@ -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 diff --git a/collector/devstat_dragonfly.go b/collector/devstat_dragonfly.go index 746d0ea7..566ffdba 100644 --- a/collector/devstat_dragonfly.go +++ b/collector/devstat_dragonfly.go @@ -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"), diff --git a/collector/devstat_freebsd.go b/collector/devstat_freebsd.go index a8c96a1a..01965004 100644 --- a/collector/devstat_freebsd.go +++ b/collector/devstat_freebsd.go @@ -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. diff --git a/collector/diskstats_common.go b/collector/diskstats_common.go index 2ab84438..46d2da54 100644 --- a/collector/diskstats_common.go +++ b/collector/diskstats_common.go @@ -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 } diff --git a/collector/diskstats_darwin.go b/collector/diskstats_darwin.go index 18b92637..01ed064f 100644 --- a/collector/diskstats_darwin.go +++ b/collector/diskstats_darwin.go @@ -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) } diff --git a/collector/diskstats_linux.go b/collector/diskstats_linux.go index f49f67d9..7390b4d8 100644 --- a/collector/diskstats_linux.go +++ b/collector/diskstats_linux.go @@ -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) } diff --git a/collector/diskstats_openbsd.go b/collector/diskstats_openbsd.go index 90b5f219..b5729bdc 100644 --- a/collector/diskstats_openbsd.go +++ b/collector/diskstats_openbsd.go @@ -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) } diff --git a/collector/diskstats_openbsd_amd64.go b/collector/diskstats_openbsd_amd64.go index 5cca7d8f..3d1c72f1 100644 --- a/collector/diskstats_openbsd_amd64.go +++ b/collector/diskstats_openbsd_amd64.go @@ -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) } diff --git a/collector/dmi.go b/collector/dmi.go index 959554aa..30051d7c 100644 --- a/collector/dmi.go +++ b/collector/dmi.go @@ -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) diff --git a/collector/drbd_linux.go b/collector/drbd_linux.go index 43e0785e..9d5befa3 100644 --- a/collector/drbd_linux.go +++ b/collector/drbd_linux.go @@ -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( diff --git a/collector/drm_linux.go b/collector/drm_linux.go index bafe1667..c431afb5 100644 --- a/collector/drm_linux.go +++ b/collector/drm_linux.go @@ -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) diff --git a/collector/edac_linux.go b/collector/edac_linux.go index e6980af9..715f0423 100644 --- a/collector/edac_linux.go +++ b/collector/edac_linux.go @@ -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"), diff --git a/collector/entropy_linux.go b/collector/entropy_linux.go index 06b81289..7416ff9d 100644 --- a/collector/entropy_linux.go +++ b/collector/entropy_linux.go @@ -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) diff --git a/collector/ethtool_linux.go b/collector/ethtool_linux.go index f974c3dd..5243cbfb 100644 --- a/collector/ethtool_linux.go +++ b/collector/ethtool_linux.go @@ -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) } diff --git a/collector/exec_bsd.go b/collector/exec_bsd.go index 06e31865..a659328a 100644 --- a/collector/exec_bsd.go +++ b/collector/exec_bsd.go @@ -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. // diff --git a/collector/fibrechannel_linux.go b/collector/fibrechannel_linux.go index 26f5514d..c43605fd 100644 --- a/collector/fibrechannel_linux.go +++ b/collector/fibrechannel_linux.go @@ -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 diff --git a/collector/filefd_linux.go b/collector/filefd_linux.go index 8ed39770..51984a4a 100644 --- a/collector/filefd_linux.go +++ b/collector/filefd_linux.go @@ -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 } diff --git a/collector/filesystem_common.go b/collector/filesystem_common.go index 80eb94c8..dbf22876 100644 --- a/collector/filesystem_common.go +++ b/collector/filesystem_common.go @@ -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 } diff --git a/collector/filesystem_linux.go b/collector/filesystem_linux.go index a054e213..813532d0 100644 --- a/collector/filesystem_linux.go +++ b/collector/filesystem_linux.go @@ -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 { diff --git a/collector/hwmon_linux.go b/collector/hwmon_linux.go index 88d6b863..e24d77fb 100644 --- a/collector/hwmon_linux.go +++ b/collector/hwmon_linux.go @@ -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[^0-9]+)(?P[0-9]*)?(_(?P.+))?$`) 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 } diff --git a/collector/infiniband_linux.go b/collector/infiniband_linux.go index 485a49d1..e4d7395d 100644 --- a/collector/infiniband_linux.go +++ b/collector/infiniband_linux.go @@ -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 diff --git a/collector/interrupts_common.go b/collector/interrupts_common.go index e54947a6..614f4b61 100644 --- a/collector/interrupts_common.go +++ b/collector/interrupts_common.go @@ -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", diff --git a/collector/ipvs_linux.go b/collector/ipvs_linux.go index 0c74bea5..cf67f676 100644 --- a/collector/ipvs_linux.go +++ b/collector/ipvs_linux.go @@ -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 } diff --git a/collector/ksmd_linux.go b/collector/ksmd_linux.go index d084298c..f642e5d8 100644 --- a/collector/ksmd_linux.go +++ b/collector/ksmd_linux.go @@ -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) diff --git a/collector/lnstat_linux.go b/collector/lnstat_linux.go index d2ac8cd8..a5809d1c 100644 --- a/collector/lnstat_linux.go +++ b/collector/lnstat_linux.go @@ -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 } diff --git a/collector/loadavg.go b/collector/loadavg.go index 15c5a109..259a9f9d 100644 --- a/collector/loadavg.go +++ b/collector/loadavg.go @@ -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}, diff --git a/collector/logind_linux.go b/collector/logind_linux.go index 0a087fbf..9958edbd 100644 --- a/collector/logind_linux.go +++ b/collector/logind_linux.go @@ -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 } diff --git a/collector/mdadm_linux.go b/collector/mdadm_linux.go index 5035276e..7e4eb86f 100644 --- a/collector/mdadm_linux.go +++ b/collector/mdadm_linux.go @@ -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 } diff --git a/collector/meminfo.go b/collector/meminfo.go index 0950a488..72283662 100644 --- a/collector/meminfo.go +++ b/collector/meminfo.go @@ -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 } diff --git a/collector/memory_bsd.go b/collector/memory_bsd.go index 6189a141..56fc85ff 100644 --- a/collector/memory_bsd.go +++ b/collector/memory_bsd.go @@ -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. diff --git a/collector/mountstats_linux.go b/collector/mountstats_linux.go index 7267cccc..c27f86b2 100644 --- a/collector/mountstats_linux.go +++ b/collector/mountstats_linux.go @@ -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) diff --git a/collector/netclass_linux.go b/collector/netclass_linux.go index 3c5bd0cd..860b6e13 100644 --- a/collector/netclass_linux.go +++ b/collector/netclass_linux.go @@ -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) } diff --git a/collector/netclass_rtnl_linux.go b/collector/netclass_rtnl_linux.go index ef963715..5b348474 100644 --- a/collector/netclass_rtnl_linux.go +++ b/collector/netclass_rtnl_linux.go @@ -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 } diff --git a/collector/netdev_common.go b/collector/netdev_common.go index e9a25b07..1e2ca293 100644 --- a/collector/netdev_common.go +++ b/collector/netdev_common.go @@ -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) diff --git a/collector/netdev_linux.go b/collector/netdev_linux.go index 3156d64a..0d3ce780 100644 --- a/collector/netdev_linux.go +++ b/collector/netdev_linux.go @@ -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) } diff --git a/collector/netisr_freebsd.go b/collector/netisr_freebsd.go index d8e5dd35..8977a57e 100644 --- a/collector/netisr_freebsd.go +++ b/collector/netisr_freebsd.go @@ -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{ { diff --git a/collector/netstat_linux.go b/collector/netstat_linux.go index 952aed4c..a05be8af 100644 --- a/collector/netstat_linux.go +++ b/collector/netstat_linux.go @@ -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, diff --git a/collector/network_route_linux.go b/collector/network_route_linux.go index eccb9d7d..5b7f8ae2 100644 --- a/collector/network_route_linux.go +++ b/collector/network_route_linux.go @@ -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( diff --git a/collector/nfs_linux.go b/collector/nfs_linux.go index 6c0893c3..a704d79d 100644 --- a/collector/nfs_linux.go +++ b/collector/nfs_linux.go @@ -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) diff --git a/collector/nfsd_linux.go b/collector/nfsd_linux.go index 551d848d..54cd8ff9 100644 --- a/collector/nfsd_linux.go +++ b/collector/nfsd_linux.go @@ -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) diff --git a/collector/ntp.go b/collector/ntp.go index c4b2d55a..957cb810 100644 --- a/collector/ntp.go +++ b/collector/ntp.go @@ -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< 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) diff --git a/collector/nvme_linux.go b/collector/nvme_linux.go index 218f7422..fbbd3e0e 100644 --- a/collector/nvme_linux.go +++ b/collector/nvme_linux.go @@ -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) diff --git a/collector/os_release.go b/collector/os_release.go index 02bbe64a..569d9b36 100644 --- a/collector/os_release.go +++ b/collector/os_release.go @@ -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( diff --git a/collector/perf_linux.go b/collector/perf_linux.go index c882404f..b8e00b5a 100644 --- a/collector/perf_linux.go +++ b/collector/perf_linux.go @@ -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, diff --git a/collector/powersupplyclass.go b/collector/powersupplyclass.go index 13cb5148..f9172197 100644 --- a/collector/powersupplyclass.go +++ b/collector/powersupplyclass.go @@ -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, diff --git a/collector/pressure_linux.go b/collector/pressure_linux.go index d63bc9d1..6141fcc1 100644 --- a/collector/pressure_linux.go +++ b/collector/pressure_linux.go @@ -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) diff --git a/collector/processes_linux.go b/collector/processes_linux.go index 316ca593..f37235e7 100644 --- a/collector/processes_linux.go +++ b/collector/processes_linux.go @@ -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) diff --git a/kingpinconfig/flags.go b/kingpinconfig/flags.go index 6c6b3e1c..c6302963 100644 --- a/kingpinconfig/flags.go +++ b/kingpinconfig/flags.go @@ -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<