Consolidate collector selection

Remove special tags necessary for gmond and runit collectors. All
collectors get built. Selection of which collectors to use continues to
happen via parameter.
This commit is contained in:
Tobias Schmidt 2014-11-24 17:15:13 -05:00
parent 600a529e09
commit 211ddf33f1
6 changed files with 64 additions and 87 deletions

View File

@ -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`.

View File

@ -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
}

View File

@ -1,4 +1,4 @@
// +build megacli
// +build !nomegacli
package collector

View File

@ -1,4 +1,4 @@
// +build megacli
// +build !nomegacli
package collector

View File

@ -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
}

View File

@ -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 {