Merge pull request #4 from prometheus/modularize

Modularize node_exporter and add Dockerfile
This commit is contained in:
Johannes 'fish' Ziemke 2014-02-12 11:18:01 +01:00
commit 6b77696a33
8 changed files with 92 additions and 41 deletions

16
Dockerfile Normal file
View File

@ -0,0 +1,16 @@
FROM ubuntu:13.10
MAINTAINER Prometheus Team <prometheus-developers@googlegroups.com>
ENV COLLECTORS NativeCollector
RUN apt-get update && apt-get install -yq curl git mercurial make
RUN curl -s https://go.googlecode.com/files/go1.2.linux-amd64.tar.gz | tar -C /usr/local -xzf -
ENV PATH /usr/local/go/bin:$PATH
ENV GOPATH /go
ADD . /usr/src/node_exporter
RUN cd /usr/src/node_exporter && make && cp node_exporter /
RUN printf '{ "scrapeInterval": 10, "attributes": {} }' > \
node_exporter.conf
ENTRYPOINT [ "/node_exporter" ]
EXPOSE 8080

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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