Browse Source

Add support for selecting collectors at buildtime

This works by using a global array with references to NewXCollector
functions. Each collector appends to that array in it's init() function.

Which file gets build depends on the build tags:

To build only the ganglia exporter, you can do:

    go build -tags nonative,ganglia

By default it will build only the native collector.
pull/4/head
Johannes 'fish' Ziemke 11 years ago
parent
commit
04380ae60a
  1. 33
      README.md
  2. 32
      exporter/exporter.go
  3. 12
      exporter/gmond_collector.go
  4. 18
      exporter/native_collector.go
  5. 10
      exporter/runit_collector.go
  6. 5
      node_exporter.conf
  7. 7
      node_exporter.go

33
README.md

@ -1,4 +1,31 @@
node_exporter
=============
# node_exporter
Prometheus exporter with plugable metric collectors.
## Available collectors
By default it will only include the NativeCollector.
To include other collectors, specify the build tags accordently.
### NativeCollector
Provides metrics for load, seconds since last login and a list of tags
read from `node_exporter.conf`.
To disable the native collector, use build tag `nonative`.
### GmondCollector
Talks to a local gmond and provide it's metrics.
### RunitCollector
Provides metrics for each runit services like state and how long it
has been in that state.
Simple exporter, exposing load, seconds since last login and a list of tags for the node it's running on.

32
exporter/exporter.go

@ -1,4 +1,4 @@
// Exporter is a prometheus exporter using multiple collectors to collect and export system metrics.
// Exporter is a prometheus exporter using multiple collectorFactories to collect and export system metrics.
package exporter
import (
@ -19,6 +19,7 @@ import (
)
var verbose = flag.Bool("verbose", false, "Verbose output.")
var collectorFactories []func(config, prometheus.Registry) (Collector, error)
// Interface a collector has to implement.
type Collector interface {
@ -33,7 +34,6 @@ type config struct {
Attributes map[string]string `json:"attributes"`
ListeningAddress string `json:"listeningAddress"`
ScrapeInterval int `json:"scrapeInterval"`
Collectors []string `json:"collectors"`
}
func (e *exporter) loadConfig() (err error) {
@ -54,7 +54,7 @@ type exporter struct {
metricsUpdated prometheus.Gauge
config config
registry prometheus.Registry
collectors []Collector
Collectors []Collector
MemProfile string
}
@ -74,24 +74,14 @@ func New(configFile string) (e exporter, err error) {
if err != nil {
return e, fmt.Errorf("Couldn't read config: %s", err)
}
cn, err := NewNativeCollector(e.config, e.registry)
if err != nil {
log.Fatalf("Couldn't attach collector: %s", err)
}
cr, err := NewRunitCollector(e.config, e.registry)
if err != nil {
log.Fatalf("Couldn't attach collector: %s", err)
}
cg, err := NewGmondCollector(e.config, e.registry)
if err != nil {
log.Fatalf("Couldn't attach collector: %s", err)
for _, fn := range collectorFactories {
c, err := fn(e.config, e.registry)
if err != nil {
return e, err
}
e.Collectors = append(e.Collectors, c)
}
e.collectors = []Collector{&cn, &cr, &cg}
if e.config.ListeningAddress != "" {
e.listeningAddress = e.config.ListeningAddress
}
@ -152,8 +142,8 @@ func (e *exporter) Loop() {
case <-tick:
log.Printf("Starting new scrape interval")
wg := sync.WaitGroup{}
wg.Add(len(e.collectors))
for _, c := range e.collectors {
wg.Add(len(e.Collectors))
for _, c := range e.Collectors {
go func(c Collector) {
e.Execute(c)
wg.Done()

12
exporter/gmond_collector.go

@ -1,3 +1,5 @@
// +build ganglia
package exporter
import (
@ -25,18 +27,22 @@ type gmondCollector struct {
registry prometheus.Registry
}
func init() {
collectors = append(collectors, NewGmondCollector)
}
var illegalCharsRE = regexp.MustCompile(`[^a-zA-Z0-9_]`)
// Takes a config struct and prometheus registry and returns a new Collector scraping ganglia.
func NewGmondCollector(config config, registry prometheus.Registry) (collector gmondCollector, err error) {
collector = gmondCollector{
func NewGmondCollector(config config, registry prometheus.Registry) (Collector, error) {
c := gmondCollector{
name: "gmond_collector",
config: config,
Metrics: make(map[string]prometheus.Gauge),
registry: registry,
}
return collector, nil
return &c, nil
}
func (c *gmondCollector) Name() string { return c.name }

18
exporter/native_collector.go

@ -1,3 +1,5 @@
// +build !nonative
package exporter
import (
@ -24,10 +26,14 @@ type nativeCollector struct {
config config
}
func init() {
collectorFactories = append(collectorFactories, NewNativeCollector)
}
// Takes a config struct and prometheus registry and returns a new Collector exposing
// load, seconds since last login and a list of tags as specified by config.
func NewNativeCollector(config config, registry prometheus.Registry) (collector nativeCollector, err error) {
collector = nativeCollector{
func NewNativeCollector(config config, registry prometheus.Registry) (Collector, error) {
c := nativeCollector{
name: "native_collector",
config: config,
loadAvg: prometheus.NewGauge(),
@ -39,24 +45,24 @@ func NewNativeCollector(config config, registry prometheus.Registry) (collector
"node_load",
"node_exporter: system load.",
prometheus.NilLabels,
collector.loadAvg,
c.loadAvg,
)
registry.Register(
"node_last_login_seconds",
"node_exporter: seconds since last login.",
prometheus.NilLabels,
collector.lastSeen,
c.lastSeen,
)
registry.Register(
"node_attributes",
"node_exporter: system attributes.",
prometheus.NilLabels,
collector.attributes,
c.attributes,
)
return collector, nil
return &c, nil
}
func (c *nativeCollector) Name() string { return c.name }

10
exporter/runit_collector.go

@ -1,3 +1,5 @@
// +build runit
package exporter
import (
@ -13,7 +15,11 @@ type runitCollector struct {
stateNormal prometheus.Gauge
}
func NewRunitCollector(config config, registry prometheus.Registry) (runitCollector, error) {
func init() {
collectors = append(collectors, NewRunitCollector)
}
func NewRunitCollector(config config, registry prometheus.Registry) (Collector, error) {
c := runitCollector{
name: "runit_collector",
config: config,
@ -43,7 +49,7 @@ func NewRunitCollector(config config, registry prometheus.Registry) (runitCollec
c.stateNormal,
)
return c, nil
return &c, nil
}
func (c *runitCollector) Name() string { return c.name }

5
node_exporter.conf

@ -1,10 +1,5 @@
{
"scrapeInterval": 10,
"collectors": [
"NativeCollector",
"GmondCollector",
"MuninCollector"
],
"attributes" : {
"web-server" : "1",
"zone" : "a",

7
node_exporter.go

@ -2,8 +2,9 @@ package main
import (
"flag"
"github.com/prometheus/node_exporter/exporter"
"log"
"github.com/prometheus/node_exporter/exporter"
)
var (
@ -18,5 +19,9 @@ func main() {
if err != nil {
log.Fatalf("Couldn't instantiate exporter: %s", err)
}
log.Printf("Registered collectors:")
for _, c := range exporter.Collectors {
log.Print(" - ", c.Name())
}
exporter.Loop()
}

Loading…
Cancel
Save