diff --git a/README.md b/README.md index ae2e079c..aabadeb4 100644 --- a/README.md +++ b/README.md @@ -2,33 +2,7 @@ Prometheus exporter with pluggable metric collectors. +## collectors - -## Available collectors - -By default the build will only include the native collectors -that expose information from /proc. - -To include other collectors, specify the build tags lile this: - - go build -tags 'ganglia runit' node_exporter.go - - -Which collectors are used is controlled by the --enabledCollectors flag. - -### NativeCollector - -Provides metrics for load, seconds since last login and a list of tags -read from `node_exporter.conf`. - - -### GmondCollector (tag: ganglia) - -Talks to a local gmond and provide it's metrics. - - -### RunitCollector (tag: runit) - -Provides metrics for each runit services like state and how long it -has been in that state. - +Which collectors are used is controlled by the --enabledCollectors flag. To see +all available collectors, use `--printCollectors`. diff --git a/collector/gmond_collector.go b/collector/gmond.go similarity index 89% rename from collector/gmond_collector.go rename to collector/gmond.go index 90d89d41..2569e66c 100644 --- a/collector/gmond_collector.go +++ b/collector/gmond.go @@ -1,4 +1,4 @@ -// +build ganglia +// +build !nogmond package collector @@ -24,7 +24,7 @@ const ( ) type gmondCollector struct { - Metrics map[string]*prometheus.GaugeVec + metrics map[string]*prometheus.GaugeVec config Config } @@ -38,41 +38,12 @@ var illegalCharsRE = regexp.MustCompile(`[^a-zA-Z0-9_]`) func NewGmondCollector(config Config) (Collector, error) { c := gmondCollector{ config: config, - Metrics: map[string]*prometheus.GaugeVec{}, + metrics: map[string]*prometheus.GaugeVec{}, } return &c, nil } -func (c *gmondCollector) setMetric(name, cluster string, metric ganglia.Metric) { - if _, ok := c.Metrics[name]; !ok { - var desc string - var title string - for _, element := range metric.ExtraData.ExtraElements { - switch element.Name { - case "DESC": - desc = element.Val - case "TITLE": - title = element.Val - } - if title != "" && desc != "" { - break - } - } - glog.V(1).Infof("Register %s: %s", name, desc) - gv := prometheus.NewGaugeVec( - prometheus.GaugeOpts{ - Namespace: gangliaMetricsPrefix, - Name: name, - Help: desc, - }, - []string{"cluster"}, - ) - } - glog.V(1).Infof("Set %s{cluster=%q}: %f", name, cluster, metric.Value) - c.Metrics[name].WithLabelValues(cluster).Set(metric.Value) -} - func (c *gmondCollector) Update(ch chan<- prometheus.Metric) (err error) { conn, err := net.Dial(gangliaProto, gangliaAddress) glog.V(1).Infof("gmondCollector Update") @@ -100,12 +71,41 @@ func (c *gmondCollector) Update(ch chan<- prometheus.Metric) (err error) { } } } - for _, m := range c.Metrics { + for _, m := range c.metrics { m.Collect(ch) } return err } +func (c *gmondCollector) setMetric(name, cluster string, metric ganglia.Metric) { + if _, ok := c.metrics[name]; !ok { + var desc string + var title string + for _, element := range metric.ExtraData.ExtraElements { + switch element.Name { + case "DESC": + desc = element.Val + case "TITLE": + title = element.Val + } + if title != "" && desc != "" { + break + } + } + glog.V(1).Infof("Register %s: %s", name, desc) + c.metrics[name] = prometheus.NewGaugeVec( + prometheus.GaugeOpts{ + Namespace: gangliaMetricsPrefix, + Name: name, + Help: desc, + }, + []string{"cluster"}, + ) + } + glog.V(1).Infof("Set %s{cluster=%q}: %f", name, cluster, metric.Value) + c.metrics[name].WithLabelValues(cluster).Set(metric.Value) +} + func toUtf8(charset string, input io.Reader) (io.Reader, error) { return input, nil //FIXME } diff --git a/collector/megacli.go b/collector/megacli.go index 404d31a5..fd4ccfc0 100644 --- a/collector/megacli.go +++ b/collector/megacli.go @@ -1,4 +1,4 @@ -// +build megacli +// +build !nomegacli package collector diff --git a/collector/megacli_test.go b/collector/megacli_test.go index 74f56998..72e52afb 100644 --- a/collector/megacli_test.go +++ b/collector/megacli_test.go @@ -1,4 +1,4 @@ -// +build megacli +// +build !nomegacli package collector diff --git a/collector/runit_collector.go b/collector/runit.go similarity index 68% rename from collector/runit_collector.go rename to collector/runit.go index 9ae78f5e..989c9047 100644 --- a/collector/runit_collector.go +++ b/collector/runit.go @@ -1,4 +1,4 @@ -// +build runit +// +build !norunit package collector @@ -8,10 +8,6 @@ import ( "github.com/soundcloud/go-runit/runit" ) -const ( - runitSubsystem = "runit" -) - type runitCollector struct { config Config @@ -23,36 +19,43 @@ func init() { } func NewRunitCollector(config Config) (Collector, error) { - var labels = []string{"service"} + var ( + subsystem = "service" + constLabels = prometheus.Labels{"supervisor": "runit"} + labelNames = []string{"service"} + ) return &runitCollector{ config: config, state: prometheus.NewGaugeVec( prometheus.GaugeOpts{ - Namespace: Namespace, - Subsystem: runitSubsystem, - Name: "state", - Help: "state of runit service.", + Namespace: Namespace, + Subsystem: subsystem, + Name: "state", + Help: "state of runit service.", + ConstLabels: constLabels, }, - labels, + labelNames, ), stateDesired: prometheus.NewGaugeVec( prometheus.GaugeOpts{ - Namespace: Namespace, - Subsystem: runitSubsystem, - Name: "desired_state", - Help: "desired state of runit service.", + Namespace: Namespace, + Subsystem: subsystem, + Name: "desired_state", + Help: "desired state of runit service.", + ConstLabels: constLabels, }, - labels, + labelNames, ), stateNormal: prometheus.NewGaugeVec( prometheus.GaugeOpts{ - Namespace: Namespace, - Subsystem: runitSubsystem, - Name: "normal_state", - Help: "normal state of runit service.", + Namespace: Namespace, + Subsystem: subsystem, + Name: "normal_state", + Help: "normal state of runit service.", + ConstLabels: constLabels, }, - labels, + labelNames, ), }, nil } diff --git a/node_exporter.go b/node_exporter.go index 86b4100a..0b8e502f 100644 --- a/node_exporter.go +++ b/node_exporter.go @@ -96,12 +96,12 @@ func loadCollectors(file string) (map[string]collector.Collector, error) { collectors := map[string]collector.Collector{} config, err := getConfig(file) if err != nil { - log.Fatalf("Couldn't read config %s: %s", file, err) + return nil, fmt.Errorf("couldn't read config %s: %s", file, err) } for _, name := range strings.Split(*enabledCollectors, ",") { fn, ok := collector.Factories[name] if !ok { - log.Fatalf("Collector '%s' not available", name) + return nil, fmt.Errorf("collector '%s' not available", name) } c, err := fn(*config) if err != nil {