Replace --collectors.enabled with per-collector flags (#640)
* Move NodeCollector into package collector * Refactor collector enabling * Update README with new collector enabled flags * Fix out-of-date inline flag reference syntax * Use new flags in end-to-end tests * Add flag to disable all default collectors * Track if a flag has been set explicitly * Add --collectors.disable-defaults to README * Revert disable-defaults flag * Shorten flags * Fixup timex collector registration * Fix end-to-end tests * Change procfs and sysfs path flags * Fix review comments
This commit is contained in:
parent
3762191e66
commit
859a825bb8
58 changed files with 410 additions and 406 deletions
|
|
@ -15,20 +15,121 @@
|
|||
package collector
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/common/log"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
// Namespace defines the common namespace to be used by all metrics.
|
||||
const Namespace = "node"
|
||||
const namespace = "node"
|
||||
|
||||
// Factories contains the list of all available collectors.
|
||||
var Factories = make(map[string]func() (Collector, error))
|
||||
var (
|
||||
scrapeDurationDesc = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, "scrape", "collector_duration_seconds"),
|
||||
"node_exporter: Duration of a collector scrape.",
|
||||
[]string{"collector"},
|
||||
nil,
|
||||
)
|
||||
scrapeSuccessDesc = prometheus.NewDesc(
|
||||
prometheus.BuildFQName(namespace, "scrape", "collector_success"),
|
||||
"node_exporter: Whether a collector succeeded.",
|
||||
[]string{"collector"},
|
||||
nil,
|
||||
)
|
||||
)
|
||||
|
||||
func warnDeprecated(collector string) {
|
||||
log.Warnf("The %s collector is deprecated and will be removed in the future!", collector)
|
||||
}
|
||||
|
||||
const (
|
||||
defaultEnabled = true
|
||||
defaultDisabled = false
|
||||
)
|
||||
|
||||
var (
|
||||
factories = make(map[string]func() (Collector, error))
|
||||
collectorState = make(map[string]*bool)
|
||||
)
|
||||
|
||||
func registerCollector(collector string, isDefaultEnabled bool, factory func() (Collector, error)) {
|
||||
var helpDefaultState string
|
||||
if isDefaultEnabled {
|
||||
helpDefaultState = "enabled"
|
||||
} else {
|
||||
helpDefaultState = "disabled"
|
||||
}
|
||||
|
||||
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).Bool()
|
||||
collectorState[collector] = flag
|
||||
|
||||
factories[collector] = factory
|
||||
}
|
||||
|
||||
// NodeCollector implements the prometheus.Collector interface.
|
||||
type nodeCollector struct {
|
||||
Collectors map[string]Collector
|
||||
}
|
||||
|
||||
// NewNodeCollector creates a new NodeCollector
|
||||
func NewNodeCollector() (*nodeCollector, error) {
|
||||
collectors := make(map[string]Collector)
|
||||
for key, enabled := range collectorState {
|
||||
if *enabled {
|
||||
collector, err := factories[key]()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
collectors[key] = collector
|
||||
}
|
||||
}
|
||||
return &nodeCollector{Collectors: collectors}, nil
|
||||
}
|
||||
|
||||
// Describe implements the prometheus.Collector interface.
|
||||
func (n nodeCollector) Describe(ch chan<- *prometheus.Desc) {
|
||||
ch <- scrapeDurationDesc
|
||||
ch <- scrapeSuccessDesc
|
||||
}
|
||||
|
||||
// Collect implements the prometheus.Collector interface.
|
||||
func (n nodeCollector) Collect(ch chan<- prometheus.Metric) {
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(len(n.Collectors))
|
||||
for name, c := range n.Collectors {
|
||||
go func(name string, c Collector) {
|
||||
execute(name, c, ch)
|
||||
wg.Done()
|
||||
}(name, c)
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func execute(name string, c Collector, ch chan<- prometheus.Metric) {
|
||||
begin := time.Now()
|
||||
err := c.Update(ch)
|
||||
duration := time.Since(begin)
|
||||
var success float64
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("ERROR: %s collector failed after %fs: %s", name, duration.Seconds(), err)
|
||||
success = 0
|
||||
} else {
|
||||
log.Debugf("OK: %s collector succeeded after %fs.", name, duration.Seconds())
|
||||
success = 1
|
||||
}
|
||||
ch <- prometheus.MustNewConstMetric(scrapeDurationDesc, prometheus.GaugeValue, duration.Seconds(), name)
|
||||
ch <- prometheus.MustNewConstMetric(scrapeSuccessDesc, prometheus.GaugeValue, success, name)
|
||||
}
|
||||
|
||||
// Collector is the interface a collector has to implement.
|
||||
type Collector interface {
|
||||
// Get new metrics and expose them via prometheus registry.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue