Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add configuration structs to all usage as a library. #2850

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 6 additions & 11 deletions collector/arp_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,47 +21,42 @@ import (
"fmt"
"net"

"github.com/alecthomas/kingpin/v2"
"github.com/go-kit/log"
"github.com/jsimonetti/rtnetlink"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/procfs"
"golang.org/x/sys/unix"
)

var (
arpDeviceInclude = kingpin.Flag("collector.arp.device-include", "Regexp of arp devices to include (mutually exclusive to device-exclude).").String()
arpDeviceExclude = kingpin.Flag("collector.arp.device-exclude", "Regexp of arp devices to exclude (mutually exclusive to device-include).").String()
arpNetlink = kingpin.Flag("collector.arp.netlink", "Use netlink to gather stats instead of /proc/net/arp.").Default("true").Bool()
)

type arpCollector struct {
fs procfs.FS
deviceFilter deviceFilter
entries *prometheus.Desc
logger log.Logger
config *NodeCollectorConfig
}

func init() {
registerCollector("arp", defaultEnabled, NewARPCollector)
}

// NewARPCollector returns a new Collector exposing ARP stats.
func NewARPCollector(logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath)
func NewARPCollector(config *NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err)
}

return &arpCollector{
fs: fs,
deviceFilter: newDeviceFilter(*arpDeviceExclude, *arpDeviceInclude),
deviceFilter: newDeviceFilter(*config.Arp.DeviceExclude, *config.Arp.DeviceInclude),
entries: prometheus.NewDesc(
prometheus.BuildFQName(namespace, "arp", "entries"),
"ARP entries by device",
[]string{"device"}, nil,
),
logger: logger,
config: config,
}, nil
}

Expand Down Expand Up @@ -119,7 +114,7 @@ func getTotalArpEntriesRTNL() (map[string]uint32, error) {
func (c *arpCollector) Update(ch chan<- prometheus.Metric) error {
var enumeratedEntry map[string]uint32

if *arpNetlink {
if *c.config.Arp.Netlink {
var err error

enumeratedEntry, err = getTotalArpEntriesRTNL()
Expand Down
16 changes: 7 additions & 9 deletions collector/bcache_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,35 @@ 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)

}

// A bcacheCollector is a Collector which gathers metrics from Linux bcache.
type bcacheCollector struct {
fs bcache.FS
logger log.Logger
config *NodeCollectorConfig
}

// NewBcacheCollector returns a newly allocated bcacheCollector.
// It exposes a number of Linux bcache statistics.
func NewBcacheCollector(logger log.Logger) (Collector, error) {
fs, err := bcache.NewFS(*sysPath)
func NewBcacheCollector(config *NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := bcache.NewFS(*config.Path.SysPath)
if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err)
}

return &bcacheCollector{
fs: fs,
logger: logger,
config: config,
}, nil
}

Expand All @@ -58,7 +56,7 @@ func NewBcacheCollector(logger log.Logger) (Collector, error) {
func (c *bcacheCollector) Update(ch chan<- prometheus.Metric) error {
var stats []*bcache.Stats
var err error
if *priorityStats {
if *c.config.Bcache.PriorityStats {
stats, err = c.fs.Stats()
} else {
stats, err = c.fs.StatsWithoutPriority()
Expand Down Expand Up @@ -317,7 +315,7 @@ func (c *bcacheCollector) updateBcacheStats(ch chan<- prometheus.Metric, s *bcac
extraLabelValue: cache.Name,
},
}
if *priorityStats {
if *c.config.Bcache.PriorityStats {
// metrics in /sys/fs/bcache/<uuid>/<cache>/priority_stats
priorityStatsMetrics := []bcacheMetric{
{
Expand Down
6 changes: 4 additions & 2 deletions collector/bonding_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
type bondingCollector struct {
slaves, active typedDesc
logger log.Logger
config *NodeCollectorConfig
}

func init() {
Expand All @@ -39,7 +40,7 @@ func init() {

// NewBondingCollector returns a newly allocated bondingCollector.
// It exposes the number of configured and active slave of linux bonding interfaces.
func NewBondingCollector(logger log.Logger) (Collector, error) {
func NewBondingCollector(config *NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &bondingCollector{
slaves: typedDesc{prometheus.NewDesc(
prometheus.BuildFQName(namespace, "bonding", "slaves"),
Expand All @@ -52,12 +53,13 @@ func NewBondingCollector(logger log.Logger) (Collector, error) {
[]string{"master"}, nil,
), prometheus.GaugeValue},
logger: logger,
config: config,
}, nil
}

// Update reads and exposes bonding states, implements Collector interface. Caution: This works only on linux.
func (c *bondingCollector) Update(ch chan<- prometheus.Metric) error {
statusfile := sysFilePath("class/net")
statusfile := c.config.Path.sysFilePath("class/net")
bondingStats, err := readBondingStats(statusfile)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
Expand Down
2 changes: 1 addition & 1 deletion collector/boot_time_bsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func init() {
}

// newBootTimeCollector returns a new Collector exposing system boot time on BSD systems.
func newBootTimeCollector(logger log.Logger) (Collector, error) {
func newBootTimeCollector(config *NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &bootTimeCollector{
logger: logger,
}, nil
Expand Down
2 changes: 1 addition & 1 deletion collector/boot_time_solaris.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func init() {
registerCollector("boottime", defaultEnabled, newBootTimeCollector)
}

func newBootTimeCollector(logger log.Logger) (Collector, error) {
func newBootTimeCollector(config *NodeCollectorConfig, logger log.Logger) (Collector, error) {
return &bootTimeCollector{
boottime: typedDesc{
prometheus.NewDesc(
Expand Down
10 changes: 6 additions & 4 deletions collector/btrfs_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,24 @@ import (
type btrfsCollector struct {
fs btrfs.FS
logger log.Logger
config *NodeCollectorConfig
}

func init() {
registerCollector("btrfs", defaultEnabled, NewBtrfsCollector)
}

// NewBtrfsCollector returns a new Collector exposing Btrfs statistics.
func NewBtrfsCollector(logger log.Logger) (Collector, error) {
fs, err := btrfs.NewFS(*sysPath)
func NewBtrfsCollector(config *NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := btrfs.NewFS(*config.Path.SysPath)
if err != nil {
return nil, fmt.Errorf("failed to open sysfs: %w", err)
}

return &btrfsCollector{
fs: fs,
logger: logger,
config: config,
}, nil
}

Expand Down Expand Up @@ -103,7 +105,7 @@ type btrfsIoctlFsStats struct {
func (c *btrfsCollector) getIoctlStats() (map[string]*btrfsIoctlFsStats, error) {
// Instead of introducing more ioctl calls to scan for all btrfs
// filesystems re-use our mount point utils to find known mounts
mountsList, err := mountPointDetails(c.logger)
mountsList, err := mountPointDetails(c.config, c.logger)
if err != nil {
return nil, err
}
Expand All @@ -123,7 +125,7 @@ func (c *btrfsCollector) getIoctlStats() (map[string]*btrfsIoctlFsStats, error)
continue
}

mountPath := rootfsFilePath(mount.mountPoint)
mountPath := c.config.Path.rootfsFilePath(mount.mountPoint)

fs, err := dennwc.Open(mountPath, true)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions collector/buddyinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ func init() {
}

// NewBuddyinfoCollector returns a new Collector exposing buddyinfo stats.
func NewBuddyinfoCollector(logger log.Logger) (Collector, error) {
func NewBuddyinfoCollector(config *NodeCollectorConfig, logger log.Logger) (Collector, error) {
desc := prometheus.NewDesc(
prometheus.BuildFQName(namespace, buddyInfoSubsystem, "blocks"),
"Count of free blocks according to size.",
[]string{"node", "zone", "size"}, nil,
)
fs, err := procfs.NewFS(*procPath)
fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err)
}
Expand Down
4 changes: 2 additions & 2 deletions collector/cgroups_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ func init() {
}

// NewCgroupSummaryCollector returns a new Collector exposing a summary of cgroups.
func NewCgroupSummaryCollector(logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*procPath)
func NewCgroupSummaryCollector(config *NodeCollectorConfig, logger log.Logger) (Collector, error) {
fs, err := procfs.NewFS(*config.Path.ProcPath)
if err != nil {
return nil, fmt.Errorf("failed to open procfs: %w", err)
}
Expand Down
39 changes: 26 additions & 13 deletions collector/collector.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,27 +50,39 @@ const (
)

var (
factories = make(map[string]func(logger log.Logger) (Collector, error))
factories = make(map[string]func(config *NodeCollectorConfig, logger log.Logger) (Collector, error))
initiatedCollectorsMtx = sync.Mutex{}
initiatedCollectors = make(map[string]Collector)
collectorState = make(map[string]*bool)
collectorStateGlobal = make(map[string]bool)
collectorFlagState = make(map[string]*bool)
availableCollectors = make([]string, 0)
forcedCollectors = map[string]bool{} // collectors which have been explicitly enabled or disabled
)

func registerCollector(collector string, isDefaultEnabled bool, factory func(logger log.Logger) (Collector, error)) {
func GetFlagDefaults() map[string]bool {
defaults := make(map[string]bool)
for k, v := range collectorFlagState {
defaults[k] = *v
}
return defaults
}

func registerCollector(collector string, isDefaultEnabled bool, factory func(config *NodeCollectorConfig, logger log.Logger) (Collector, error)) {
var helpDefaultState string
if isDefaultEnabled {
helpDefaultState = "enabled"
} else {
helpDefaultState = "disabled"
}
availableCollectors = append(availableCollectors, collector)

flagName := fmt.Sprintf("collector.%s", collector)
flagHelp := fmt.Sprintf("Enable the %s collector (default: %s).", collector, helpDefaultState)
defaultValue := fmt.Sprintf("%v", isDefaultEnabled)

flag := kingpin.Flag(flagName, flagHelp).Default(defaultValue).Action(collectorFlagAction(collector)).Bool()
collectorState[collector] = flag
collectorStateGlobal[collector] = isDefaultEnabled
collectorFlagState[collector] = flag

factories[collector] = factory
}
Expand All @@ -84,9 +96,9 @@ type NodeCollector struct {
// DisableDefaultCollectors sets the collector state to false for all collectors which
// have not been explicitly enabled on the command line.
func DisableDefaultCollectors() {
for c := range collectorState {
for c := range collectorFlagState {
if _, ok := forcedCollectors[c]; !ok {
*collectorState[c] = false
*collectorFlagState[c] = false
}
}
}
Expand All @@ -104,29 +116,30 @@ func collectorFlagAction(collector string) func(ctx *kingpin.ParseContext) error
}

// NewNodeCollector creates a new NodeCollector.
func NewNodeCollector(logger log.Logger, filters ...string) (*NodeCollector, error) {
func NewNodeCollector(config *NodeCollectorConfig, logger log.Logger, filters ...string) (*NodeCollector, error) {
f := make(map[string]bool)
for _, filter := range filters {
enabled, exist := collectorState[filter]
enabled, exist := config.Collectors[filter]
if !exist {
return nil, fmt.Errorf("missing collector: %s", filter)
}
if !*enabled {
if !enabled {
return nil, fmt.Errorf("disabled collector: %s", filter)
}
f[filter] = true
}
collectors := make(map[string]Collector)

initiatedCollectorsMtx.Lock()
defer initiatedCollectorsMtx.Unlock()
for key, enabled := range collectorState {
if !*enabled || (len(f) > 0 && !f[key]) {
for key, enabled := range config.Collectors {
if !enabled || (len(f) > 0 && !f[key]) {
continue
}
if collector, ok := initiatedCollectors[key]; ok {
if collector, ok := initiatedCollectors[key]; ok && config.AllowCachingOfCollectors {
collectors[key] = collector
} else {
collector, err := factories[key](log.With(logger, "collector", key))
collector, err := factories[key](config, log.With(logger, "collector", key))
if err != nil {
return nil, err
}
Expand Down